scriptorium 0.0.3 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/myuserdoc/userdoc-toc.txt +88 -0
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,87 @@
|
|
1
|
+
.h1 Phoenix isn't Rails
|
2
|
+
|
3
|
+
.set post.num = 0007
|
4
|
+
.set post.slug = phoenix-isnt-rails
|
5
|
+
.set post.date = 2015-07-27
|
6
|
+
.set post.title = Phoenix isn't Rails
|
7
|
+
.set post.tags =
|
8
|
+
.set post.views = computing
|
9
|
+
.set post.published = yes
|
10
|
+
.set post.deployed = no
|
11
|
+
|
12
|
+
I don't know Elixir very well at all. But I've started to learn Phoenix now. The
|
13
|
+
first thing to know: Phoenix is not Ruby on Rails (nor is it "Elixir on Rails").
|
14
|
+
I began my learning experience by dutifully crunching through the tutorial and
|
15
|
+
making my share (at least) of newbie mistakes. (Disclaimer: I'm not a web guy. I
|
16
|
+
don't natively "think" in those terms and perhaps never will.)
|
17
|
+
|
18
|
+
At some point in the hello-world example, I stopped and did a count of the files
|
19
|
+
under my tree. It will become clear in a moment why this was a little naive and
|
20
|
+
careless.
|
21
|
+
|
22
|
+
At any rate, I think find . | wc -lreported 11,648 files to me. I found this
|
23
|
+
a bit confusing and puzzling, and I didn't think it through.
|
24
|
+
|
25
|
+
I chatted with Chris McCord and another guy I don't think I've met. This is a summary:
|
26
|
+
|
27
|
+
hal_9000: chrismccord: I have a question about the philosophy/design
|
28
|
+
of phoenix - if you have time/inclination and the answer is not too involved
|
29
|
+
|
30
|
+
chrismccord: hal_9000: shoot
|
31
|
+
|
32
|
+
hal_9000: first of all, i’m not a web guy - i’ve played with rails and several
|
33
|
+
other things - wrote a few small apps. One thing that appealed to me
|
34
|
+
about Sinatra was how “lightweight” it was compared to Rails — you can
|
35
|
+
write a primitive Sinatra app in a single file.
|
36
|
+
hal_9000: i “sort of” expected that Phoenix might be that way — but a find piped
|
37
|
+
to wc showed me that a hello-world app has more than 11,000 files in it.
|
38
|
+
why in general is that?
|
39
|
+
|
40
|
+
chrismccord: hal_9000: remove the node_modules folder and re-run ws
|
41
|
+
chrismccord: it's all nodejs for the asset building
|
42
|
+
chrismccord: hal_9000: we are lightweight. It's a misconception I have to keep correcting.
|
43
|
+
We are much closer to sinatra than rails
|
44
|
+
|
45
|
+
hal_9000: hmm, i don’t even know nodejs of course
|
46
|
+
hal_9000: chrismccord: thanks, i had a feeling i was missing something for sure
|
47
|
+
|
48
|
+
chrismccord: hal_9000: you could write an app in a single file, but no-one does that,
|
49
|
+
because we don't write production software in a single file
|
50
|
+
chrismccord: hal_9000: It is also worth mentioning there is also nothing global in
|
51
|
+
phoenix. We are not a monolith like rails
|
52
|
+
|
53
|
+
jeregrine: hal_9000: something to keep in mind here is that phoenix assumes you are
|
54
|
+
writing production software. Eventually you will need to touch every file, otherwise
|
55
|
+
it wouldn't generate the file
|
56
|
+
|
57
|
+
hal_9000: chrismccord: ok, thanks, i will look more closely. i’m impressed with what i see
|
58
|
+
|
59
|
+
jeregrine: hal_9000: if you are like me and have used sinatra for production software you
|
60
|
+
probably discovered you ended up writing a slightly smaller version of rails
|
61
|
+
|
62
|
+
hal_9000: jeregrine: that makes perfect sense
|
63
|
+
|
64
|
+
jeregrine: hal_9000: if you only need a single route/api call, and are certain it will never grow,
|
65
|
+
you could VERY easily get away with just plug and it's router
|
66
|
+
jeregrine: hal_9000: http://hexdocs.pm/plug/Plug.Router.html for reference.
|
67
|
+
|
68
|
+
hal_9000: chrismccord: i grasp it now, sorry for the noise
|
69
|
+
|
70
|
+
jeregrine: hal_9000: lemme know if you have any questions, this is something we need to be better at
|
71
|
+
communicating. We are not rails
|
72
|
+
|
73
|
+
chrismccord: hal_9000: no worries. Sorry if my response was rash too. I just have to fight a lot of
|
74
|
+
"phoenix is bloated" comments because people assume it is given my Rails background and
|
75
|
+
the comparisons with rails
|
76
|
+
|
77
|
+
hal_9000: chrismccord: no, your response was not rash at all
|
78
|
+
|
79
|
+
So first of all: I didn't pay attention to what I was doing when I did my file count.
|
80
|
+
|
81
|
+
But the real takeaway here is: Phoenix isn't bloated, and more importantly, Phoenix isn't Rails.
|
82
|
+
The philosophy seems to be more "minimalistic" as I had hoped.
|
83
|
+
|
84
|
+
And of course, we all know that Elixir isn't Ruby. I won't belabor that point.
|
85
|
+
|
86
|
+
On the other hand, I do find (so far) that Plug is a lot like Rack. That's a good thing, because I
|
87
|
+
always thought Rack was sheer genius. More on that as I learn.
|
@@ -0,0 +1,129 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Concerning the term "monkeypatching"</title>
|
6
|
+
<meta name="generator" content="Scriptorium Import">
|
7
|
+
<meta property="og:title" content="Concerning the term "monkeypatching"">
|
8
|
+
<meta property="og:locale" content="en_US">
|
9
|
+
<meta property="og:type" content="article">
|
10
|
+
<meta property="article:published_time" content="2015-08-10">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<article>
|
14
|
+
<header>
|
15
|
+
<h1>Concerning the term "monkeypatching"</h1>
|
16
|
+
<time datetime="2015-08-10">August 10, 2015</time>
|
17
|
+
</header>
|
18
|
+
|
19
|
+
<div class="content">
|
20
|
+
<p>
|
21
|
+
There have been many "dark days" in the Ruby community, some much darker than others.
|
22
|
+
Guy Decoux died, _why the lucky stiff_ left us (without dying), Jim Weirich died. (Yes, I count
|
23
|
+
actual deaths as the darkest moments of all.)
|
24
|
+
|
25
|
+
<p>
|
26
|
+
But I count another dark moment that many of you will not. When I had been using Ruby a
|
27
|
+
little more than six years, in December 2005, the term "monkeypatching" was introduced
|
28
|
+
into our circle.
|
29
|
+
|
30
|
+
<p>
|
31
|
+
It was a post by Drew Mills, quoting a blog from a Python person who apparently hated Ruby.
|
32
|
+
I don't blame Drew. I don't suppose I "blame" anyone. But I regret that this slang has entered
|
33
|
+
our culture.
|
34
|
+
|
35
|
+
<p>
|
36
|
+
The post Drew quoted was this:
|
37
|
+
|
38
|
+
<p>
|
39
|
+
<blockquote>
|
40
|
+
It's the second generation that's going to be less enthused, that's going to stare in bafflement at these classes that mysteriously spawn methods, and trying to figure out what's going when there's an exception in dynamically generated code. You can monkeypatch code in Python pretty easily, but we look down on it enough that we call it "monkeypatching". In Ruby they call it "opening a class" and think it's a cool feature. I will assert: we are right, they are wrong.
|
41
|
+
</blockquote>
|
42
|
+
Before I go on to my main point, I'll make an observation that is arguably much more interesting.
|
43
|
+
If you read again, it sounds like the Python person (Ian Bicking) was talking about dynamic method
|
44
|
+
dispatch (the use or abuse of method_missing) rather than actual open classes.
|
45
|
+
|
46
|
+
<p>
|
47
|
+
Someone later in that thread decried the "ignorance" of Bicking with regard to this -- that he didn't
|
48
|
+
even know enough Ruby to know the difference between dynamic dispatch and open classes. I
|
49
|
+
wonder if the original pythonism meant something different? Since I never completed my Python
|
50
|
+
studies, I can't comment.
|
51
|
+
|
52
|
+
<p>
|
53
|
+
At any rate: Back to my story.
|
54
|
+
|
55
|
+
<p>
|
56
|
+
I still recall the revulsion I felt, almost physical nausea, when I read this the first time. That's probably
|
57
|
+
a somewhat extreme response on my part.
|
58
|
+
|
59
|
+
<p>
|
60
|
+
I regarded open classes as a programming technique that is potentially very powerful but easy to misuse.
|
61
|
+
This sounds like a "good and yet bad" argument. But let me rephrase that sentence.
|
62
|
+
|
63
|
+
<p>
|
64
|
+
Open classes are a technique that is potentially very powerful <i>(and</i> therefore) easy to misuse. That is
|
65
|
+
the point. Any tool that is powerful enough is prone to misuse by people who are unskilled.
|
66
|
+
|
67
|
+
<p>
|
68
|
+
The term "monkeypatching" is obviously a pejorative term. Upon seeing it, my first thought was, "I am
|
69
|
+
not a monkey, and I am not 'patching' anything."
|
70
|
+
|
71
|
+
<p>
|
72
|
+
After all, that is the implication. The term implies that the developer is a monkey, and that the work he is
|
73
|
+
doing is sloppy or shoddy. It is an insult both to the quality of the developer's work and to the developer
|
74
|
+
himself.
|
75
|
+
|
76
|
+
<p>
|
77
|
+
So it bothered me because it was a pejorative and it was insulting to us as programmers. It was also
|
78
|
+
(arguably) an insult to Ruby itself and therefore by extension an insult to Matz.
|
79
|
+
|
80
|
+
<p>
|
81
|
+
I dislike being clannish, though perhaps sometimes I am. After all, Ruby is not (supposed to be) anyone's
|
82
|
+
religion or cultural heritage. It's only a programming language, and I think it's very much like Python. But it
|
83
|
+
also bothered me that this neologism originated <i>outside</i> our community, in particular with the Python
|
84
|
+
community.
|
85
|
+
|
86
|
+
<p>
|
87
|
+
Generalizations are always wrong. (Yes, that's a joke.) And stereotypes as such are at least useless if not
|
88
|
+
actually hurtful. And yet I always heard about the arrogance and rudeness of Python programmers, and I
|
89
|
+
occasionally saw real evidence of it. And though I dislike the word "nice" in general, I always found it interesting
|
90
|
+
that Ruby coders were labeled as "nice" (as in the abbreviation MINASWAN, "Matz is nice, and so we are nice").
|
91
|
+
|
92
|
+
<p>
|
93
|
+
So when this usage was introduced, I felt rather as though someone had opened my front door and dumped a
|
94
|
+
large piece of dog manure onto my carpet. What is worse, it has wormed its way into common usage in our
|
95
|
+
community, even in documentation. A lot of this happened in the early days of Rails, when fate dumped a huge
|
96
|
+
influx of newbies onto the Ruby community. Not to disparage the Rails people in general, but at the time this
|
97
|
+
felt much the same as it did back when AOL (America Online) made its debut and dumped millions of (insert
|
98
|
+
noun here) into the Internet and Usenet communities.
|
99
|
+
|
100
|
+
<p>
|
101
|
+
It's impossible to stop this usage now (like so many other usages in the English language having nothing to do
|
102
|
+
with computing). But I still protest, and I still stand against it.
|
103
|
+
|
104
|
+
<p>
|
105
|
+
The term "monkeypatching" appears only once in more than 800 pages of <i>The Ruby Way</i>. It occurs when I
|
106
|
+
say I don't condone this term, and it won't be used further in the book.
|
107
|
+
|
108
|
+
<p>
|
109
|
+
As an aside: The "refinements" which exist in recent versions of Ruby make open classes stricter and safer. I'll blog
|
110
|
+
about that later. But this isn't much of a technical post. It's just a reminiscence and a rant.
|
111
|
+
|
112
|
+
<p>
|
113
|
+
So basically I hate the term "monkeypatching." I am polite to people who say it to me (e.g., in asking a question), but
|
114
|
+
secretly I want to just ignore them.
|
115
|
+
|
116
|
+
<p>
|
117
|
+
The last time I saw Jim Weirich, in New Orleans, he and I talked about this. He agreed it was a pejorative term,
|
118
|
+
and it was a shame it had entered the common dialect, though there was really nothing to do about it. But being
|
119
|
+
much more level-headed and good-natured than I am, he wasn't bothered much by it.
|
120
|
+
|
121
|
+
<p>
|
122
|
+
I really miss Jim, by the way. He was a truly brilliant developer and an amiable and wonderful person in general.
|
123
|
+
If it would bring him back, I would gladly change the book's name to <i>The Art of Monkeypatching</i>.
|
124
|
+
|
125
|
+
<p>
|
126
|
+
</div>
|
127
|
+
</article>
|
128
|
+
</body>
|
129
|
+
</html>
|
@@ -0,0 +1,92 @@
|
|
1
|
+
.h1 Concerning the term "monkeypatching"
|
2
|
+
|
3
|
+
.set post.num = 0008
|
4
|
+
.set post.slug = concerning-the-term-monkeypatching
|
5
|
+
.set post.date = 2015-08-10
|
6
|
+
.set post.title = Concerning the term "monkeypatching"
|
7
|
+
.set post.tags =
|
8
|
+
.set post.views = computing
|
9
|
+
.set post.published = yes
|
10
|
+
.set post.deployed = no
|
11
|
+
|
12
|
+
There have been many "dark days" in the Ruby community, some much darker than others.
|
13
|
+
Guy Decoux died, _why the lucky stiff_ left us (without dying), Jim Weirich died. (Yes, I count
|
14
|
+
actual deaths as the darkest moments of all.)
|
15
|
+
|
16
|
+
But I count another dark moment that many of you will not. When I had been using Ruby a
|
17
|
+
little more than six years, in December 2005, the term "monkeypatching" was introduced
|
18
|
+
into our circle.
|
19
|
+
|
20
|
+
It was a post by Drew Mills, quoting a blog from a Python person who apparently hated Ruby.
|
21
|
+
I don't blame Drew. I don't suppose I "blame" anyone. But I regret that this slang has entered
|
22
|
+
our culture.
|
23
|
+
|
24
|
+
The post Drew quoted was this:
|
25
|
+
|
26
|
+
It's the second generation that's going to be less enthused, that's going to stare in bafflement at these classes that mysteriously spawn methods, and trying to figure out what's going when there's an exception in dynamically generated code. You can monkeypatch code in Python pretty easily, but we look down on it enough that we call it "monkeypatching". In Ruby they call it "opening a class" and think it's a cool feature. I will assert: we are right, they are wrong.
|
27
|
+
|
28
|
+
Before I go on to my main point, I'll make an observation that is arguably much more interesting.
|
29
|
+
If you read again, it sounds like the Python person (Ian Bicking) was talking about dynamic method
|
30
|
+
dispatch (the use or abuse of method_missing) rather than actual open classes.
|
31
|
+
|
32
|
+
Someone later in that thread decried the "ignorance" of Bicking with regard to this -- that he didn't
|
33
|
+
even know enough Ruby to know the difference between dynamic dispatch and open classes. I
|
34
|
+
wonder if the original pythonism meant something different? Since I never completed my Python
|
35
|
+
studies, I can't comment.
|
36
|
+
|
37
|
+
At any rate: Back to my story.
|
38
|
+
|
39
|
+
I still recall the revulsion I felt, almost physical nausea, when I read this the first time. That's probably
|
40
|
+
a somewhat extreme response on my part.
|
41
|
+
|
42
|
+
I regarded open classes as a programming technique that is potentially very powerful but easy to misuse.
|
43
|
+
This sounds like a "good and yet bad" argument. But let me rephrase that sentence.
|
44
|
+
|
45
|
+
Open classes are a technique that is potentially very powerful (and therefore) easy to misuse. That is
|
46
|
+
the point. Any tool that is powerful enough is prone to misuse by people who are unskilled.
|
47
|
+
|
48
|
+
The term "monkeypatching" is obviously a pejorative term. Upon seeing it, my first thought was, "I am
|
49
|
+
not a monkey, and I am not 'patching' anything."
|
50
|
+
|
51
|
+
After all, that is the implication. The term implies that the developer is a monkey, and that the work he is
|
52
|
+
doing is sloppy or shoddy. It is an insult both to the quality of the developer's work and to the developer
|
53
|
+
himself.
|
54
|
+
|
55
|
+
So it bothered me because it was a pejorative and it was insulting to us as programmers. It was also
|
56
|
+
(arguably) an insult to Ruby itself and therefore by extension an insult to Matz.
|
57
|
+
|
58
|
+
I dislike being clannish, though perhaps sometimes I am. After all, Ruby is not (supposed to be) anyone's
|
59
|
+
religion or cultural heritage. It's only a programming language, and I think it's very much like Python. But it
|
60
|
+
also bothered me that this neologism originated outside our community, in particular with the Python
|
61
|
+
community.
|
62
|
+
|
63
|
+
Generalizations are always wrong. (Yes, that's a joke.) And stereotypes as such are at least useless if not
|
64
|
+
actually hurtful. And yet I always heard about the arrogance and rudeness of Python programmers, and I
|
65
|
+
occasionally saw real evidence of it. And though I dislike the word "nice" in general, I always found it interesting
|
66
|
+
that Ruby coders were labeled as "nice" (as in the abbreviation MINASWAN, "Matz is nice, and so we are nice").
|
67
|
+
|
68
|
+
So when this usage was introduced, I felt rather as though someone had opened my front door and dumped a
|
69
|
+
large piece of dog manure onto my carpet. What is worse, it has wormed its way into common usage in our
|
70
|
+
community, even in documentation. A lot of this happened in the early days of Rails, when fate dumped a huge
|
71
|
+
influx of newbies onto the Ruby community. Not to disparage the Rails people in general, but at the time this
|
72
|
+
felt much the same as it did back when AOL (America Online) made its debut and dumped millions of (insert
|
73
|
+
noun here) into the Internet and Usenet communities.
|
74
|
+
|
75
|
+
It's impossible to stop this usage now (like so many other usages in the English language having nothing to do
|
76
|
+
with computing). But I still protest, and I still stand against it.
|
77
|
+
|
78
|
+
The term "monkeypatching" appears only once in more than 800 pages of The Ruby Way. It occurs when I
|
79
|
+
say I don't condone this term, and it won't be used further in the book.
|
80
|
+
|
81
|
+
As an aside: The "refinements" which exist in recent versions of Ruby make open classes stricter and safer. I'll blog
|
82
|
+
about that later. But this isn't much of a technical post. It's just a reminiscence and a rant.
|
83
|
+
|
84
|
+
So basically I hate the term "monkeypatching." I am polite to people who say it to me (e.g., in asking a question), but
|
85
|
+
secretly I want to just ignore them.
|
86
|
+
|
87
|
+
The last time I saw Jim Weirich, in New Orleans, he and I talked about this. He agreed it was a pejorative term,
|
88
|
+
and it was a shame it had entered the common dialect, though there was really nothing to do about it. But being
|
89
|
+
much more level-headed and good-natured than I am, he wasn't bothered much by it.
|
90
|
+
|
91
|
+
I really miss Jim, by the way. He was a truly brilliant developer and an amiable and wonderful person in general.
|
92
|
+
If it would bring him back, I would gladly change the book's name to The Art of Monkeypatching.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Announcement coming soon...</title>
|
6
|
+
<meta name="generator" content="Scriptorium Import">
|
7
|
+
<meta property="og:title" content="Announcement coming soon...">
|
8
|
+
<meta property="og:locale" content="en_US">
|
9
|
+
<meta property="og:type" content="article">
|
10
|
+
<meta property="article:published_time" content="2015-08-11">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<article>
|
14
|
+
<header>
|
15
|
+
<h1>Announcement coming soon...</h1>
|
16
|
+
<time datetime="2015-08-11">August 11, 2015</time>
|
17
|
+
</header>
|
18
|
+
|
19
|
+
<div class="content">
|
20
|
+
<p>
|
21
|
+
Maybe this will stir your curiosity a little. I hope it does.
|
22
|
+
I've started working on a project with someone else, and I
|
23
|
+
think it will be really worthwhile.
|
24
|
+
This will be launched within 48 hours and announced at the
|
25
|
+
Lone Star Ruby Conference in Austin, Texas (October 15).
|
26
|
+
Maybe it will be leaked a little before then, too.
|
27
|
+
|
28
|
+
<p>
|
29
|
+
Sit tight 48 hours or so...
|
30
|
+
</div>
|
31
|
+
</article>
|
32
|
+
</body>
|
33
|
+
</html>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
.h1 Announcement coming soon...
|
2
|
+
|
3
|
+
.set post.num = 0009
|
4
|
+
.set post.slug = announcement-coming-soon
|
5
|
+
.set post.date = 2015-08-11
|
6
|
+
.set post.title = Announcement coming soon...
|
7
|
+
.set post.tags =
|
8
|
+
.set post.views = computing
|
9
|
+
.set post.published = yes
|
10
|
+
.set post.deployed = no
|
11
|
+
|
12
|
+
Maybe this will stir your curiosity a little. I hope it does.
|
13
|
+
I've started working on a project with someone else, and I
|
14
|
+
think it will be really worthwhile.
|
15
|
+
This will be launched within 48 hours and announced at the
|
16
|
+
Lone Star Ruby Conference in Austin, Texas (October 15).
|
17
|
+
Maybe it will be leaked a little before then, too.
|
18
|
+
|
19
|
+
Sit tight 48 hours or so...
|
@@ -0,0 +1,175 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Immutable data (ditching the wax tablet)</title>
|
6
|
+
<meta name="generator" content="Scriptorium Import">
|
7
|
+
<meta property="og:title" content="Immutable data (ditching the wax tablet)">
|
8
|
+
<meta property="og:locale" content="en_US">
|
9
|
+
<meta property="og:type" content="article">
|
10
|
+
<meta property="article:published_time" content="2015-08-25">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<article>
|
14
|
+
<header>
|
15
|
+
<h1>Immutable data (ditching the wax tablet)</h1>
|
16
|
+
<time datetime="2015-08-25">August 25, 2015</time>
|
17
|
+
</header>
|
18
|
+
|
19
|
+
<div class="content">
|
20
|
+
<p>
|
21
|
+
A couple of weeks ago, I went to Phoenix training prior to the Lone Star Ruby
|
22
|
+
Conference in Austin. I was talking with Bruce Tate, and he shared with me
|
23
|
+
some thoughts about functional programming in general.
|
24
|
+
Obviously Bruce isn't responsible if I misquote him. My memory is faulty.
|
25
|
+
|
26
|
+
<p>
|
27
|
+
"Functional programming is the future," he told me, "and OOP is dying."
|
28
|
+
He pointed to the ever-increasing popularity of multi-core machines and the
|
29
|
+
increasing irrelevance of conserving memory.
|
30
|
+
|
31
|
+
<p>
|
32
|
+
He said that OOP was all about optimizing for memory usage, and that was
|
33
|
+
no longer such a big concern. I wasn't sure what he meant. I thought about it
|
34
|
+
later, and decided I was probably missing some profound points.
|
35
|
+
|
36
|
+
<p>
|
37
|
+
But at the same time, I thought I saw something with a clarity that I hadn't
|
38
|
+
before. I have wrestled with the concepts of FP over the last year or two; as
|
39
|
+
a procedural and OOP type, it hasn't always fit into my brain quickly or
|
40
|
+
easily.
|
41
|
+
|
42
|
+
<p>
|
43
|
+
At times it felt that I was taking a step backwards technologically, back into
|
44
|
+
procedural thinking. On the one hand, that isn't really true. On the other
|
45
|
+
hand, I think we all know what backtracking is for. If you've ever gotten lost
|
46
|
+
in a strange town, you know that sometimes you have to back up to a known
|
47
|
+
point and try going off in a different direction.
|
48
|
+
|
49
|
+
<p>
|
50
|
+
If you're interested, you could make some fine analogies here between human
|
51
|
+
technological advances and things like game theory and machine learning. It's
|
52
|
+
hard to imagine navigating a maze or implementing a chess-playing program
|
53
|
+
without the concept of backtracking. But that's not my point here.
|
54
|
+
|
55
|
+
<p>
|
56
|
+
One of the key concepts in functional programming, as I understand it, is that
|
57
|
+
of immutable data. I have spent hours puzzling over this, because it hasn't
|
58
|
+
been immediately intuitive to me.
|
59
|
+
|
60
|
+
<p>
|
61
|
+
There was a quote I read once that the GOTO statement caused difficulties
|
62
|
+
because it left us with the question, "How did I get here?" And mutable data
|
63
|
+
leaves us with the question, "How did I get to this state?" That made sense
|
64
|
+
to me, at least a little.
|
65
|
+
|
66
|
+
<p>
|
67
|
+
It got me to thinking about a more remote time, when I taught programming
|
68
|
+
concepts to beginners (using BASIC). In an effort to explain how a program
|
69
|
+
worked, I would run through an exercise on the whiteboard which I called
|
70
|
+
"playing computer." Variables were represented by little boxes which more or
|
71
|
+
less corresponded to memory locations. As I manually stepped through the execution
|
72
|
+
of some simple program, I would erase and update the contents of these boxes.
|
73
|
+
|
74
|
+
<p>
|
75
|
+
It was nice and effective, but I sometimes did it another way. I expressed the
|
76
|
+
same information in the form of a table, with variable names across the
|
77
|
+
columns and time increasing down the rows. This made it clear not just what
|
78
|
+
values the variables had, but what values they used to have (and how/when they
|
79
|
+
changed).
|
80
|
+
|
81
|
+
<p>
|
82
|
+
As an aside, I'm one of those people who believes that an education should not
|
83
|
+
be merely deep but also broad. I believe a good vocabulary, like a good
|
84
|
+
education in general, enhances our experience of life.
|
85
|
+
|
86
|
+
<p>
|
87
|
+
And as I thought about my old whiteboard shenanigans, the word that came to me
|
88
|
+
was <i>palimpsest</i> -- a beautiful, useful, poetic word that we rarely see nowadays.
|
89
|
+
It's sometimes used figuratively; but the literal definition is <i>(a</i> document on )
|
90
|
+
<i>(which</i> the original writing has been erased and replaced with new writing).
|
91
|
+
|
92
|
+
<p>
|
93
|
+
I thought about the many older modes of writing, such as clay and wax tablets
|
94
|
+
and papyrus. Some materials such as papyrus and parchment (vellum) were rather
|
95
|
+
limited in availability or moderately labor-intensive to produce; people wanted
|
96
|
+
to re-use them. It was natural to wipe (or scrape or clean) such a material
|
97
|
+
once the writing on it was no longer relevant. The term "blank slate" <i>((tabula</i> rasa))
|
98
|
+
was once very literal; the stuff we wrote on was the same as the building material.
|
99
|
+
|
100
|
+
<p>
|
101
|
+
By the way, what is deemed relevant may change over the course of 1,000 or 2,000
|
102
|
+
years. Many an archaeologist or linguist has spent countless frustrating hours
|
103
|
+
trying to decipher the original writing under some later inscription. In a
|
104
|
+
similar way, art experts have gone to enormous lengths to uncover artworks
|
105
|
+
which someone painted over rather than start a new canvas.
|
106
|
+
|
107
|
+
<p>
|
108
|
+
But what if writing materials were cheap? Today we are much more likely to
|
109
|
+
have notepads on our desks than little erasable slates or wax tablets.
|
110
|
+
|
111
|
+
<p>
|
112
|
+
Let's extend the analogy to computer memory. There was a time, perhaps four
|
113
|
+
decades ago, when it was expensive and limited in availabilty. I recall seeing
|
114
|
+
an information sheet about a mainframe ("What's a mainframe?" asks everyone
|
115
|
+
under 40) that listed its specs, almost bragging about its memory, which was
|
116
|
+
448K. Yes, that is less than half a meg. That computer ran a medium-sized
|
117
|
+
university. Within seven years, of course, people were carrying around floppy
|
118
|
+
disks that held three times that much. ("What's a floppy disk?" asks everyone
|
119
|
+
under 30.)
|
120
|
+
|
121
|
+
<p>
|
122
|
+
It was only ten years or so prior to that time that the world saw the creation
|
123
|
+
of this curious thing called UNIX (a play on the name MULTICS). Some of you
|
124
|
+
reading this may have wondered (or not) why UNIX and its offspring stored a
|
125
|
+
conceptual newline as a single linefeed character (rather than the somewhat
|
126
|
+
more sensible "carriage return + linefeed" combination. The answer is that
|
127
|
+
the designers wanted to save RAM and disk space. For every line of text, they
|
128
|
+
saved an entire byte in this way. When a linefeed was sent to a device such
|
129
|
+
as a terminal or printer, the OS typically converted it to a "real" CRLF pair.
|
130
|
+
This all happened because memory was scarce and expensive.
|
131
|
+
|
132
|
+
<p>
|
133
|
+
It isn't true anymore. In some cases, we may have learned bad habits and
|
134
|
+
forgotten how to conserve memory. But in general, we have more imortant things
|
135
|
+
to worry about now.
|
136
|
+
|
137
|
+
<p>
|
138
|
+
But let's think a minute. If memory is cheap and available, why are we
|
139
|
+
turning it into a palimpsest? Isn't there something to be said for the idea of
|
140
|
+
leaving data alone, never overwriting information, always writing new data
|
141
|
+
somewhere else?
|
142
|
+
|
143
|
+
<p>
|
144
|
+
If we do that, we have a "history" of what has happened in program execution,
|
145
|
+
like a trail of breadcrumbs. More importantly, pieces of code that run
|
146
|
+
concurrently need not worry about stepping on each other's data. One process
|
147
|
+
(or thread or fiber) will never write over an item that another process is
|
148
|
+
reading. If this doesn't eliminate synchronization issues, it at least
|
149
|
+
mitigates them greatly.
|
150
|
+
|
151
|
+
<p>
|
152
|
+
So I'm starting to see where immutable data could be a good thing. And I'm
|
153
|
+
starting to see how it's good for concurrency. And concurrency really matters,
|
154
|
+
because it is the limiting factor of this generation of computing just as
|
155
|
+
memory scarcity was a limiting factor one or two generations ago.
|
156
|
+
|
157
|
+
<p>
|
158
|
+
In fact, I'll speculate a little about memory in general. Let's look 10, 20,
|
159
|
+
or even 50 years into the future. (My crystal ball, like everyone else's, is
|
160
|
+
very cloudy.)
|
161
|
+
|
162
|
+
<p>
|
163
|
+
I can imagine a time when memory is simply never erased at all. We're seeing
|
164
|
+
the crude beginnings of this already. Source control systems and databases
|
165
|
+
preserve far more history than they used to. My laptop's OS encourages me to
|
166
|
+
think of my backed-up data as a sort of limitless archive of past versions of
|
167
|
+
files. It's mostly an illusion, but it needn't always be. Why should any
|
168
|
+
document, any image, any video ever be erased?
|
169
|
+
|
170
|
+
<p>
|
171
|
+
Food for thought. Chow down, friends.
|
172
|
+
</div>
|
173
|
+
</article>
|
174
|
+
</body>
|
175
|
+
</html>
|