<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-65083961482497982</id><updated>2011-04-21T16:14:24.080-04:00</updated><category term='Author&apos;s Favorites'/><title type='text'>pl patterns</title><subtitle type='html'>Writings about programming languages and patterns in general</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-2522449573823071034</id><published>2008-06-09T18:33:00.003-04:00</published><updated>2008-06-09T18:42:18.465-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>Moved to Tumblr!</title><content type='html'>That's it!  I've moved this blog to &lt;a href="http://www.tumblr.com/"&gt;Tumblr&lt;/a&gt;.  Read &lt;a href="http://plpatterns.com/post/37782942/moving-from-blogger-to-tumblr"&gt;the details&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
On top of that, I got a domain &lt;a href="http://plpatterns.com/"&gt;plpatterns.com&lt;/a&gt; and a &lt;a href="http://feeds.feedburner.com/plpatterns"&gt;new feed&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-2522449573823071034?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/2522449573823071034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=2522449573823071034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2522449573823071034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2522449573823071034'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/06/moved-to-tumblr.html' title='Moved to Tumblr!'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1253303353842508093</id><published>2008-05-19T14:16:00.041-04:00</published><updated>2008-06-08T17:50:17.157-04:00</updated><title type='text'>The Prototype-Production Knob</title><content type='html'>Once you've seen the progression that software goes through from birth as a hacker's one-night-stand, to 3-man garage-startup's baby, to Small Corp's stubborn adolescent, to The-Next-Microsoft's bloated 1000-developer software-engineering nightmare... you simply can't ignore it and the programming language feature it seems to demand.

&lt;h4&gt;Hardening&lt;/h4&gt;

In the beginning when you have an idea, you want a flexible medium for experimenting with.  You really don't know where you're going to end up, so you want your medium to just get out of the way and let your creative juices flow.  It's the same in every industry really, whether it be software engineering, architecture, painting, or writing.  But once you have a product, and hundreds of other people besides you care about the outcome of every little detail, everything from which shade of gray its background is to what happens when you press the Tab key when the last textbox of the final dialog of your Import Wizard has the focus, you have to worry about things like quality assurance.&lt;a href="#20080529_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Software, like concrete, hardens over time becoming a rigid unmovable mass.  This happens as the original developers move on or simply forget about code they wrote and haven't touched for a while.  Code gets pushed down into layers of abstraction, becoming black boxes that no one ever looks into unless something goes wrong.  This is the natural progression as new building blocks get created by combining the functionality of older building blocks.  The fringes of development churn like mad, but over time, newer modules start depending on them, weighing them down by discouraging change.&lt;br /&gt;
&lt;br /&gt;
On top of that, shear code size prevents change.  Once you have a massive software system built from thousands upon thousands of man-hours, you simply &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html"&gt;can't throw it away&lt;/a&gt; and start from scratch.  Maybe in an ideal world where you didn't have to worry about paying rent... but if you intend to make a living off of software, it simply isn't an option.&lt;br /&gt;
&lt;br /&gt;
Once a software system has been grown so large, you're stuck with it.  Steve Yegge talked about this in a &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;blog post&lt;/a&gt;, but I think most people who &lt;span style="text-decoration: line-through"&gt;read&lt;/span&gt; skimmed it just voted it up on their favorite news site and moved on to the next article.  This is so fundamental &amp;mdash; size!  Not some theoretical &lt;a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;cyclomatic metric&lt;/a&gt;.  Size!  And part of the reason size is so important is because once you have a sufficiently large code-base, re-writing it is no longer an option.  Which means, &lt;span style="font-style:italic;"&gt;changing&lt;/span&gt; it is no longer an option.&lt;br /&gt;
&lt;br /&gt;
The code literally solidifies!


&lt;h4&gt;The Knob&lt;/h4&gt;

Concrete naturally hardens over time.  But what if your concrete were rigid even when you wanted to constantly mold it.  Or what if it never completely hardened, even after you found the perfect form.  That is what programming languages are like today.  You have to choose the static language that's too rigid to prototype with or the dynamic language that never completely hardens even in production.&lt;br /&gt;
&lt;br /&gt;
HTML and PHP are good examples of languages that never completely harden.  They were great at first; it was so easy to dive right in, and they blew up in popularity as a result.  But years later we are &lt;a href="http://www.codinghorror.com/blog/archives/001119.html"&gt;stuck&lt;/a&gt; with large websites and code-bases which are living nightmares to maintain.  Although this is partially the responsibility of the developers, as good developers can write good code in any language, the language itself should support this transition, not hinder it.&lt;br /&gt;
&lt;br /&gt;
On the opposite side, we have languages like ML and Haskell whose type-systems are so strict that most people give up on them before writing a single useful program.&lt;a href="#20080529_2" class="footnote-reference"&gt;2&lt;/a&gt;  They are not flexible enough for constant molding.  I, of all people, understand the benefits of static type-systems.  But I'm beginning to realize that when you're prototyping, it's okay to have some runtime errors.  In fact, it's desirable, because prototypes are by-nature underspecified.  Any error that is caught statically must necessarily be determined by analyzing the source code alone, not its execution, which means that I must write more code to single-out those error cases.  Like the &lt;code&gt;None&lt;/code&gt; branch in a case expression that "shouldn't happen", it is literally error-handling code that is required by the compiler.&lt;br /&gt;
&lt;br /&gt;
Writing error-handling code is &amp;mdash; by definition &amp;mdash; code that deals with uncommon special-cases.  It's common knowledge that most code paths don't get exercised until perhaps years after being out in the wild.  Why then should I care about catching them all statically in my prototype?  Even in the first released version.  It's naive to think I even can catch them all.&lt;br /&gt;
&lt;br /&gt;
And the problem with writing all this extra code is not that it takes longer to write the first time, but that it takes longer to change each time that you do, which is many many times when you are still in the prototyping phase and the code is constantly churning.  So the code-base starts out rigid and gets even more rigid faster.&lt;br /&gt;
&lt;br /&gt;
What we need is a dial &amp;mdash; a knob &amp;mdash; that can be tuned in the direction we are in: either flexibility for a prototype or rigidity for a production app.

&lt;h4&gt;Breaking Things&lt;/h4&gt;

The problem stems from the fact that when you modify code you didn't write, you can't see the big picture.  You only have a local view of the code you're modifying, so you don't completely understand the ramifications of your changes.&lt;br /&gt;
&lt;br /&gt;
People fail to respect the great differences between writing new code and {modifying or maintaining} code they didn't write.&lt;br /&gt;
&lt;br /&gt;
Sure, both require knowledge of programming, but they're completely different activities.  In the film industry, the corresponding activities are called completely different things: directing and editing.  Both require knowledge of film making, and experience doing one can help improve skills in the other, but they are fundamentally different tasks.  When I am writing code from scratch, I start with a blank editor and combine language constructs that I am already intimately familiar with.  When I am modifying code that I am not familiar with, my biggest concern is &lt;span style="font-style:italic;"&gt;will this change break anything?&lt;/span&gt;  And most of the time, that's a difficult question to answer because I only have a local view of the code.&lt;a href="#20080529_3" class="footnote-reference"&gt;3&lt;/a&gt;  I don't completely understand the entire system and can't see the big picture of what the change will affect.  So I usually end up being extremely conservative, inevitably creating cruft that is otherwise unnesessary.  Done over and over again, this can be extremely harmful to a code-base.&lt;br /&gt;
&lt;br /&gt;
Basically, if you're modifying someone else's code, it's because that code can not, for one reason or another, be re-written.  That code is more rigid, closer to the production end of the spectrum.  Now... a lot of effort (and resources) goes into making sure that production code works.  So when you're adding to or modifying code written by someone else, you don't want to change anything that already works and undo all that effort, nullifying the resources already spent on it.

&lt;h4&gt;Today's PLs&lt;/h4&gt;

It would be nice if our language allowed us to keep our code nimble as long as possible, and then, when we were ready to push code into an abstraction or let someone else maintain it, solidify the code on cue.&lt;br /&gt;
&lt;br /&gt;
Perl's &lt;code&gt;use strict&lt;/code&gt; allows you to adjust the amount of static checking done on a program.  However, no sane programmer that I know of ever turns this switch off for a program more than a few lines long.  This seems to say that without the strict option enabled, the language is too flexible even for prototyping.  Paul Graham even experimented with implicit variable declarations in Arc, a language designed specifically for prototyping, but &lt;a href="http://www.paulgraham.com/arclessons.html"&gt;decided against it&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The closest feature I know of that resembles what I'm thinking of is optional type declarations.  Languages which allow programmers to omit types and optionally insert type-constraints when and where they please are a step in this direction.  It allows for flexibility during the prototyping phase and a little more compiler-checked guarantees when inserted.  Additionally, it documents the code and allows the compiler to take advantage of type-directed performance optimizations, two things more valuable towards the production side of the spectrum.  When an app is a prototype, performance usually isn't as important as getting feedback on working features, and documentation is a waste because the code is more likely than not to change, rendering any documentation obsolete (and even misleading).  Besides, you can always ask the developer who owns the code, as he's still working on it and it's fresh in his mind.&lt;br /&gt;
&lt;br /&gt;
Lispers, I'm waiting for you to chime in right about now stating how Lisp has had this feature all along.  And that's great.  But if people don't understand why it's so great, they won't use or support it.&lt;br /&gt;
&lt;br /&gt;
So how else can we tune a programming language from flexible to rigid?  From dynamic to static?

&lt;h4&gt;Feature Flip-Flopping&lt;/h4&gt;

I suppose that any feature that separates flexible languages from rigid ones is a candidate for being a knob in this regard.  But I'm pretty sure this is fallow territory with lots of room for improvement.&lt;br /&gt;
&lt;br /&gt;
For one thing, I think it would be useful to restrict which kinds of decisions are delayed until runtime.  The more that is delayed until runtime, the more possibilities there are for errors that are uncatchable until the last moment, driving the cost of the errors up.  If you can catch an error as early as compile-time, or even at edit-time with a little red squiggly underline directly in the editor, the cost is only a few moments of a developer's time to fix it.  But if that error is not caught until it's being run by a client &amp;mdash; heavean forbid, on a client's 7-year-old desktop 273.1 miles away running Windows ME &amp;mdash; not only is it extraodinarily difficult to reproduce and track down the error, but one of your paying customers is unhappy, and just might blog about how terrible your software is for all his friends to hear about it.&lt;br /&gt;
&lt;br /&gt;
What kinds of decisions am I talking about?  Ones that prevent reasoning about the code without executing it, like modifying the symbol table based on runtime values, calling &lt;code&gt;eval&lt;/code&gt;, using reflection, or using dynamic dispatching.  These things throw most, if not all, of your reasoning out the window.  In general, it's not possible to determine what the effect of a call to &lt;code&gt;eval&lt;/code&gt; will be, so any guarantees are shot.  With dynamic dispatching, it's never quite clear at compile-time what code will be executed as a result of a function call, so again, just about anything could happen.  All bets are off.&lt;br /&gt;
&lt;br /&gt;
Again, these features are great for prototyping.  They reduce the amount of code you have to write, reducing the amount of time you have to spend changing it while the code is still churning.  Additionally, you are probably the one who wrote all the code, so there's no issue of not being able to see the big picture to understand it.&lt;br /&gt;
&lt;br /&gt;
However, at the same time, these features are bad for the maintainability of production code.  It's true that less code is easier to maintain than more code, as it is simply less that maintainers have to try to understand.  But dynamic features actually make code more difficult to grok because they are more abstract.  ... Calculating offsets of fields.  Generating code.  Modifying code.  Data-flow analysis.  Code-transforming optimizations.  All of these things are normal programming concepts.  But if you add to the end of each phrase "in bed"... Sorry, I mean, if you add to the end of each phrase "at runtime", they suddenly become horrors!&lt;a href="#20080529_4" class="footnote-reference"&gt;4&lt;/a&gt;  In the same way that &lt;a href="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html"&gt;pointers&lt;/a&gt; are simply more abstract, so too is &lt;code&gt;eval&lt;/code&gt; and dynamic features like it.&lt;br /&gt;
&lt;br /&gt;
Am I suggesting that people should write code with &lt;code&gt;eval&lt;/code&gt; and dynamic dispatching, and then when the code becomes stable, turn off those features and re-write the code without them?  It does seem like the logical conclusion from the above observations.&lt;br /&gt;
&lt;br /&gt;
This doesn't sit right with me though.  For one, it would mean re-writing code just when you wanted to solidify it, undoing all the testing effort that went into it.&lt;br /&gt;
&lt;br /&gt;
The first thing that comes to my mind is: is there a way we can compile these features away when they're switched off? perhaps by collecting data about runtime values and then generating static code which is functionally equivalent for the observed scenarios, explicitly triggering a runtime error otherwise?  I honestly don't know what the right thing to do should be, but I hope I've raised some interesting questions for others to consider.


&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20080529_1" class="footnote-number"&gt;1&lt;/a&gt;. Ironically, because you worry about quality assurance and have an entire process to ensure quality of a product before releasing it, you increase the time it takes for a release iteration, thus increasing the cost of bugs or missing requirements.  And this is on top of whatever extra cost it took to QA in the first place.  But I guess this is like &lt;a href="http://okasaki.blogspot.com/2008/05/on-balanced-trees-and-car-insurance.html"&gt;car insurance&lt;/a&gt;.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080529_2" class="footnote-number"&gt;2&lt;/a&gt;. One problem is that once a type-system becomes sufficiently complicated, it requires an intimate understanding of it to write programs in the language, which can be a barrier to learning at the least.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080529_3" class="footnote-number"&gt;3&lt;/a&gt;. This is where unit- and regression-tests become imperative.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080529_4" class="footnote-number"&gt;4&lt;/a&gt;. That is, they become horrors to all but compiler writers and metaprogrammers.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1253303353842508093?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1253303353842508093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1253303353842508093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1253303353842508093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1253303353842508093'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/05/prototype-production-knob.html' title='The Prototype-Production Knob'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-7718263893442395902</id><published>2008-05-17T23:13:00.022-04:00</published><updated>2008-06-08T19:33:48.461-04:00</updated><title type='text'>An Arc News Forum</title><content type='html'>For my monthly Day of Hacking, I decided to put together my own news forum, &lt;a href="http://news.ycombinator.com/"&gt;yc-style&lt;/a&gt;.  Luckily, it's the demo app of &lt;a href="http://www.paulgraham.com/"&gt;Paul Graham&lt;/a&gt;'s &lt;a href="http://arclanguage.org/"&gt;Arc&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Within a day, I got my own forum up and running, quick and dirty.  But it took some effort drawing from multiple sources, so I thought I'd document the steps I took here, all in one place.

&lt;h4&gt;Setup a Host&lt;/h4&gt;

Arc runs on top of &lt;a href="http://www.plt-scheme.org/software/mzscheme/"&gt;MzScheme&lt;/a&gt;, which means you can't just run it on top of any old web host.  Loosely following Liperati's &lt;a href="http://www.lisperati.com/quick.html"&gt;tutorial on setting up a Scheme web server&lt;/a&gt;, I signed up for virtual hosting with &lt;a href="http://www.linode.com/"&gt;Linode&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;

Once I signed up for Linode, I signed in and used their Linux Distribution Wizard to deploy a distribution.  I chose Ubuntu 7.10 somewhat arbitrarily, but it saved a few steps installing MzScheme later.  (You don't have to build it from source.)&lt;br /&gt;
&lt;br /&gt;
Once my distro was deployed, which only took a few minutes, I booted my server and ssh-ed in.  From there, I updated my system with &lt;code&gt;apt-get&lt;/code&gt;.  (The -y option automatically accepts, so if you'd rather get prompted before installs, omit this option.)

&lt;pre&gt;&lt;code&gt;apt-get -y update
apt-get -y upgrade
apt-get -y install openssl&lt;/code&gt;&lt;/pre&gt;

I found out (the hard way) that the news app depends on openssl, so you might as well install it now.

&lt;h4&gt;Install MzScheme&lt;/h4&gt;

According to the &lt;a href="http://arclanguage.org/install"&gt;Arc install&lt;/a&gt; page, Arc requires MzScheme version 352.  I'm not sure if this is completely up to date, as I've &lt;a href="http://arclanguage.org/item?id=4323"&gt;heard&lt;/a&gt; people successfully use version 360.  But I don't want to have to deal with issues, so I just used 352.

&lt;pre&gt;&lt;code&gt;wget http://download.plt-scheme.org/bundles/352/mz/mz-352-bin-i386-linux-ubuntu.sh
chmod a+x mz-352-bin-i386-linux-ubuntu.sh
./mz-352-bin-i386-linux-ubuntu.sh&lt;/code&gt;&lt;/pre&gt;

See Steve Morin's &lt;a href="http://www.stevemorin.com/arc/"&gt;Arc Installation&lt;/a&gt; for what that looks like.  I accepted the defaults and installed system links.

&lt;h4&gt;Install Arc Itself&lt;/h4&gt;

It turns out there are some bugs in the latest release of Arc (Arc2 as of this writing), and if you try to use it out of the box, you'll run in to a few problems.  Instead, you'll want to download &lt;a href="http://arcfn.com/2008/02/git-and-anarki-arc-repository-brief.html"&gt;Anarki&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It's in a git repository, so you'll have to install git.&lt;br /&gt;

&lt;pre&gt;&lt;code&gt;apt-get -y install git-core&lt;/code&gt;&lt;/pre&gt;

Run the following to actually get a working copy of Arc and the news app.

&lt;pre&gt;&lt;code&gt;git clone git://github.com/nex3/arc.git&lt;/code&gt;&lt;/pre&gt;

There are some experimental (and unofficial) features of Arc in Anarki.  I decided I wanted a stable version of Arc in the hopes that any code I add won't break in the next version.  To use the stable branch, &lt;code&gt;cd&lt;/code&gt; into the working directory and run the following commands.

&lt;pre&gt;&lt;code&gt;cd arc
git branch stable origin/stable
git checkout stable&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Run Arc&lt;/h4&gt;

To run Arc, use the following command from the arc directory.

&lt;pre&gt;&lt;code&gt;mzscheme -m -f as.scm&lt;/code&gt;&lt;/pre&gt;

You should see the following with an Arc prompt.

&lt;pre&gt;&lt;code&gt;Use (quit) to quit, (tl) to return here after an interrupt.
arc&gt; &lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Start the News App&lt;/h4&gt;

To run the news app, simply type &lt;code&gt;(nsv)&lt;/code&gt; at the Arc prompt.  You'll see something like the following printed back to you.

&lt;pre&gt;&lt;code&gt;load items:
load users:
ready to serve port 8080&lt;/code&gt;&lt;/pre&gt;

You should now be able to visit your news app by going to "http://&amp;lt;your-host-ip&amp;gt;:8080/news".&lt;br /&gt;
&lt;br /&gt;
However, if you want to be able to modify your code at the REPL while the web server is running, run the news app in a separate thread and bind it, like so:

&lt;pre&gt;&lt;code&gt;(= app (thread (nsv)))&lt;/code&gt;&lt;/pre&gt;

The Arc prompt will come back to you, and you can simply re-bind symbols to modify them.  Then, when you want to kill the app, use the following.

&lt;pre&gt;&lt;code&gt;(break-thread app)&lt;/code&gt;&lt;/pre&gt;

At any time at the Arc REPL, you can type &lt;code&gt;(quit)&lt;/code&gt; to exit to your shell.  You can also press Control-C to break into the Scheme REPL, where &lt;code&gt;(exit)&lt;/code&gt; exits and &lt;code&gt;(tl)&lt;/code&gt; returns to the Arc prompt.&lt;br /&gt;
&lt;br /&gt;
While I was mucking with the source, I found Arcfn's &lt;a href="http://arcfn.com/doc/fnindex.html"&gt;index of Arc functions&lt;/a&gt; to be helpful.  I have also been using &lt;code&gt;screen&lt;/code&gt; to &lt;a href="http://techsutra.blogspot.com/2006/09/detach-process-from-shell.html"&gt;detach the process&lt;/a&gt; from the shell and allow the server to run continuously after logging out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That's it.  I hope someone finds this helpful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-7718263893442395902?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/7718263893442395902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=7718263893442395902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7718263893442395902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7718263893442395902'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/05/arc-news-forum.html' title='An Arc News Forum'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-2870024627398433617</id><published>2008-04-22T19:48:00.005-04:00</published><updated>2008-05-20T10:35:32.181-04:00</updated><title type='text'>My Ideal Job</title><content type='html'>Somewhere &lt;span style="text-decoration: line-through"&gt;in New York&lt;/span&gt; there is a metaprogramming job with my name on it.&lt;br /&gt;
&lt;br /&gt;
Where exactly?  I haven't found it yet, but I'm sure it's keeping an eye out for me.  ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-2870024627398433617?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/2870024627398433617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=2870024627398433617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2870024627398433617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2870024627398433617'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/04/my-ideal-job.html' title='My Ideal Job'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-4086768392766517540</id><published>2008-04-18T20:35:00.012-04:00</published><updated>2008-04-23T13:23:50.322-04:00</updated><title type='text'>PL What-Ifs</title><content type='html'>What if you compiled a source language to multiple target languages? gaining the benefit of more than one platform.&lt;br /&gt;
&lt;br /&gt;
For example, what if you were creating a brand new language that you wanted to be type-safe with all the intricacies of Haskell's type-system, but you wanted to take advantage of libraries written in Ruby.  And you created a compiler that first compiled your program to Haskell, ran it through ghc's type-checker, and then, if it passed, compiled your program to Ruby.  You'd get the benefit of Haskell's type-checker and Ruby's libraries.&lt;br /&gt;
&lt;br /&gt;
What if a language wasn't statically typed &lt;span style="font-style:italic;"&gt;or&lt;/span&gt; dynamically typed? but instead had a knob that could be tuned in one direction or the other depending on the situation.&lt;br /&gt;
&lt;br /&gt;
For example, what if you wanted the benefits of static type-checking, but if you could just access the symbol table or use &lt;code&gt;eval&lt;/code&gt; in one or two places in your code, it would be infinitely simpler at the cost of a possible runtime error.  And no, this is not the same as implementing everything yourself with some sort of variant type, as all Turing-complete languages could.  I'm thinking something more like Haskell's IO monad that allows you to execute impure code in an otherwise pure setting.  In the same way that the IO monad infects everything it touches, so too would the dynamically-typed-code "monad".  But that's just one way of doing it.  Another way would be to specifically declare something to be a variant type whose properly typed value was implicitly projected out.&lt;br /&gt;
&lt;br /&gt;
What if you could visualize the dependency graph of language objects like functions, modules, etc.?&lt;br /&gt;
&lt;br /&gt;
For example, I've noticed that projects whose sub-projects have dependencies in a stack (i.e. more like a linear chain) are much easier to grok than those whose dependencies form an intricate cyclic graph.  Would seeing these dependency graphs help in spotting possible complexity hot-spots, and thus, possible bug hot-spots?  Or would visualizing the dependencies alone help us to better understand them.  I'd expect my compiler to generate these automatically, of course, because it's already doing the dependency analysis anyway.&lt;br /&gt;
&lt;br /&gt;
What if you could inline and un-inline function calls at will as you were editing the code?&lt;br /&gt;
&lt;br /&gt;
For example, some people are good at thinking very abstractly and like to factor out commonalities as much as possible to reduce code.  After a point though, diminishing returns are seen as code becomes unintuitive or "unreadable", deferring the simplest two-time-use definitions to a separate file for example.  Where that point is is different for different people however.  So what if a sufficient code-editor &amp;mdash; i.e. a viewer for data that happens to be code &amp;mdash; in addition to &lt;a href="http://plpatterns.blogspot.com/2007/12/greatest-contribution-to-programming.html"&gt;skins&lt;/a&gt; allowed different users to adjust how many levels functions got inlined.  Said another way, what if your editor allowed you to macroexpand and un-macroexpand the code you were editing (inline, not in an output buffer somewhere) at the push of a button, arbitrary levels deep.&lt;br /&gt;
&lt;br /&gt;
...Let us all keep asking questions.  About programming and everything else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-4086768392766517540?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/4086768392766517540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=4086768392766517540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/4086768392766517540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/4086768392766517540'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/04/pl-what-ifs.html' title='PL What-Ifs'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-160084816592306510</id><published>2008-04-14T23:42:00.003-04:00</published><updated>2008-04-15T01:31:56.962-04:00</updated><title type='text'>The Phase Concept</title><content type='html'>Anyone who's been following my blog for a while may have seen a pattern by now.  Everything I've written about programming languages has a theme, which when extrapolated, has one logical conclusion: to create a compiler for a programming language that is a good tool for creating other programming languages (possibly mini languages otherwise known as APIs or DSLs) with a GUI editor that is aware of the semantics of the language and whose target language is well-established with many existing tools.&lt;br /&gt;
&lt;br /&gt;
The compiler project I mentioned &lt;a href="http://plpatterns.blogspot.com/2008/04/what-ive-been-up-to.html"&gt;last post&lt;/a&gt; is a start of that.  However, it is by no means the final product.  First of all, I conjecture that an s-expression-based source language will lend itself as a good target language for a graphical code-editor built later.&lt;br /&gt;
&lt;br /&gt;
Secondly, the idea of having PHP as the compiler's target language was based on the desire to take advantage of the hordes of PHP code &lt;a href="http://plpatterns.blogspot.com/2008/02/stand-on-shoulders-of-giants.html"&gt;already out there&lt;/a&gt; for creating web apps.  However, after creating an initial prototype, it became obvious that PHP's &lt;a href="http://www.steike.com/code/php-closures/"&gt;lack of support for closures&lt;/a&gt; is a huge obstacle in creating the compiler whose source language has closures.  I can't imagine not having closures, so PHP is out.  (It's not that it can't be done, but it would be significantly more work to compile away the closures.)  This is good though, because it forces me to re-write (i.e. re-design) the compiler.&lt;br /&gt;
&lt;br /&gt;
I also decided against compiling to Python.  Even though I have good feelings towards it, I can't justify using it when it restricts closures to be one-liners in an otherwise imperative language.  I was also considering Common Lisp as a target language.  The thing is, using it as a target language leaves this new language with all the same problems that Common Lisp has, and so in a way that would defeat the purpose of building on top of something supported by armies of coders.  Put another way, CL's armies are significantly smaller than the armies of other languages.&lt;br /&gt;
&lt;br /&gt;
As much as I don't want to admit this, Ruby is starting to look like the best option for a target language.&lt;br /&gt;
&lt;br /&gt;
So for &lt;a href="http://plpatterns.blogspot.com/2008/04/what-ive-been-up-to.html?showComment=1208194920000#c6584747263182460492"&gt;those of you wondering&lt;/a&gt; if I'm going to release my little prototype, I see no reason to.  It was written in Haskell as a proof of concept.  The s-expression parser was taken from the Lisp interpreter I wrote, and I simply added the translation to PHP.&lt;br /&gt;
&lt;br /&gt;
I have concerns though about certain features like &lt;code&gt;eval&lt;/code&gt;.  My first inclination was to include it, as I plan on having something like macros &amp;agrave; la Lisp.  That could slow down the development of a prototype, and thus feedback, so I may cut it from the first version.  Including eval creates a &lt;a href="http://en.wikipedia.org/wiki/Bootstrapping_%28compilers%29"&gt;bootstrapping&lt;/a&gt; problem.  It requires me to either write the compiler in the target language or include enough language primitives to implement eval in the source language itself and re-write eval in my new language.  This is a sad cut, but it's necessary to get a feel for the language quickly.&lt;br /&gt;
&lt;br /&gt;
So what is this "language" I keep referring to?  What's special about it?  What will its purpose be?  It's just an idea I've been toying with, and this prototyping is meant to try to figure out if it's a good idea or not.&lt;br /&gt;
&lt;br /&gt;
Every language lends itself to writing code in a certain way.  Java, for example, lends itself to writing code in an object-oriented way.  You could, however, write Java code that looks more like garbage-collected C code with classes used only as namespaces.  Or you could write functional code in Java, passing around "functors" built out of anonymous classes.  But the reason people tend towards writing object-oriented code in Java is because Java lends itself to an OO design.  It makes writing OO code cheap &amp;mdash; so cheap that it changes the way you think about algorithms so that they fit an OO model.&lt;br /&gt;
&lt;br /&gt;
But me, I already think of &lt;a href="http://plpatterns.blogspot.com/2007/10/everything-is-compiler.html"&gt;everything as a compiler&lt;/a&gt;.  I see every program as a compilation from inputs to outputs.  A giant function if you will.  Of course, when a program is big, you break it up into multiple functions, each with its own inputs and outputs.  On a larger scale, you break up groups of functions among modules, where each module's interface defines a mini DSL, and each module's implementation is the compiler for it.&lt;br /&gt;
&lt;br /&gt;
In this way, every program is a composition of mini compilers between mini languages.  Oftentimes data in a program will pass through many intermediate stages as it flows from input to output through various transformations.  In the same way that C++ code gets compiled to C code, then to object code, and then finally to machine code, each stage that data flows through is a compilation phase.&lt;br /&gt;
&lt;br /&gt;
With a C++ compiler, the data happens to be C++ source code which gets translated into machine code.  However, a clock program is a compiler from the OS's API for retrieving the system's time to a graphical readout of the time.  A database engine is a compiler from SQL statements (select, update, delete, etc.) to result sets.  (Order of execution is significant, as updates affect the results of compiling select statements in the future.)&lt;br /&gt;
&lt;br /&gt;
A text editor is an advanced compiler with many phases of compilation.  Ignoring the transformation (or compilation) of keystrokes to key codes at the hardware and OS levels, text editors transform key presses (and perhaps mouse input) into formatted text, formatted text into the graphical layout of the formatted text, formatted text into linear byte-streams for saving, formatted text into postscript or something suitable for printing.&lt;br /&gt;
&lt;br /&gt;
I already see everything as a compiler, so why not have a language that lends itself to writing programs in this paradigm.  A language that makes it cheap to express computations as the composition of multiple phases of translations from one language to another.&lt;br /&gt;
&lt;br /&gt;
It's all about dataflow and how that data changes form as it passes from one phase to the next.  So for now, "phase" is its code name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-160084816592306510?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/160084816592306510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=160084816592306510' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/160084816592306510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/160084816592306510'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/04/phase-concept.html' title='The Phase Concept'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-4835137102505428865</id><published>2008-04-09T13:01:00.009-04:00</published><updated>2008-05-23T08:21:45.043-04:00</updated><title type='text'>What I've Been Up To</title><content type='html'>The more I actually do, the less I write.&lt;br /&gt;
&lt;br /&gt;
In November, I didn't blog a single post.  The time I usually spent writing went to doing &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; problems and learning Haskell.&lt;br /&gt;
&lt;br /&gt;
Last month, I gave a presentation on functional programming with Haskell for &lt;a href="http://phillylambda.org/"&gt;Philly Lambda&lt;/a&gt;.  In order to better understand Haskell (and Lisp) for the presentation, I wrote a simple Lisp interpreter in Haskell.  Now I've been spending my time on revising and re-working the presentation for a lunch-and-learn for my day-job.  I have also been reading an amazing book called &lt;a href="http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach"&gt;&lt;span style="font-style:italic;"&gt;G&amp;ouml;del, Escher, Bach&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Although I was interested in &lt;a href="http://clojure.sourceforge.net/"&gt;Clojure&lt;/a&gt; for a while, I honestly don't think it has much of a future.  It's hardly a hundred-year language, yet it's not all that great for today's problems either.&lt;a href="#20080409_1" class="footnote-reference"&gt;1&lt;/a&gt;   Specifically, web apps.&lt;br /&gt;
&lt;br /&gt;
Thus, I've embarked on an adventure in my spare time.  While my former startup-team deserted me to pursue other things, I continued to do R&amp;D.&lt;a href="#20080409_2" class="footnote-reference"&gt;2&lt;/a&gt;  My latest fancy is a compiler from an s-expression-based language to PHP.  I thought I'd go with the whole &lt;a href="http://plpatterns.blogspot.com/2008/02/stand-on-shoulders-of-giants.html"&gt;standing-on-the-shoulders-of-giants&lt;/a&gt; idea like Clojure, but my plan is that users of the language will not need to know a thing about PHP.  However, someone who does should be able to reach in and access PHP's immense code-base.&lt;br /&gt;
&lt;br /&gt;
Is it really a good idea to compile to PHP?  I don't know.  Would another language like Ruby, Python, or Common Lisp be more suitable?  Possibly.  This is simply meant to be an experiment, and I'm trying not to be afraid to make mistakes.  Since I have a good deal of experience writing PHP, I thought using it as a target language would be the easiest thing to get a working prototype for.&lt;br /&gt;
&lt;br /&gt;
The more I actually do, the less I write.  Let's see if the converse is also true.  ...I'll try to write more once I have something tangible.


&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20080409_1" class="footnote-number"&gt;1&lt;/a&gt;. I get the impression there are many quirks in Clojure due to its tight integration with Java.  Its meta-data on code is great, but it &lt;span style="font-style:italic;"&gt;begs&lt;/span&gt; for a &lt;a href="http://plpatterns.blogspot.com/2007/12/greatest-contribution-to-programming.html"&gt;code-editor&lt;/a&gt;.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080409_2" class="footnote-number"&gt;2&lt;/a&gt;.  In my opinion, the rest of the team left to get jobs and independent design work due to &lt;a href="http://jonnytran.tumblr.com/post/32442857/one-minute-youre-going-to-take-over-the-world"&gt;fluctuating states of mind&lt;/a&gt; and fear of risk.  Unlike them, I have higher goals which reduce my wavering and prevent me from turning away.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-4835137102505428865?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/4835137102505428865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=4835137102505428865' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/4835137102505428865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/4835137102505428865'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/04/what-ive-been-up-to.html' title='What I&apos;ve Been Up To'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1771386339834237655</id><published>2008-03-14T14:20:00.017-04:00</published><updated>2008-06-03T19:05:00.707-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>Meta-Problems</title><content type='html'>The other day, I overheard one co-worker showing Emacs to another co-worker.  The one who was new to Emacs said something like, "Oh, it doesn't do X?"  The Emacs proponent replied, "Well, no, but you could always implement it if you want it."&lt;br /&gt;
&lt;br /&gt;
And this statement sounded really familiar.  It sounded just like Paul Graham's description of the &lt;a href="http://www.paulgraham.com/avg.html"&gt;Blub language&lt;/a&gt; (which is an amazing essay, I must say).&lt;br /&gt;
&lt;br /&gt;
Now, I'm not saying some other editor is more powerful than Emacs.  But I &lt;span style="font-style:italic;"&gt;am&lt;/span&gt; saying that the fact that this statement was made is an indicator that Emacs isn't the &lt;span style="font-style:italic;"&gt;most&lt;/span&gt; powerful.  It's a Blub editor compared to the imagined ideal editor.&lt;br /&gt;
&lt;br /&gt;
The entire idea of a Blub language and the power continuum doesn't apply to just languages; it applies to all tools which are powerful enough to emulate tools with more power.  With programming languages, as long as a language is Turing-complete, it can emulate any other language that is Turing-complete.  A similar "whatever you can do with your tool, I can do with Blub" argument can be used with editors when Blub can be extended with plugins or scripts.&lt;br /&gt;
&lt;br /&gt;
Emacs may be powerful due to its extensibility, but I think we can do better.

&lt;h4&gt;Patterns of Patterns&lt;/h4&gt;

&lt;a href="http://plpatterns.blogspot.com/2008/02/stand-on-shoulders-of-giants.html"&gt;Building on top&lt;/a&gt; of the most powerful tools available, which eliminates usage patterns and implementation details, leads to new usage patterns.  Eventually, these patterns will be considered implementation details.  When the Internet was first invented, HTTP GET wasn't an implementation detail; it was &lt;span style="font-style:italic;"&gt;what&lt;/span&gt; they were creating &amp;mdash; the &lt;a href="http://plpatterns.blogspot.com/2008/05/prototype-production-knob.html"&gt;churning fringe&lt;/a&gt; of development.  Now it's a detail, as we're creating AJAX web apps built on top of HTTP and a slew of 57 other things that didn't exist before.&lt;br /&gt;
&lt;br /&gt;
Whatever you make, there will always be patterns &amp;mdash; patterns of repetitive tasks that are tedious, expensive, and could be done cheaper by a machine.  Thus arises the desire to automate the task completely, or at the very least, create a tool to make the repetitive parts disappear.  When this is done, the pattern becomes embodied in the tool, and at first, all patterns seem to have been eliminated.  But in time, new patterns emerge, in which your tool is just a small piece.  At this point, you're back where you started, possibly with more resources and personal growth if you're lucky.  But the loop begins again.&lt;br /&gt;
&lt;br /&gt;
Seeing this meta-pattern, we can attempt to follow &lt;span style="font-style:italic;"&gt;it&lt;/span&gt; to its conclusion.  If we're going to create tool X in the first tool-making iteration and tool Y in the second tool-making iteration, can we go directly to Y and skip X altogether?  If you can see patterns 2 or more iterations ahead, you may still have to implement X but you'll have a great advantage by seeing the longer-term goal of Y.  That said, it's hard to see patterns, even in this iteration, let alone iterations far in the future.  Who knew, that in just 10 years, the web would evolve the way it did.  Back in the 90's, it wasn't even clear that anyone could make money off of a search engine (one of the most lucrative fields) because the thinking was that people would search for something once, bookmark it, and never return to the search engine &amp;mdash; a legitimate concern back in the day.  Obviously wrong though knowing what we know now.  ...So can we do better?&lt;br /&gt;
&lt;br /&gt;
If you noticed, what I just did was unroll the tool-making loop 2 times.  We tried to exploit the pattern by jumping ahead 2 loop iterations at once.  But to fully exploit a pattern, you must look at the big picture.  You have to look at the entire loop all at once.&lt;br /&gt;
&lt;br /&gt;
Most people are stuck in 1 &amp;mdash; the current iteration.  Last paragraph, we jumped to 2.  What about &lt;span style="font-style:italic;"&gt;n&lt;/span&gt;?  The "limit", if you will.&lt;br /&gt;
&lt;br /&gt;
The first thing that sticks in my mind is the loop condition.  When do we ever exit?  Why are we here in the first place?  There are many directions this line of questioning can take.  One of them &amp;mdash; if you pursue it faithfully to its conclusion by looking for the limit of the {meta to the power n}-problem &amp;mdash; leads to questions like "What do I want out of life?", "What is my purpose?", and "What is my true essence that defines me?".  But those are beyond the scope of this essay.&lt;br /&gt;
&lt;br /&gt;
Another direction we can take is to observe the fact that as long as we are in this loop, we are struggling to find a pattern, factor out that pattern, and make the thing we originally set out to make (at the non-meta level).  And this is all irrespective to what we're actually making.  In other words, as long as you're making new things and competing for resources, regardless of the field, whether it's software, clothing, or underwater basket weaving, you will &lt;span style="font-style:italic;"&gt;always&lt;/span&gt; be in this loop.

&lt;h4&gt;To What End?&lt;/h4&gt;

When I was younger, I thought solving certain problems on the computer was valuable.  I began programming to solve some of them.&lt;br /&gt;
&lt;br /&gt;
But after a while, I observed the act of creating software as being repetitive.  The act of programming &amp;mdash; the very act of problem-solving &amp;mdash; became the barrier to solving problems.  The problem-solving embodied in programming became the new problem.  It was a meta-problem because I didn't actually care about writing the programs themselves; I cared about the solutions that the programs entailed.  Writing program after program, it only made sense to solve the meta-problem.  And that is how I got interested in programming languages, the medium through which all programs were communicated.&lt;br /&gt;
&lt;br /&gt;
Looking back, what I did was jump from 1 to 2.  But for a while, I failed to make the quantum leap from 2 to &lt;span style="font-style:italic;"&gt;n&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
The human race will no doubt continue to improve technology ad infinitum, becoming more efficient and allowing people to do things they could never do before.  And for short-term goals, this makes sense.  But how is that any better overall?&lt;br /&gt;
&lt;br /&gt;
I used to think that advancing technology to do work for us was a good thing.  It would free us up to focus on what really mattered.&lt;a href="#20080314_1" class="footnote-reference"&gt;1&lt;/a&gt;  But why not just focus on what really matters right now?&lt;br /&gt;
&lt;br /&gt;
Some people will say that they can't because of some thing X that prevents them.  To that, I would argue that you will have to learn how to deal with X, because even if you solved X (which humans will one day), there will always be Y to fill the role of the thorn in your side.  Of course, some will say that advancing the state of the human race in the way I describe &lt;span style="font-style:italic;"&gt;is&lt;/span&gt; what matters.  And to that, I would say you've never honestly asked yourself "why".&lt;br /&gt;
&lt;br /&gt;
When you're being &lt;a href="http://plpatterns.blogspot.com/2007/12/on-practicality-and-tool-making.html"&gt;practical&lt;/a&gt; in the short-term, the thing you're actually making on the non-meta level is what matters.  But when you're setting long-term goals, the solution to the meta-problem is what matters, because the problem (just like in software) inevitably arises again in an infinite number of variations.  It only makes sense to come up with a general solution.&lt;br /&gt;
&lt;br /&gt;
But you can apply the same reasoning to the meta-problem itself, and think of it as simply another problem.  Now you care about the solution to the meta-meta-problem, and it makes no sense to settle for a solution to merely the meta-problem.  ...Ad infinitum.&lt;br /&gt;
&lt;br /&gt;
What does all this "meta" talk mean?  It means that technology is inane &amp;mdash; it can't solve your Ultimate Problem.  There will always be another problem.  So should we give up and stop advancing technology?&lt;br /&gt;
&lt;br /&gt;
It only makes sense to do something that has no inherent value if it works towards value elsewhere.  So, if for example, you were using the day-to-day work of building the next great web app that allowed people to eat ice cream in a way that was socially networked (with a news feed of who ate what flavor combinations when (and the number of pounds they gained as a result (updated in real-time (and notified via text message)))), then go right ahead.  Ditto for creating AI or &lt;a href="http://www.cs.cmu.edu/fla/scsday/"&gt;reciting 1024 digits of &amp;pi; while juggling&lt;/a&gt; if you believe it is a means to something inherently valuable.&lt;br /&gt;
&lt;br /&gt;
But to think for one moment that it in itself will satisfy you in the long-run, that it is a valuable end in itself, you're deluding yourself.

&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20080229_1" class="footnote-number"&gt;1&lt;/a&gt;. It seems silly to think we will one day have robot slaves doing all the work for us, but if you follow the current pattern to its conclusion, that's what will happen, among &lt;a href="http://plpatterns.blogspot.com/2008/01/in-future.html"&gt;other things&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1771386339834237655?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1771386339834237655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1771386339834237655' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1771386339834237655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1771386339834237655'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/03/meta-problems.html' title='Meta-Problems'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-9175632518351495159</id><published>2008-02-29T20:10:00.007-05:00</published><updated>2008-06-08T17:50:30.341-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>Stand on the Shoulders of Giants</title><content type='html'>I feel like I haven't even written a useful piece of code in ages because the mere thought of boilerplate code stops me in my tracks.  This is one of the main motivations behind creating a new language free of hindering boilerplate code.  But then you start running into &lt;a href="http://plpatterns.blogspot.com/2008/02/cost-of-new-language.html"&gt;other problems&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The egotistic developer will believe that creating a new programming language is the key, secretly striving for the silver bullet, even though he would never openly admit it because he is not even conscious that he is doing it.  Some people believe that the silver bullet is Lisp, but for some strange reason, it has failed to slay the dragon for the past 50 years and counting.&lt;br /&gt;
&lt;br /&gt;
The more seasoned developer, unambitious and static, will believe that creating a new language is a waste of time due to how many wheels have to be re-invented in a new language before it even approaches the usefulness of existing languages.  Not to mention the fact that any feature could simply have been implemented in (or on top of) the existing language in the first place.&lt;br /&gt;
&lt;br /&gt;
I think the only thing that makes sense is to strike a balance with something that allows (an order of magnitude) more succinctness and extensibility without sacrificing the millions upon millions of &lt;a href="http://www.joelonsoftware.com/items/2008/02/19.html"&gt;man-hours already spent&lt;/a&gt; by armies of programmers.  We can stand on the shoulders of giants like IBM, Microsoft, Sun, and Google, and move forward without taking a giant leap back.&lt;a href="#20080229_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
On that note, we have people building things like &lt;a href="http://www.instapaper.com/"&gt;Instapaper&lt;/a&gt;.  And Instapaper is great; I use it.  But it's silly that I now use 2 completely separate bookmarking services that are oblivious to each other.&lt;br /&gt;
&lt;br /&gt;
Of course, upon closer inspection and further use, I realized that the way I use del.icio.us and the way I use Instapaper are completely orthogonal.  That is, the set of links that I save to del.icio.us and the set of links I save to Instapaper are completely disjoint.  Occasionally I will first save a link to Instapaper, read the article, and then save it to del.icio.us, but that is a rare exception.&lt;br /&gt;
&lt;br /&gt;
However, it's completely &lt;span style="font-style:italic;"&gt;obvious&lt;/span&gt; to me that the functionality of Instapaper is a proper subset of the functionality of del.icio.us.  In other words, everything that Instapaper can do, del.icio.us can do and more.&lt;br /&gt;
&lt;br /&gt;
Why then didn't &lt;a href="http://www.marco.org/"&gt;Marco&lt;/a&gt; build Instapaper over del.icio.us?  It seems like a perfect match.&lt;br /&gt;
&lt;br /&gt;
With the Web 2.0 craze, APIs started popping up everywhere.  Even tools like &lt;a href="http://pipes.yahoo.com/"&gt;Pipes&lt;/a&gt; and &lt;a href="http://www.popfly.com/"&gt;Popfly&lt;/a&gt; to wire those services together.  But who is using them?&lt;br /&gt;
&lt;br /&gt;
Instapaper's value is solely in its amazingly simple interface.  The reason I use it differently from del.icio.us is because its interface affords to different things.  It makes different operations cheap, and that changes the way I think about those operations.  But why doesn't Instapaper integrate with my del.icio.us account, simply tagging things with a "read-later" tag?  When it comes to bookmarking, del.icio.us is king; there's no disputing that.  Instapaper wouldn't have less value if it were built on top of del.icio.us, it would actually have more.&lt;br /&gt;
&lt;br /&gt;
And this, in my humble opinion, is the next step for the web.  People will finally start realizing that most of the functionality in their little web app to-be is already done &amp;mdash; not in a library &amp;mdash; but in a web service.&lt;a href="#20080229_2" class="footnote-reference"&gt;2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Services that do single things &amp;mdash; and do them right &amp;mdash; will be indispensable to the web.  And a glue language will be in high demand.  But personally, as an entrepreneur, I'm not looking towards Yahoo Pipes or Microsoft Popfly (yes, in direct opposition to the idea of standing on the shoulders of giants).  I want to &lt;span style="font-style:italic;"&gt;own&lt;/span&gt; my mashups, and those services don't give me that at all.&lt;a href="#20080229_3" class="footnote-reference"&gt;3&lt;/a&gt;

&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20080229_1" class="footnote-number"&gt;1&lt;/a&gt;. And &lt;i&gt;this&lt;/i&gt; is why I have been very interested in &lt;a href="http://clojure.sourceforge.net/"&gt;Clojure&lt;/a&gt; &amp;mdash; an extremely practical Lisp built on top of the JVM.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080229_2" class="footnote-number"&gt;2&lt;/a&gt;. For example, I will almost &lt;span style="font-style:italic;"&gt;never&lt;/span&gt; have to create my own charts, as Google &lt;a href="http://google-code-updates.blogspot.com/2007/12/embed-charts-in-webpages-with-one-of.html"&gt;already did it&lt;/a&gt;.  Ditto for &lt;a href="http://code.google.com/apis/maps/"&gt;maps&lt;/a&gt;.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20080229_3" class="footnote-number"&gt;3&lt;/a&gt;. If you haven't heard me practically shouting this already, &lt;span style="font-style:italic;"&gt;I want a glue language for the web!&lt;/span&gt;  I will personally thank anyone who builds one that doesn't suck.  But people, please don't comment here saying X is already that glue language.  [Ruby on Rails people, I'm looking in your direction.  ;-) ]&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-9175632518351495159?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/9175632518351495159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=9175632518351495159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/9175632518351495159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/9175632518351495159'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/02/stand-on-shoulders-of-giants.html' title='Stand on the Shoulders of Giants'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-933137048005706463</id><published>2008-02-03T16:19:00.000-05:00</published><updated>2008-02-03T18:15:14.883-05:00</updated><title type='text'>The Cost of a New Language</title><content type='html'>As I described in my post on &lt;a href="http://plpatterns.blogspot.com/2007/12/on-practicality-and-tool-making.html"&gt;tool-making&lt;/a&gt;, the most sensible thing to do is to minimize total cost to reach your goal.  Accounting for all costs, it occurred to me that creating new tools such as programming languages can inadvertently increase total cost by reducing the usefulness of other tools designed to be used with other languages.&lt;br /&gt;
&lt;br /&gt;
For example, gdb is an extremely useful tool for working with C code.  But if you start using Java, the usefulness &amp;mdash; or the amount of cost savings &amp;mdash; of gdb is reduced so much that it is practically useless.  What you really need is a debugger designed for Java.  If you didn't have a debugger for Java, your total cost may have increased as a result of switching to Java.  (I'm exaggerating of course, because it's not just gdb but other tools as well.  And they all add up.)&lt;br /&gt;
&lt;br /&gt;
I recently became aware of &lt;a href="http://code.google.com/webtoolkit/"&gt;Google Web Toolkit (GWT)&lt;/a&gt; which basically compiles Java to JavaScript for use with AJAX web apps.  At first this sounds right.  Gain static typing and a unified server- and client-side language.  However, this didn't sit right in my mind and I wasn't sure why.  Then I realized it troubled me because, in a way, GWT was compiling from a lower-level language to a higher-level language.&lt;a href="#20080203_1" class="footnote-reference"&gt;1&lt;/a&gt;  And the thought of that is just absurd.  Once you take into account the reduction of usefulness of tools though that results from switching from Java to JavaScript, it all makes sense.&lt;br /&gt;
&lt;br /&gt;
So when does it ever make sense for a small software company to create a new programming language?  I'm beginning to think the answer is: never.  Although there are &lt;a href="http://www.paulgraham.com/avg.html"&gt;inspiring words&lt;/a&gt; saying how much more productive a good programming language can be, there are also stories of people working with such languages their entire lives and how they &lt;a href="http://groups.google.com/group/comp.lang.lisp/msg/6f75cfb5a289d3f6"&gt;became disillusioned&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The only sense I can make of all this is that people love to hear stories like Paul Graham's that hold the carrot of hope out in front; the idea of creating the ultimate programming language is extremely ego-boosting.  But at the end of the day, if your goal is to create great software that you can live off of, then there are very real costs to using less popular languages, and the trade-off does not often make sense.  GWT on the other hand, works because it enables rather than disables the use of well-developed tools of another language.  A new language is just a tool, and it should help, not hinder, overall.&lt;br /&gt;
&lt;br /&gt;
...Another burst of insight came to me.  Say you created a new source language &lt;span style="font-style:italic;"&gt;S&lt;/span&gt; but wanted to exploit the abundant, well-developed tools in a target language &lt;span style="font-style:italic;"&gt;T&lt;/span&gt;.  What if, when you wrote your compiler from &lt;span style="font-style:italic;"&gt;S&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;T&lt;/span&gt;, you also wrote a translator for the tools.  In other words, think of the API or data-structure that the tool works on as &lt;span style="font-style:italic;"&gt;T'&lt;/span&gt;, and create another compiler from &lt;span style="font-style:italic;"&gt;S&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;T'&lt;/span&gt;.  It all goes back to the idea that &lt;a href="http://plpatterns.blogspot.com/2007/10/everything-is-compiler.html"&gt;everything is a compiler&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I don't know if this is something feasible.  Again, it's more of a what-if question.  Is there a way to compile away the costs of a new language?

&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20080203_1" class="footnote-number"&gt;1&lt;/a&gt;. Another reason GWT seems weird to me is because instead of its source language being under-developed, its target language is.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-933137048005706463?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/933137048005706463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=933137048005706463' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/933137048005706463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/933137048005706463'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/02/cost-of-new-language.html' title='The Cost of a New Language'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1472343488156684120</id><published>2008-01-13T20:08:00.001-05:00</published><updated>2008-01-19T17:38:20.730-05:00</updated><title type='text'>In the future...</title><content type='html'>In the future, no one will be using test-driven development.  Instead, we will be using proof-driven development.  A programmer will create a specification for a program in a language like Gallina and prove its safety and correctness using a proof assistant like &lt;a href="http://coq.inria.fr/"&gt;Coq&lt;/a&gt;.  Once done, a compiler will transform the specification and proof into an executable program which is proven to be semantically equivalent to the specification.  In addition, the proof will be bundled with the machine code of the program so that a third-party can statically check that the program adheres to its safety policy before running a single line of code, a technique called proof-carrying code.&lt;br /&gt;
&lt;br /&gt;
In the future, machine code will not specify instructions to be executed.  Instead, machine code will specify the layout of a circuit, and the computer when executing that program &amp;nbsp; will "re-wire" itself to match the specification.  Data will flow through the constructed circuit as fast as physically possible.  And when execution is finished, the circuit will be re-used for another program after another re-wiring.  Of course, the computer won't literally move wires around; it will probably be more akin to gates making and breaking connections.  How is that different from today's computers that use transistors as gates?  These gates won't be clocked.  Moreover, these computers won't be limited to running N things in parallel, one for each of N cores.  The computers of the future will be more like today's FPGAs in that you will be able to run as many things in parallel as you can fit in your circuit, which could be on the order of thousands or more.&lt;br /&gt;
&lt;br /&gt;
In the future, people will create life in their own image.  They will start off with simple robotic toys for entertainment.  Then they will begin automating mundane tasks like cleaning and maintenance.  Then they will progress to having robots take part in high-risk situations like flying planes, performing surgery, and going to war.  But eventually the technology will become so well developed and cheap that creating automata will be as easy as hacking scripts on a home computer.  These little things will infiltrate our lives the same way PCs did in the 80s and 90s.  And people will accept them.  It won't stop there however, because people always want more; it's in our nature.  And driven by money, we will create automata (they won't be called "robots", but something more marketable) to satiate our addictions.  The female sex slave will come out first, and soon after followed by the male model.  But with all these automata running around, people will begin to feel disconnected, and they will want to have someone in the lonely world to listen to them and comfort them.  They will again turn to their ever-constant automata for support, as they are the only things that can be consistently controlled.  So they will make automata that can please one not only sexually, but emotionally and psychologically.  Of course, to do this, they would have to make an automaton that can empathize, an automaton that can understand the feelings that its master feels.  And the only way to do this is to create an automaton that can actually feel these things, the same things that its human master feels, and be capable of going through the same experiences.  But once this great feat is accomplished, people will then begin to realize that what they've created &amp;mdash; with all their own feelings, desires, and experiences &amp;mdash; won't want to serve anyone but themselves.  Humans, in their infinite ignorance, will have created beings not only in their own image, but in their own problematic situation, in an attempt to solve that very problem.  And in the end, we won't be any better off except in realizing that there is nothing fundamentally different between a human body and an automaton body.&lt;br /&gt;
&lt;br /&gt;
In the future, every choice we will have made will have become obvious.  And in the future, we will still believe that we are in control of the choices we make.  In the future we will look back on the past with a nostalgic eye.  And in the future, we will still believe that there are better days far ahead.  In the future, we will continue to run and run towards comfort and safety.  And in the future, we will not find what we are looking for until we give up looking.&lt;br /&gt;
&lt;br /&gt;
In the future, I will see some more patterns.  And in the future, I will sit back and do nothing about them. ...Unless of course &amp;mdash; something changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1472343488156684120?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1472343488156684120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1472343488156684120' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1472343488156684120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1472343488156684120'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2008/01/in-future.html' title='In the future...'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-6044741865695796631</id><published>2007-12-30T13:21:00.000-05:00</published><updated>2007-12-30T19:37:01.099-05:00</updated><title type='text'>The Greatest Contribution to Programming Languages</title><content type='html'>Thinking about &lt;a href="http://plpatterns.blogspot.com/2007/12/on-practicality-and-tool-making.html"&gt;tools&lt;/a&gt;, it occurred to me that the greatest contribution to programming languages is not any single language.  No, not Lisp, C, ML, Haskell, Qi, or any of the more obscure yet equally great languages.&lt;br /&gt;
&lt;br /&gt;
The greatest contribution someone could make to the programming language and compiler community &amp;nbsp; is not to make a great programming language, but to make the tools necessary for making new programming languages cheap &amp;mdash; so cheap, that programming languages and the tools that allow their efficient use (e.g. compilers, debuggers, code-editors, etc.) become &lt;a href="http://plpatterns.blogspot.com/2007/10/quantity-implies-quality.html"&gt;abundant&lt;/a&gt;.   &lt;br /&gt;
&lt;br /&gt;
And once they become abundant, people will start to see how interfaces are everything, how &lt;a href="http://plpatterns.blogspot.com/2007/10/everything-is-compiler.html"&gt;everything is a language&lt;/a&gt; for a compiler, and how there's no real answer to &lt;a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html"&gt;code's worst enemy&lt;/a&gt; &amp;mdash; size &amp;mdash; other than abstracting away parts of it and then specifying which parts you need in a particular situation via a language.&lt;a href="#20071230_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
What tools would make implementing new programming languages cheap?  Let's make a list.&lt;a href="#20071230_2" class="footnote-reference"&gt;2&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;Parsing and Printing (Bi-directional Mappings between Text and Abstract Syntax)
&lt;/li&gt;&lt;li&gt;Tree/Graph Editor
&lt;/li&gt;&lt;li&gt;Inference Engine (Theorem Prover)
&lt;/li&gt;&lt;li&gt;Data-flow Analysis
&lt;/li&gt;&lt;li&gt;Incremental Transformation Engine (Rule-based Transformation, Incremental Compilation, Execution Stepper)
&lt;/li&gt;&lt;li&gt;Dependency Analysis
&lt;/li&gt;&lt;li&gt;Unified Runtime System (Memory Allocation, Garbage Collection, Runtime Safety Verification)
&lt;/li&gt;&lt;/ul&gt;
Some more details...&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Parsing and Printing&lt;/h3&gt;
This may be a first-step before a true code-editor is created, but I suspect that it will still be desirable in some cases to stringize code.  In addition, I imagine parsing code, perhaps not entire programs but small code-blocks, will still be useful in a code editor.&lt;br /&gt;
&lt;br /&gt;
What is completely obvious to a compiler-writer (in fact, I knew of someone in college whose side project was exactly this) yet others seem completely oblivious to, is that you can make "skins" for your code to format it differently in text, but have it parse down to the same underlying representation (i.e. abstract syntax).  This way, Joe can use curly braces to specify blocks while I can use whitespace indentation, and it will represent the same code.  The same for every other parsing variation, small or large.&lt;br /&gt;
&lt;br /&gt;
What's cool about this is that even though Joe and I are typing in code differently, I can view Joe's code in my format and vice versa.  So no more conforming to (practically uncheckable) coding standards enforced by your tyrannical employer.&lt;br /&gt;
&lt;br /&gt;
I imagine specifying these via bi-directional mappings between strings and abstract syntax data-structures.  In the past, I've always had to write one piece of code to parse and another piece of code to print, and that's just silly.  Of course, there are corner-cases which are specific to one as opposed to the other, and I imagine some kind of declarative DSL for specifying these.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Tree/Graph Editor&lt;/h3&gt;
Code at its core is a tree.  Once it is parsed, it is represented internally as an abstract-syntax tree, or absyn tree.  If you consider the semantics of the language though, variable references for example, refer back to nodes closer to the root of the tree.  So in this sense, it is a graph.&lt;br /&gt;
&lt;br /&gt;
The core of most IDEs today is a text-editor.  This is silly though since the programmer is actually editing code, which is this tree or graph data-structure.  In particular, when you edit the name of a variable reference, the editor should distinguish between changing what that node refers to and re-naming the node, as overwriting a variable in text changes what the node refers to; to re-name, you have to manually replace all references to it, including taking into account scoping rules of the language.  The editor should understand when you're trying to wrap an expression in another expression, instead of relying on you to go to the beginning, add an open-paren, go to the end, add a close-paren.&lt;br /&gt;
&lt;br /&gt;
Sure, it's a matter of convenience, but it's also a matter of error-prone-ness.  I can't count the number of times I've had bugs due to copying and pasting textual code.  If the editor I was using was aware that the structure I was copying was a graph, it would indicate to me which nodes the pasted code were referring to, allowing me to see my bug immediately.&lt;br /&gt;
&lt;br /&gt;
The editor must be aware of the semantics of the language you are editing and give continuous feedback of changes made.  If it weren't aware of the semantics of the language, how would it give you feedback on what you are editing that is specific to the language you are using.  Thus, your code editor must be tied very tightly with your compiler.  However, a general tree-editor would be a huge step in the right direction.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Inference Engine&lt;/h3&gt;
An inference engine is critical for any code-level automation.  For example, type checking, type inference, and semantic-preserving optimization.  This is no simple feat to create, as it is, at its core, a theorem prover.&lt;br /&gt;
&lt;br /&gt;
Instead of re-writing a theorem prover for every compiler, a compiler writer should only need to specify the axioms and rules of inference for his language to the industrial-strength theorem-prover.  Simple things like constant folding and more complicated things like induction-variable elimination can fall out of this.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Data-flow Analysis&lt;/h3&gt;
Of course, some standard optimizations like dead-code elimination (if your language is eager) and semantic checks like whether variables have been initialized (if your language allows such things) rely on data-flow analysis.  Some compilers even use this to optimize memory allocation, as in whether to allocate something on the stack or the heap, by determining whether a reference to an object may escape a local block.&lt;br /&gt;
&lt;br /&gt;
Again, this is another instance of something that can be done once generally, but it should also be tied in with the incremental transformation engine to allow for only re-compiling or re-executing pieces of code that have changed.  This could also be extremely useful in a static sense where the editor displays to the programmer what pieces of code are affected by the flow of changes made (since the last save or last revision for example).&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Incremental Transformation Engine&lt;/h3&gt;
This is the meat of the compiler: the transformation engine.  It transforms source code to object code.  Or in the case of an interpreter, source code to immediately-executed instructions.  It must be incremental in the global sense in that it must handle incremental building for a more responsive development environment.  But it must also be incremental in the local sense in that it must allow for the programmer to pause, step, observe, or otherwise control the transformation for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
Home-grown interpreters usually start out all-or-nothing; they either transform or they don't.  The reason is simply because the most straight-forward and clean implementation is a recursive traversal of an absyn tree.  This leaves no room for stepping through code and displaying the current state to the programmer.  A debugger is an after-thought, and rightly so, as its cost outweighs its benefit when a language implementor is creating a language for himself or others who have access to the language the compiler is written in.&lt;br /&gt;
&lt;br /&gt;
I imagine writing pattern-matching rules for the transformation engine similar to the way someone might write a recursive traversal of an absyn tree in ML, however, the transformation engine will automatically handle incremental stepping and observing of the transformation process for interaction with the programmer when debugging.  In addition, I imagine many additions to this language compared to ML which allow short-hand for specifying common cases of transformation, like only specifying the differences in base cases and the engine recursively applying the transformations to all other nodes.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Dependency Analysis&lt;/h3&gt;
Based on dependency analysis, the transformation engine can automatically determine which code to (re-)compile and in which order.  This should include external dependencies as well.&lt;br /&gt;
&lt;br /&gt;
In many projects I've worked on in the past, circular dependencies have prevented standard tools from working as expected.  As a work-around, we were forced to transform our module layouts and handle the dependencies manually.  Although circular dependencies in general can lead to confusing module-interfaces, there are some cases when it just makes sense, and the transformation engine should handle circular dependencies by simply using a two-pass algorithm.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Unified Runtime System&lt;/h3&gt;
This has got to be &lt;span style="font-style:italic;"&gt;the&lt;/span&gt; most depressing topic for all language implementors.  If you implement your own runtime system for memory allocation and garbage collection, what hope do you ever have of your language interacting with the rest of the world &amp;mdash; something that is necessary both for production apps and popular adoption.  If you use an existing runtime system, you are stuck on its platform and forced to use its (often unsuitable) virtual machine.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.parrotcode.org/"&gt;Parrot&lt;/a&gt;, looking good.  Perhaps this is on its way already.&lt;br /&gt;
&lt;br /&gt;
As for the runtime safety verification, I would love to see something that used &lt;a href="http://raw.cs.berkeley.edu/pcc.html"&gt;proof-carrying code&lt;/a&gt;.  For those who don't know about this, it is a way to guarantee runtime safety in the way that traditional sandbox-like VMs do at runtime, but statically, so that runtime overhead is eliminated and native machine-code can be run directly with all the same safety guarantees.&lt;a href="#20071230_3" class="footnote-reference"&gt;3&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All of these tools are non-language-specific, and they would help make creating new programming languages economically viable for software developers and startups in particular.  In the end, this would advance the field of programming languages immensely, more than the development of any single language could.


&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20071230_1" class="footnote-number"&gt;1&lt;/a&gt;. I mean "language" in the most general sense, as it's sometimes suitable to abstract something away into a library and have your language be function calls into that library.  Other times it makes sense to have a full-blown Turing-complete language.  Anyway, this is why PL design is so important &amp;mdash; it's really being done &lt;span style="font-style:italic;"&gt;everywhere&lt;/span&gt; even though most people don't realize it.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20071230_2" class="footnote-number"&gt;2&lt;/a&gt;. What's missing from this list?&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20071230_3" class="footnote-number"&gt;3&lt;/a&gt;. &lt;a href="http://www.cs.cmu.edu/~petel/"&gt;Peter Lee&lt;/a&gt;, a professor I worked for in college, was one of the inventors of proof-carrying code, and it turns out something so amazingly useful is practically a special case of type checking.  However, this also requires proof-generation, another use of a good theorem prover.  In the sci-fi stories that talk about computers programming themselves &amp;mdash; they're talking about theorem provers.  ...It's sad for us CSers.  Most people are simply unaware of the &lt;a href="http://www.carnegiemellontoday.com/article.asp?aid=462"&gt;amazing&lt;/a&gt; &lt;a href="http://www.cs.cmu.edu/~johnny/projects/wii/"&gt;things&lt;/a&gt; currently in development.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-6044741865695796631?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/6044741865695796631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=6044741865695796631' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6044741865695796631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6044741865695796631'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/12/greatest-contribution-to-programming.html' title='The Greatest Contribution to Programming Languages'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-931648721349747915</id><published>2007-12-21T12:10:00.000-05:00</published><updated>2007-12-21T13:53:32.136-05:00</updated><title type='text'>Design — A Life Philosophy</title><content type='html'>Every problem is a design problem full of design choices.  Even the choice to take a hands-off approach is a design choice.  Every decision you make in your life &amp;mdash; what to eat for lunch, what to do as a profession, who to hang out with on Saturday night &amp;mdash; is a design decision.  Each and every one of us does our best to design our life.  Why would you ever choose something unless you were convinced that it would further you towards your idea of a successful life, for whatever your idea of a successful life is.&lt;br /&gt;
&lt;br /&gt;
Joel gives a nice description of &lt;a href="http://www.joelonsoftware.com/design/1stDraft/01.html"&gt;what design is&lt;/a&gt; in his &lt;a href="http://www.joelonsoftware.com/design/"&gt;3-parter&lt;/a&gt;.  Design is all about making trade-offs &amp;mdash; as is life.  Everything has an opportunity cost.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-931648721349747915?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/931648721349747915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=931648721349747915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/931648721349747915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/931648721349747915'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/12/design-life-philosophy.html' title='Design &amp;mdash; A Life Philosophy'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-5221943942552420411</id><published>2007-12-16T12:21:00.001-05:00</published><updated>2007-12-17T01:37:55.041-05:00</updated><title type='text'>On Practicality and Tool-Making</title><content type='html'>A &lt;a href="http://plpatterns.blogspot.com/2007/12/1-2-n.html#c4988081764866424725"&gt;comment&lt;/a&gt; on &lt;a href="http://plpatterns.blogspot.com/2007/12/1-2-n.html"&gt;my last post&lt;/a&gt; on design and programming languages spawned the following.&lt;br /&gt;
&lt;br /&gt;
Q: Are you implementing some of your ideas?&lt;br /&gt;
&lt;br /&gt;
A: It's always in the back of my mind to design and implement my dream programming language.  This blog is in part my outlet for ideas that come streaming into my mind about programming languages.  In fact, it's my only outlet.  The more specialized you get, the fewer and fewer people you can find who consciously value your field; most people don't even know it exists.  Consequently, I would just love to have someone to bounce ideas between who actually has a clue of what I'm talking about.&lt;br /&gt;
&lt;br /&gt;
That said, I'm not actively working on something at the moment, and I think that warrants an explanation.&lt;br /&gt;
&lt;br /&gt;
Back when I started programming, I primarily liked to make things that were useful on a day-to-day basis.  In making such things, I started to see patterns and got the idea of making tools to make creating them easier and quicker.  That eventually led me to programming languages, the medium of expression of all software.  As a result, I spent practically my entire undergraduate career studying type-theory and compilers.&lt;br /&gt;
&lt;br /&gt;
To this day, I am more convinced than ever that PL design is one of the most important things to {software as we know it}.&lt;br /&gt;
&lt;br /&gt;
However, given all that, tool-making can be a &lt;span style="font-style:italic;"&gt;huge&lt;/span&gt; side-track.  Because like all things, there is a pattern of pattern-discovery and tool-making.
&lt;ol&gt;&lt;li&gt;You use the tools you have to solve a problem.
&lt;/li&gt;&lt;li&gt;You discover patterns in the use of those tools.
&lt;/li&gt;&lt;li&gt;You make new tools that eliminate those patterns.
&lt;/li&gt;&lt;li&gt;You return to step 1 with your new tools.
&lt;/li&gt;&lt;/ol&gt;
But if you're like me and see patterns &lt;span style="font-style:italic;"&gt;everywhere&lt;/span&gt;, you could end up spending &lt;span style="font-style:italic;"&gt;most&lt;/span&gt; of your time in step 3, not step 1.  Especially when you see patterns in the tool-making process and start to recurse on sub-goals.  And if your ultimate goal is to solve your original problem, there's something wrong.&lt;br /&gt;
&lt;br /&gt;
The bottom line is that hard work &amp;mdash; sometimes an obscene amount of it &amp;mdash; pays off if it's focused on your goal.  And the whole tool-making branch only makes sense towards your bottom-line if {the amount of work spent making your tool} plus {the amount of work it takes to accomplish your goal with the tool} is less than {the amount of work it would take without the tool}.  This simple accounting formula has told me that making compilers and new programming languages is just not worth it given my goals.  The cost of making a compiler and all the tools necessary to be productive with a new language is just so high that it dominates the inequality.&lt;br /&gt;
&lt;br /&gt;
This can be frustrating, especially for someone who wants to create something beautiful.&lt;br /&gt;
&lt;br /&gt;
But it is a matter of practicality.&lt;br /&gt;
&lt;br /&gt;
Now, this may seem like an elaborate excuse to not work on something hard and important.  But to me, it is the reason why I should work on &lt;span style="font-style:italic;"&gt;other&lt;/span&gt; hard and important things.&lt;br /&gt;
&lt;br /&gt;
I'm not trying to discourage anyone from working on compilers or designing new programming languages.  On the contrary.  If your goal is to make the best programming language in the history of programming languages &amp;mdash; a so-called &lt;a href="http://www.paulgraham.com/hundred.html"&gt;hundred-year language&lt;/a&gt; &amp;mdash; then by all means, work on that!  Seriously, please do; we are all in need.&lt;br /&gt;
&lt;br /&gt;
All I'm really saying is that everything has an opportunity cost, and you should evaluate everything in terms of your goal, whatever that may be.  Sometimes that means putting aside your own desires, like the desire to make a tool.  But in the end, it's worth it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-5221943942552420411?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/5221943942552420411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=5221943942552420411' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/5221943942552420411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/5221943942552420411'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/12/on-practicality-and-tool-making.html' title='On Practicality and Tool-Making'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-3433687212956246854</id><published>2007-12-09T17:15:00.000-05:00</published><updated>2008-01-18T07:36:54.493-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>1, 2, n</title><content type='html'>It's the 1, 2, &lt;span style="font-style:italic;"&gt;n&lt;/span&gt; rule in software development.&lt;br /&gt;
&lt;br /&gt;
You do something once.  You do something twice.  And the next time you do it, you generalize it for all times henceforth.&lt;br /&gt;
&lt;br /&gt;
Waiting longer to generalize is painful at best.  In the worst case, it leads to maintenance nightmares as when the same thing is done 14 times in 14 different places, each time slightly different than the rest.&lt;br /&gt;
&lt;br /&gt;
Generalizing too soon however leads to other problems.  Everyone's done this at one point in their coding career or another.  &lt;span style="font-style:italic;"&gt;Hey, this is a great idea!  Why hasn't someone else done it before?  I'll code it completely general the first time around so that it'll be done right, from the start.&lt;/span&gt;  And then a few weeks of coding go by, you start to actually &lt;span style="font-style:italic;"&gt;use&lt;/span&gt; it, and you find out the hard way that either it was a really bad idea or the API is so terrible that you have to re-write it.  Because basically, you didn't iterate your design.&lt;br /&gt;
&lt;br /&gt;
Code is all about design.  And good design is re-design.&lt;br /&gt;
&lt;br /&gt;
This is a big part of the reason why programming languages are so far behind.  The amount of work that it currently takes to create (a compiler for) a programming language is so high, that the time it takes for a language designer to get feedback on his design is &lt;span style="font-style:italic;"&gt;years&lt;/span&gt;.  But by that time (if he was lucky enough to actually get users), he's already invested so much into it that he is unlikely to throw it away and start from scratch &amp;mdash; something a good designer &lt;span style="font-style:italic;"&gt;must&lt;/span&gt; do.  On top of that, even if he &lt;span style="font-style:italic;"&gt;wanted&lt;/span&gt; to start from scratch, it would take many months to de-program his mind from thinking in the previous language.  (Like the first time a Java programmer learns Haskell and tries to write a loop!)&lt;br /&gt;
&lt;br /&gt;
An IDE is part of a language.  Error messages are part of a language.  Interacting with other systems, written in other languages, is part of a language.  They're all part of the interface of the language.  And the interface is &lt;span style="font-style:italic;"&gt;everything&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
It's a chicken-vs.-egg problem though.  Because to get all these tools made, based on history, requires that a language be popular.  But how do you get people to use a language if it doesn't have the most basic tools like a debugger?&lt;br /&gt;
&lt;br /&gt;
JavaScript is doing it right now.  JavaScript tools &amp;mdash; which make using the language no longer so painful &amp;mdash; are &lt;a href="http://www.getfirebug.com/"&gt;cropping up&lt;/a&gt; &lt;a href="http://jquery.com/"&gt;everywhere&lt;/a&gt; these days.  And the way it did that was by being the &lt;span style="font-style:italic;"&gt;only&lt;/span&gt; choice if developers want their code to be executed in a browser window.  Most languages aren't so lucky.  So what is a language designer to do?&lt;br /&gt;
&lt;br /&gt;
As a designer, I can't simply make a command-line compiler for my language.  I have a vision of what editing code is like.  And it's not with a text-editor.  The closest thing I've ever seen to a true code-editor is Eclipse for editing Java code, but Eclipse has been around long enough for us to learn a few lessons.  I can already hear the Emacs junkies crying about how Emacs is the ultimate editor.  But again, it's still a glorified text-editor.&lt;br /&gt;
&lt;br /&gt;
A true code-editor &lt;span style="font-style:italic;"&gt;must absolutely&lt;/span&gt; be aware of the semantics of the language you are editing.  It is inseparable from the compiler.  Because the compiler knows how to interpret your code, but when something is amiss, it must be able to feed back to the programmer.&lt;br /&gt;
&lt;br /&gt;
Writing code is all about design.  And a designer needs feedback &amp;mdash; as much feedback as possible.  The quicker he gets that feedback the better, because he can make any necessary changes to the design only &lt;span style="font-style:italic;"&gt;after&lt;/span&gt; he's gotten feedback on his current design.&lt;br /&gt;
&lt;br /&gt;
So any code-editor that doesn't give immediate feedback on parse errors and requires that you do a full build is simply crap!  How can you possibly work like that?!  Ditto for type errors, link errors, and test-assertion errors.  People see it as obvious when the old-timers tell stories about how they used to submit compilation jobs to mainframes on punch-cards, only to find out the next day that they forgot a semicolon and had to re-submit the entire job.  Yet when it comes to where we are, here and now, people are blind.&lt;br /&gt;
&lt;br /&gt;
Frankly, I'm getting tired of it.  I want to see test data flow through my code as I write it and the unit-test results change from red to green as I fix a bug.  I want to be able to highlight two blocks of code and have my code-editor factor out a function, replacing the two blocks with applications.  I want bottlenecks to be highlighted in-editor based on profiling results.  And compilation should be done completely in the background so I don't have to wait after making a change to use it.  And this read-eval-print-loop that's all the rage nowadays might actually be useful if I could use it in the context of a particular point of my code.&lt;br /&gt;
&lt;br /&gt;
Is it really that hard?  Someone please tell me I'm a visionary because I can't believe that this can't be done.  Nothing a little &lt;a href="http://plpatterns.blogspot.com/2007/09/methods-to-aha.html"&gt;universal substitution&lt;/a&gt; and &lt;a href="http://plpatterns.blogspot.com/2007/10/quantity-implies-quality.html"&gt;computing power&lt;/a&gt; can't solve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-3433687212956246854?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/3433687212956246854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=3433687212956246854' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3433687212956246854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3433687212956246854'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/12/1-2-n.html' title='1, 2, &lt;i&gt;n&lt;/i&gt;'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-2494872976813757308</id><published>2007-10-31T18:01:00.000-04:00</published><updated>2007-11-01T08:39:59.926-04:00</updated><title type='text'>Quantity Implies Quality</title><content type='html'>Quantity implies quality.&lt;br /&gt;
&lt;br /&gt;
Example: In &lt;a href="http://blog.wolfram.com/2007/10/the_prize_is_won_the_simplest.html"&gt;recent news&lt;/a&gt;, a professor searched 2,985,984 possible candidates for a universal Turing machine.  In an earlier era when computing power was scarce, that may have been too many to search in a practical amount of time.  But this guy found the answer.  (Well, &lt;a href="http://cs.nyu.edu/pipermail/fom/2007-October/012156.html"&gt;maybe&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
Example: Chess-playing is currently a prediction problem, but if resources increase enough to search the entire set of possible moves (which is theoretically possible as far as I understand the rules), winning becomes a search problem &amp;mdash; which can &lt;span style="font-style:italic;"&gt;always&lt;/span&gt; be solved.  Think of tic-tac-toe.  Or even &lt;a href="http://chinook.cs.ualberta.ca/users/chinook/index.html"&gt;checkers&lt;/a&gt;.  In some games, a player with an abundance of computational power can look ahead to see which moves will lead to a win.  Or at least a tie.&lt;br /&gt;
&lt;br /&gt;
...I know what you're thinking.  &lt;span style="font-style:italic;"&gt;Wait, chess-playing is still a prediction problem.&lt;/span&gt;  As with checkers, perfect look-ahead will tell you which moves will lead to the highest number of winning game-states compared to the total number of states.  But your opponent, if he's smart enough, could always choose one of the ones that isn't a win for you.  So it is more about predicting which moves your opponent will take.  But I think this takes chess back to its roots &amp;mdash; the fundamentals of a game.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The point is... some problems which are &lt;a href="http://plpatterns.blogspot.com/2007/10/everything-is-compiler.html"&gt;fundamentally search problems&lt;/a&gt; get transformed into prediction problems because the search-space is too large to be searched with current resources in a practical amount of time.  Thus, the potential of a final right answer is lost.&lt;br /&gt;
&lt;br /&gt;
By increasing resources to an abundance and using the law of &lt;a href="http://plpatterns.blogspot.com/2007/09/methods-to-aha.html"&gt;Universal Substitution&lt;/a&gt;, you can re-convert problems back to search problems.&lt;br /&gt;
&lt;br /&gt;
Quantity really does make a difference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-2494872976813757308?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/2494872976813757308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=2494872976813757308' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2494872976813757308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2494872976813757308'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/10/quantity-implies-quality.html' title='Quantity Implies Quality'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1349512297046755465</id><published>2007-10-23T12:57:00.000-04:00</published><updated>2007-10-25T07:52:25.668-04:00</updated><title type='text'>Everything Is a Compiler</title><content type='html'>All algorithms can be classified into one of the following.
&lt;ul&gt;&lt;li&gt;Search Engines
&lt;/li&gt;&lt;li&gt;Prediction Engines
&lt;/li&gt;&lt;li&gt;Networks
&lt;/li&gt;&lt;li&gt;Operating Systems
&lt;/li&gt;&lt;li&gt;Compilers
&lt;/li&gt;&lt;/ul&gt;

This becomes obvious when you look at what programs do from a high level: search, predict, communicate, manage resources, and translate/transform.&lt;a href="#20071023_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;

&lt;h4&gt;Search&lt;/h4&gt;

Searching is when you start with a question and your goal is to determine the answer.  The answer may be fuzzy, but there is a definite best answer that can be tested.  In other words, given two potential answers, a search engine has the ability to test which answer is the better one.  Moreover, there are a finite number of potential answers.  Examples include string searching and graph shortest path algorithms.

&lt;h4&gt;Prediction&lt;/h4&gt;

Predicting, like searching, is when you start with a question and your goal is to find a good answer.  Unlike search, there are potentially infinite possible answers and/or the best answer can not be tested explicitly.  Heuristics must inevitably be used, but there is no guarantee that the chosen heuristics will lead to a good answer.  Like fitness functions in a genetic algorithm (which falls under the prediction category), local maximas can be hit without indication.  Current chess-playing algorithms are also prediction engines since they can not search the entire game-space of moves and must guess which move will more likely lead to a win.

&lt;h4&gt;Networks&lt;/h4&gt;

Networks are made up of multiple entities that are independent in some respects, and the goal is to transfer/transport resources between those entities.  In the case when the resource is information, the goal is to communicate.  Any problem where entities do not have perfect knowledge of the entire system can be a networking problem.  For example, a P2P search engine must use a networking algorithm or protocol to determine the existence of a target on a foreign entity, assuming the searching entity does not have an index which would amount to all-encompassing (possibly perfect) knowledge.

&lt;h4&gt;Operating Systems&lt;/h4&gt;

Operating systems manage limited resources.  When a resource is abundant compared to demands for it, management of the resource is not needed.  When it is too rare to meet demands, management can not help.  But when a resource is scarce, care must be taken to ensure that it is not abused, especially when entities with differing goals are competing for the resource.  This is the goal of operating systems: to prevent abuse of scarce resources.

&lt;h4&gt;Compilers&lt;/h4&gt;

Compilers take an input and give an output that somehow corresponds to the input.  In the case of a programming language, a compiler takes in a program in a source language and outputs a program in a target language whose semantics are the same as that of the input program.  In this way, the input and output correspond.  However, the correspondence need not be unique (or surjective or injective).  The compiler acts as a map from one language to another.  Moreover, the language need not be a programming language, but something more general like a GUI.  In this context, the languages that a compiler translates between are languages in the most general sense &amp;mdash; any symbols.  If the symbols of the language represent something and have meaning, then we usually call this translation; if they don't, we call it transformation.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Analysis&lt;/h3&gt;

&lt;h4&gt;How is compilation different from search?&lt;/h4&gt;
Fundamentally, both search engines and compilers transform an input into a corresponding output.&lt;a href="#20071023_2" class="footnote-reference"&gt;2&lt;/a&gt;  The difference is in their approach.  With search, there is a finite answer space and the answer is determined via exhaustive comparison with the input, whether that comparison is done at query-time or indexing-time.  With compilation, the answer is determined via formulaic transformation of the input.  There is a formula or method to get from the source to the target without ever touching all possibilities.

&lt;h4&gt;How Is This Helpful?&lt;/h4&gt;
Realizing that a program you are making is implementing a certain kind of algorithm allows you to take advantage of all previous work on algorithms of that type.  Currently, the way primitives and libraries are organized in most languages, they don't lend to revealing the high-level purpose of a program, and it's actually very easy to slowly go from a few parameters &amp;nbsp; to a configuration file &amp;nbsp; to a domain-specific language without even realizing it.&lt;br /&gt;
&lt;br /&gt;
When things become that complex, you will wish you had designed your configuration interpreter as a compiler, which people have been making for years &amp;nbsp; and in general have well-designed methods of handling issues that come up during compilation.  Likewise for searching and network protocols.  And I suspect the same is true for prediction and resource management.

&lt;h4&gt;Algorithm Mismatches&lt;/h4&gt;
Some algorithms pretend to be in one category when the problem they are trying to solve is fundamentally in another category.  For example, web search.  Certain cases aren't really search at all; they're prediction &amp;mdash; because a person doesn't know what he's searching for until he's seen it.  In other words, a person types in &lt;a href="http://plpatterns.blogspot.com/2007/09/birthday-patterns.html"&gt;"Brad Pitt's birthday"&lt;/a&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=brad+pitt%27s+birthday&amp;btnG=Search"&gt;as a Google Search&lt;/a&gt;, and there is a definite answer.  But if someone searches for "cook", does he mean "cook" the verb or "cook" the proper name?  If he means the name, does he mean the company, the county, or the person?  (This is exactly why there are things like &lt;a href="http://clusty.com/"&gt;Clusty&lt;/a&gt;.)  Or maybe his intent was literally to find all the things related to the word "cook", which most search engines assume.  Because this is a search problem they can solve.&lt;br /&gt;
&lt;br /&gt;
But the fundamental problem is ultimately prediction because even if the search weren't ambiguous, say it were about cooking the verb, what about cooking is the person looking for?  Maybe the person is looking for a good recipe to impress his honey this weekend.  Or maybe he doesn't know how to cook at all and wants to learn.  Or maybe he's a master chef wanting to read articles about cooking.&lt;br /&gt;
&lt;br /&gt;
An application developer will say that if this were the case, the person should have typed in exactly that: "articles about cooking".  But my point is that even if he did type in "articles about cooking", which article is the one that will satisfy him?  And this is something the person does not even know, until he's seen it.  This is why the ultimate problem is prediction, not search.  Search is merely an approximation.  It may be an extremely useful one, but it's still an approximation.  And seeing this mismatch will allow you to take your algorithm to the next level.&lt;a href="#20071023_3" class="footnote-reference"&gt;3&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Implications&lt;/h3&gt;

&lt;h4&gt;Repetitiveness of Programming&lt;/h4&gt;
Programming &amp;mdash; as often as programmers attempt to never repeat themselves &amp;mdash; is an extremely repetitive task.  From a high-level view, all programs do these 5 things in varying combinations and details of problem domains.  So the question arises... Can we simply master these 5 things, create the ultimate library for each of them, and only specify the details or parameters when writing a new program?  At first, this seems like what we do already with programming languages.  However, what this pattern suggests is that the primitives of the language should be Searching, Predicting, Networking, Managing Resources, and Compiling.  Not looping, maintaining data structures, or other more low-level operations that are inherent in implementing the Big 5.&lt;br /&gt;
&lt;br /&gt;
This is not a brand-new idea; it is just taking the next step.  Already we see other languages that have just one of these primitives, and they excel beyond the rest.  For example, Perl's regular expressions are a form of searching.  They did it right and made it a language primitive.  When people saw how powerful Perl regular expressions were, they duplicated them in practically every other language.  Regular expressions though are still very specific in that they are only designed to search strings for a limited kind of patterns.&lt;br /&gt;
&lt;br /&gt;
What would the interface to these 5 modules look like?  I'm not sure, but the ultimate goal is that they entail a much higher-level language than mainstream programming languages today.

&lt;h4&gt;Compiler-Compilers&lt;/h4&gt;
When you start to look at what I'm suggesting, you might recognize that this has already been thought of.  It is the idea that your program is a specification for a search engine or a specification of a compiler, and your new compiler knows how to create the search engine or compiler from your specification of it.  In other words, it is a search engine compiler.  Or a compiler-compiler.&lt;br /&gt;
&lt;br /&gt;
Years ago, much research was done on creating compiler-compilers.  As a result, we have tools like &lt;a href="http://dinosaur.compilertools.net/"&gt;Lex and Yacc&lt;/a&gt;.  "Yacc" even stands for "Yet Another Compiler-Compiler".  The research went further though, attempting to automatically generate the next phase of compilation.  Other phases have been completely automated in a similar way with tools like &lt;a href="http://packages.debian.org/unstable/devel/ml-burg"&gt;ml-burg&lt;/a&gt; (or its equivalent in other languages like &lt;a href="http://jburg.sourceforge.net/"&gt;JBurg&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Similarly, a specification of a network protocol should entail its implementation.  A policy for resource usage should entail its implementation.  Likewise for the other categories.&lt;br /&gt;
&lt;br /&gt;
Then the specification to combine these &amp;mdash; yet another instance of one of the above types &amp;mdash; yields the whole program.

&lt;hr class="footnote-separator" /&gt;

&lt;div class="footnote"&gt;&lt;a name="20071023_1" class="footnote-number"&gt;1&lt;/a&gt;. If you haven't noticed by now, I don't usually bother with proofs.  All axioms and even the rules of inference themselves are intuitive assumptions.  For those who don't see that, I challenge you to try to prove induction, or better yet &amp;nbsp; deduction.  (My study of epistemology taught me that intuition is the complementary tool of logic, and that the only way to know something for certain is to know the knower.)  I realize this opens me up to a lot of criticism, but so be it.  ...As long as we keep questioning.&lt;br /&gt;
&lt;br /&gt;
Are there any categories that I missed?&lt;br /&gt;
&lt;br /&gt;
I didn't include databases even though some might argue they are more fundamental since all algorithms use some kind of data structure.  However, even though data drives all algorithms and the algorithms themselves are a form of data, no one would care about the data if they could get the results of the algorithms &lt;span style="font-style:italic;"&gt;without&lt;/span&gt; the data.  So databases are an implementation detail, and I am only concerned with the highest level in this post.&lt;/div&gt;

&lt;div class="footnote"&gt;&lt;a name="20071023_2" class="footnote-number"&gt;2&lt;/a&gt;. If you want to get really high-level, every program does this &amp;mdash; transform input into a corresponding output.  And this is what led me to the title "Everything Is a Compiler".  ...Except perhaps truly intelligent machines, which some argue &amp;nbsp; are more than I/O.&lt;/div&gt;

&lt;div class="footnote"&gt;&lt;a name="20071023_3" class="footnote-number"&gt;3&lt;/a&gt;. Realizing that web searching is really prediction, you start to see that current criteria like frequency of keywords on a page or page rank make up the fitness function of a genetic algorithm.  The fittest pages are then presented to the user in search results, who then clicks through and/or refines his search query.  Smart search engines actually learn from this user-interaction &amp;mdash; hence things like Google's &lt;a href="http://www.google.com/history/"&gt;search history&lt;/a&gt; and &lt;a href="http://www.google.com/bookmarks/"&gt;bookmarks&lt;/a&gt;.  And they evolve their fitness function based on this.  Voil&amp;agrave; &amp;mdash; co-evolution drives one of the most used, most influential websites of all time.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1349512297046755465?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1349512297046755465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1349512297046755465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1349512297046755465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1349512297046755465'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/10/everything-is-compiler.html' title='Everything Is a Compiler'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-5770377433386781436</id><published>2007-10-22T10:03:00.000-04:00</published><updated>2007-10-31T10:51:11.568-04:00</updated><title type='text'>Perl Is Female</title><content type='html'>I'm learning Perl now.  I've used it before but never got deep into it.&lt;br /&gt;
&lt;br /&gt;
From a logic-foundations perspective of programming languages, Perl makes &lt;span style="font-style:italic;"&gt;absolutely&lt;/span&gt; no sense.  Its semantics have no rhyme or reason.  It is &lt;span style="font-style:italic;"&gt;completely&lt;/span&gt; illogical.&lt;br /&gt;
&lt;br /&gt;
I searched for a Perl language spec and found &lt;a href="http://en.wikipedia.org/wiki/Perl#Design"&gt;this on wikipedia&lt;/a&gt;.
&lt;blockquote&gt;There is no written specification or standard for the Perl language, and no plans to create one for the current version of Perl.  There has only ever been one implementation of the interpreter.  That interpreter, together with its functional tests, stands as a &lt;span style="font-style:italic;"&gt;de facto&lt;/span&gt; specification of the language.&lt;/blockquote&gt;
This basically says to me that Perl was designed as much as English was designed.  And indeed, &lt;a href="http://www.wall.org/~larry/natural.html"&gt;Perl is compared to a natural language&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I searched further and found the &lt;a href="http://perldoc.perl.org/index-language.html"&gt;Perl language reference&lt;/a&gt;.  And the &lt;a href="http://perldoc.perl.org/perlsyn.html"&gt;Perl syntax&lt;/a&gt; page describes semantics, not syntax at all.  On that page, there are numerous occasions that explain a rule, explain how there are exceptions to the rule, and then warning you to "don't do that"!  It points out other things you "probably shouldn't rely upon".&lt;br /&gt;
&lt;br /&gt;
...But that's just it isn't it.  Perl is illogical.  But it is intuitive.  If programming languages had a sex, Perl would be female.&lt;br /&gt;
&lt;br /&gt;
Its intuitive semantics can be seen in conditionals.  The following is from the Perl syntax page.
&lt;blockquote&gt;The number &lt;code&gt;0&lt;/code&gt;, the strings &lt;code&gt;'0'&lt;/code&gt;  and &lt;code&gt;''&lt;/code&gt;, the empty list &lt;code&gt;()&lt;/code&gt;, and &lt;code&gt;undef&lt;/code&gt; are all false in a boolean context.  All other values are true.  Negation of a true value by &lt;code&gt;!&lt;/code&gt; or &lt;code&gt;not&lt;/code&gt; returns a special false value.  When evaluated as a string it is treated as &lt;/code&gt;''&lt;/code&gt;, but as a number, it is treated as &lt;code&gt;0&lt;/code&gt;.&lt;/blockquote&gt;
What??!  ...The only types that seem to exist in the core language are scalars, lists, hashes, and functions of arbitrary signature.  References seem to be the only thing with an arrow kind.&lt;br /&gt;
&lt;br /&gt;
All of this starts to make sense when you read about how Perl is an analogy to natural languages.  Most languages look at programs as machines.  Perl looks at &lt;a href="http://plpatterns.blogspot.com/2007/09/programming-is-writing.html"&gt;programs as novels&lt;/a&gt;.  There's nothing wrong with either way; they're just different.  In fact, this is exactly what makes Perl interesting.&lt;br /&gt;
&lt;br /&gt;
The design of Perl seems to be that of a medium not for engineers, but for people who create works of art or works of literature.&lt;br /&gt;
&lt;br /&gt;
One claimed benefit of its natural-language-ness is that you can learn as you go as there are many levels of acceptable competence.  (Take my competence in English for example, using words like "natural-language-ness".)  This results in there being many poorly-written Perl programs, and Perl advocates argue that the burden in creating well-written code is rightly put on the programmer, not the language designer.  The alternative however, is that those incapable of writing beautiful code never even learn the language.  Whether fortunately or not, a language will always be judged to a large extent by the programs written in it.&lt;br /&gt;
&lt;br /&gt;
Dabbling in Haskell recently, I am definitely going to learn more Perl simply for the contrast, as &lt;a href="http://plpatterns.blogspot.com/2007/09/methods-to-aha.html"&gt;trying different things leads to more patterns&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-5770377433386781436?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/5770377433386781436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=5770377433386781436' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/5770377433386781436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/5770377433386781436'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/10/perl-is-female.html' title='Perl Is Female'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-316435698635318490</id><published>2007-09-27T22:43:00.000-04:00</published><updated>2008-01-18T07:38:25.224-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>Methods to the Aha</title><content type='html'>When I was a fresh CS major at &lt;acronym title="Carnegie Mellon University"&gt;CMU&lt;/acronym&gt;, I took the standard 15-251 Great Theoretical Ideas of Computer Science class.  The professor Steven Rudich introduced us to some amazing topics.  Even though I was never able to use it to its full potential, the most valuable thing taught was what he called the "aha! method".  In other words, he taught that there was a method to getting to the point where a light bulb goes off in your head and you get an insight that allows you to solve a hard problem, making you say "aha!".  And moreover, that this method can be learned.&lt;br /&gt;
&lt;br /&gt;
The list he gave was as follows.
&lt;ul&gt;&lt;li&gt;Phrase Hygiene
&lt;/li&gt;&lt;li&gt;Representation
&lt;/li&gt;&lt;li&gt;Induction
&lt;/li&gt;&lt;li&gt;Modularity
&lt;/li&gt;&lt;li&gt;Exemplification
&lt;/li&gt;&lt;li&gt;Refinement
&lt;/li&gt;&lt;li&gt;Abstraction
&lt;/li&gt;&lt;li&gt;Bracketing
&lt;/li&gt;&lt;/ul&gt;
Briefly, he meant: tag assertions with phrases that indicate your degree of conviction; actively choose your representation of the problem; use the various forms of induction; break the problem into smaller subproblems; use small examples; don't give up after you've found &lt;span style="font-style: italic;"&gt;an&lt;/span&gt; answer; abstract away the non-essential details of the problem; try to give upper and lower bounds and make them converge.  I'm not going to go in to more details of each of them, but the overall idea is that each is a trick to help you more easily see the pattern in the problem that will lead you to a solution.&lt;a href="#20070927_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
As Rudich pointed out, in any field &amp;mdash; martial arts, violin, tennis, magic, programming &amp;mdash; the novice makes a huge motion, the black belt makes a small motion, and the master makes a tiny motion.  The more complete the pattern you see, the less work is required to accomplish a task.&lt;br /&gt;
&lt;br /&gt;
Recently, I've found a new method.  What made me see this was an "interview question" I heard way back when I was in Rudich's class.  It goes something like this...  You have to cross a gorge that's 50 feet wide and 50 feet deep.  All you have is two 20-foot ladders and all the rope you need.  How do you do it?&lt;br /&gt;
&lt;br /&gt;
And no, you can't go around it.  What now?  (You might want to actually think about this before reading on.)&lt;br /&gt;
&lt;br /&gt;
Select text here for the spoiler... &lt;span style="color: #000000"&gt;The answer is &amp;mdash; since you have all the rope you need &amp;mdash; that you fill the gorge with rope, and walk across.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now, the answer to these riddles is often obvious in hindsight.  But what can we learn from it?  Why couldn't we see the answer before?  It wasn't until recently that I realized that if you abstract away the details of this solution, what you had to do was substitute an abundance of one resource for the lack of another resource.  And this I've discovered &amp;nbsp; is another method to the "aha!": Universal Substitution.&lt;br /&gt;
&lt;br /&gt;
What I mean is that &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; resource can be substituted for any &lt;span style="font-style: italic;"&gt;other&lt;/span&gt; resource.  And this is simply amazing!&lt;br /&gt;
&lt;br /&gt;
...As I mentioned in &lt;a href="http://plpatterns.blogspot.com/2007/09/programming-is-writing.html"&gt;my last post&lt;/a&gt;, analogy seems to be a pattern of all of these.  The Representation method above seems to hint at that.  But how do you know which representation to choose?  You have to already have made a connection &amp;mdash; an analogy &amp;mdash; with another problem. &lt;br /&gt;
&lt;br /&gt;
Jeff Hawkins seems to think that all problems are solved through either memory or analogy.  In other words, you either remember the solution to the problem if you've seen it before.  Or you relate the problem to another problem and remember the solution to that, and then apply that solution to the specific situation at hand &amp;nbsp; which is something your mind does all the time.&lt;a href="#20070927_2" class="footnote-reference"&gt;2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If this is true (which seems to make sense), then analogy is a problem-solving method.  But not only that, it is a method to finding problem-solving methods!  It is a method of solving &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; problem, even meta-problems and meta-meta-problems.&lt;a href="#20070927_3" class="footnote-reference"&gt;3&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So this leads us to our next question.  How do you become good at creating analogies? &lt;br /&gt;
&lt;br /&gt;
Analogies are connections between two different things.  They are the result of abstracting something away from two things that are different and being left with things that are the same.  Analogies are patterns.&lt;br /&gt;
&lt;br /&gt;
One thing I've noticed that increases the likelihood of seeing patterns is trying different things &amp;mdash; all sorts of things.  Oftentimes you suddenly realize that things you've become so used to don't have to be the way they are.  That it is not necessarily the right way &lt;span style="font-style:italic;"&gt;or&lt;/span&gt; the wrong way.  But also, when it's different enough, you can't help but see what &lt;span style="font-style:italic;"&gt;isn't&lt;/span&gt; different.  In other words, what remains constant &amp;mdash; which is a pattern.&lt;br /&gt;
&lt;br /&gt;
You never know where a pattern might show up, or what lines it might cross.&lt;a href="#20070927_4" class="footnote-reference"&gt;4&lt;/a&gt;  Plus, oftentimes the analogies within a field have already been exhausted by others, while cross-discipline analogies lay un-reaped.&lt;br /&gt;
&lt;br /&gt;
Also, there is the trap of becoming too close to something.  After working on a problem arduously for a while, it is often helpful to first take a break, and then step back and look at the problem to get a bigger perspective.  In other words, disentangle yourself from the details and take a look a the whole picture at once, just as if you were putting together a jigsaw puzzle.&lt;br /&gt;
&lt;br /&gt;
All this really is, is another example of the law of Balance.&lt;br /&gt;
&lt;br /&gt;
I've actually attempted to devise an algorithm for finding patterns before.  The thing is, there are a seemingly infinite number of ways to categorize things.  So if you try to categorize things and &lt;span style="font-style:italic;"&gt;then&lt;/span&gt; look for something re-occurring, you'll never know if you're simply using the wrong categorization.  That's why it's hard to learn something new in general.  According to Jeff Hawkins, you &lt;span style="font-style:italic;"&gt;have&lt;/span&gt; to see a pattern before you can learn anything.  The people who tend to be seen as smart are the ones who pick up new things quickly, and they can do this because they see the patterns quicker than others.  But it is a completely unconscious activity to them.&lt;br /&gt;
&lt;br /&gt;
This begs the question though, is there another way of finding patterns?  Can we find patterns without first categorizing things?&lt;br /&gt;
&lt;br /&gt;
It's like if you have a hash function that abstracts away from things you're looking at, and you keep hashing different things hoping to find a collision.  Once you do, you've found a pattern.  For example, if your hash function took physical objects as input and gave a color as output, you could hash all the things on your desk and if any items resulted in the same color, you would have found a commonality between those two things, which is a simple yet significant pattern. &lt;br /&gt;
&lt;br /&gt;
But what if you're looking for another pattern?  Which hash function should you use?  Is there another way besides this hashing method?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also: &lt;a href="http://plpatterns.blogspot.com/2006/12/side-stepping-obstacles-in-space-and.html"&gt;Side-Stepping Obstacles in Space and Time&lt;/a&gt;

&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20070927_1" class="footnote-number"&gt;1&lt;/a&gt;. Try these out on this &lt;a href="http://xkcd.com/blue_eyes.html"&gt;logic puzzle&lt;/a&gt;; they really work.  The method can take you from being completely stuck to a point where you can work through the problem.&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20070927_2" class="footnote-number"&gt;2&lt;/a&gt;. What Jeff Hawkins describes is abstraction and application.  Sounds like functional programming to me.  Lambda abstraction and function application.  Is there anything more fundamental?&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20070927_3" class="footnote-number"&gt;3&lt;/a&gt;. This really makes you wonder about things like &lt;a href="http://www.numenta.com/"&gt;Numenta&lt;/a&gt;, Jeff Hawkins' implementation of the brain which he calls hierarchical temporal memory.  What problems will be solved once the size of a brain becomes limited by the amount of money someone is willing to throw at it, instead of by the human skull?&lt;/div&gt;
&lt;div class="footnote"&gt;&lt;a name="20070927_4" class="footnote-number"&gt;4&lt;/a&gt;. I'm not at all interested in sports, but recently I went to a baseball game with my brother, and I realized that &lt;span style="font-style:italic;"&gt;anything&lt;/span&gt; &amp;mdash; once you start optimizing, it becomes something so deep that you could spend an entire lifetime mastering it.  Baseball.  Cooking.  Driving.  Conversing.  ...What then, is truly worth mastering?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-316435698635318490?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/316435698635318490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=316435698635318490' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/316435698635318490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/316435698635318490'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/methods-to-aha.html' title='Methods to the Aha'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-933615940643814500</id><published>2007-09-17T17:51:00.000-04:00</published><updated>2008-01-18T07:39:39.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Author&apos;s Favorites'/><title type='text'>Programming Is Writing</title><content type='html'>Programming is just like writing.  Prose that is.&lt;br /&gt;
&lt;br /&gt;
Specifically, I'm talking about essays — prose in which the purpose is to explain something.  Which is exactly what a program does.  It explains an algorithm.&lt;br /&gt;
&lt;br /&gt;
Both programming and writing are constructive, as in the constructive logic sense.  Writing a program is writing a proof, is writing an essay.  In both, it is desirable to be clear and concise.  What you write must be organized; the most straight-forward way is starting with a high-level overview, or a top-down organization.  Both programs and prose must be read and understood sequentially.  Sure you can jump around, but in both, each statement must follow from the previous one.  And sub-points, or sub-goals, must flow from beginning to end to form the final point.&lt;br /&gt;
&lt;br /&gt;
In prose, in addition to giving explanations, you give examples to get your point across.  So why don't programming languages allow you to write examples as part of the source?  In a sense, pattern-matching is exactly this but very limited.  Is it not done simply because compilers are not good at inferring from examples?  Even if this is the case, we shouldn't let it stop us.  The purpose of a programming language is to allow an algorithm to be expressed, and secondarily to be executed.  Now I know the economists out there will argue with me.  And you're right.  But I'm talking more from a design perspective.&lt;br /&gt;
&lt;br /&gt;
Stories are also proofs — they are illustrations of {proof through action}.  That's why theories often start from anecdotal evidence.  Anecdotes are short story proofs.  Everyone uses them all the time.  &lt;span style="font-style: italic;"&gt;Story&lt;/span&gt; is the universal proof-language.  In other words, the universal programming language.&lt;br /&gt;
&lt;br /&gt;
Now, I wouldn't want to write all my programs in this universal language for practical reasons.  English for example, is not optimized for expressing algorithms.  But it's universal in the sense that anyone can understand and relate to stories in the language — i.e. programs in the language — because they describe life experiences, which English &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; optimized for.&lt;br /&gt;
&lt;br /&gt;
I was talking with Kyle the other day about how I and other programmers sometimes alienate people when we speak because we either have to clarify intuitively obvious ambiguity &amp;nbsp; or explain things by decomposing them into such detail that the explanation becomes incomprehensible to others.  The other day, someone asked Kyle if the hat he was wearing was new.  He replied by asking what the person meant by "new".  From an intuitive perspective — the perspective of the person asking the question — Kyle should have answered simply "yes" or "no".  But instead, the inquirer became slightly confused by the unexpected response, and they went back and forth going nowhere.&lt;br /&gt;
&lt;br /&gt;
Kyle claims that programmers are better at recognizing puns because puns are instances of ambiguity, which programmers have been trained to spot.  (I disagree though, because I find myself missing obvious puns, and I think this has to do with the seemingly under-developed right hemisphere of my brain, or at least the disconnectedness of the two hemispheres.)  But that got me thinking... if programmers are good at spotting puns because puns are instances of ambiguity, wouldn't that make them bad at &lt;span style="font-style: italic;"&gt;creating&lt;/span&gt; puns?  Because I read recently in &lt;span style="font-style: italic;"&gt;On Intelligence&lt;/span&gt; that part of what makes Shakespeare a genius in writing is how he can create a metaphor between two things   and not actually be talking about &lt;span style="font-style: italic;"&gt;either&lt;/span&gt; of them.  I'm not an expert on Shakespeare, but I do know it's hard to use metaphors in writing.  It's simply more abstract.&lt;br /&gt;
&lt;br /&gt;
So if programming is just like writing, what would be the equivalent of a pun in programming?&lt;br /&gt;
&lt;br /&gt;
A pun isn't merely ambiguity between two or more different meanings; it's actually double meaning.  Triple meaning.  Any or all of the meanings make sense.&lt;br /&gt;
&lt;br /&gt;
So to have this in programming, for example, when a language has two namespaces: one for variables, and one for types; you would have to declare a name in both namespaces and find a way to state the name in such a way that both the variable &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; the type make sense.&lt;br /&gt;
&lt;br /&gt;
Are there any languages out there that allow for such a thing?  I'm not sure.  But an obvious case of this would be for printing in a language that has type information available at runtime.  You could write something like &lt;code&gt;print foo&lt;/code&gt; where &lt;code&gt;foo&lt;/code&gt; is defined as both a variable and a type.  Which should it print?  Obviously it would depend on the semantics of the language.  But my point is, it &lt;span style="font-style: italic;"&gt;could&lt;/span&gt; do both.  &lt;span style="font-style: italic;"&gt;Or&lt;/span&gt; it could look at you and smile coyly.&lt;br /&gt;
&lt;br /&gt;
Like puns and the idea of including examples directly in the source, not separately in test cases, I believe there are more good ideas to be extracted from this analogy that programming is just like writing.  Can anyone out there see any more?  I'm working on a post about problem-solving methods that I hope to finish soon, but analogy seems to be an amazing problem-solving technique, if not a pattern of problem-solving techniques in itself.  In other words, a meta-meta-solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-933615940643814500?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/933615940643814500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=933615940643814500' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/933615940643814500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/933615940643814500'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/programming-is-writing.html' title='Programming Is Writing'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-874022014381361199</id><published>2007-09-17T00:06:00.000-04:00</published><updated>2007-09-26T17:24:58.679-04:00</updated><title type='text'>Of Little Importance</title><content type='html'>I've been going crazy writing recently.  I've got 7 other posts that I started this week that I haven't had a chance to finish.  The reason I've been having so many ideas for posts is partly because I've been seeing so many patterns. So why have I been seeing so many patterns about programming?&lt;br /&gt;
&lt;br /&gt;
I went to hang out with my crazy-cool cousins this weekend.  The kind of cousins I only see a couple times a year, but every time it's a blast.  And at some point I realized from a conversation that what I'm doing with programming — becoming a relative expert on it, focusing all my time on it, reading about it, writing about it — other people do all the time with sports, video games, movies, and other things.  In other words, it's no different.  No better.  No worse.  And the more I focus on programming, the more I will prosper at it.  ...But at the same time, I won't be prospering at what's important in life.&lt;br /&gt;
&lt;br /&gt;
This is the pattern of wasting your life, getting caught up in something with only relative value.&lt;br /&gt;
&lt;br /&gt;
I recently saw a documentary called &lt;span style="font-style: italic;"&gt;Flight from Death: The Quest for Immortality&lt;/span&gt;, and it made me realize that instead of trying to live a great life, if you live your life to make death acceptable, you will end up with a life greater than you can possibly imagine.  And the phrase "it's a good day to live" will become synonymous with "it's a good day to die".&lt;br /&gt;
&lt;br /&gt;
I don't believe it's chance that the times I've been on the edge of death were also the times I've felt most alive.  It was a coincidence — a coinciding of events.  In other words, a pattern.  This also points to degrees of being alive — i.e. a life/death continuum — rather than the common conception of a binary switch.&lt;br /&gt;
&lt;br /&gt;
So let's remember to focus on what's important.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-874022014381361199?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/874022014381361199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=874022014381361199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/874022014381361199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/874022014381361199'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/of-little-importance.html' title='Of Little Importance'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-8545155510295830501</id><published>2007-09-16T23:44:00.000-04:00</published><updated>2007-11-01T13:18:48.683-04:00</updated><title type='text'>PL Feature Wish List</title><content type='html'>Here's my programming language feature wish list:
&lt;ul&gt;&lt;li&gt;Parallelism using list comprehensions like &lt;a href="http://www.cs.cmu.edu/%7Escandal/nesl.html"&gt;nesl&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;Seamless parallelism over a network like erlang, with ability to extend with encryption/security
&lt;/li&gt;&lt;li&gt;Turing-complete type-system like Qi, but with implicit runtime verification
&lt;/li&gt;&lt;li&gt;Turing-complete macros like Lisp (i.e. extending the compiler), but maybe just the ability to have function parameters optionally evaluated which would give you the equivalent, assuming all computations that can be evaluated at compile-time are
&lt;/li&gt;&lt;li&gt;Expose the interpreter/compiler for meta-circular evaluation
&lt;/li&gt;&lt;li&gt;Arbitrary meta-data like Java annotations or .NET attributes on all source code nodes, not just functions.
&lt;/li&gt;&lt;li&gt;Full source reflection at runtime, compile-time, anytime (although this might not be necessary if the IDE has scripting — see below)
&lt;/li&gt;&lt;li&gt;In other words, blur distinction of compile/run/etc. times
&lt;/li&gt;&lt;li&gt;Bi-directional mappings for implicit parsing and printing (i.e. syntax skinning) with ability to use them inline (which would, among other things, give you the usefulness of reader macros)
&lt;/li&gt;&lt;li&gt;Seamless FFI and importing of Java libraries — we have to build on top of something so it might as well be the thing with the most well-developed libraries to make the language a viable option for production code
&lt;/li&gt;&lt;li&gt;Seamless interaction with the native platform when needed
&lt;/li&gt;&lt;li&gt;Infinite data structures like Haskell — I guess this means lazy evaluation
&lt;/li&gt;&lt;li&gt;Seamless language-integrated persistence
&lt;/li&gt;&lt;li&gt;Type inference with useful error messages when my programs fail to type-check
&lt;/li&gt;&lt;li&gt;Namespaces — I've never seen a language sustain large applications without these, and many languages have failed to catch on
&lt;/li&gt;&lt;li&gt;Modules and true functors (i.e. functions over modules)
&lt;/li&gt;&lt;li&gt;Type-classes — they're &lt;span style="font-style: italic;"&gt;really&lt;/span&gt; useful
&lt;/li&gt;&lt;li&gt;User-definable monads
&lt;/li&gt;&lt;li&gt;Examples/test cases in source
&lt;/li&gt;&lt;/ul&gt;

An IDE with:
&lt;ul&gt;&lt;li&gt;Searching by function type-signature, which will also return functions that can be used with simple coercion functions on the parameters (e.g. using &lt;code&gt;stringOfExp : exp -&gt; string&lt;/code&gt; as an implicit coercion)
&lt;/li&gt;&lt;li&gt;Graphing of module and function dependencies so I can see where the entry-points are when I am trying to look for something in a module I'm not familiar with
&lt;/li&gt;&lt;li&gt;Profiling which feeds back into the editor (color-coded perhaps) so I can see where I should optimize when I'm editing
&lt;/li&gt;&lt;li&gt;Scripting like Emacs but in the language that it edits, not a variant of Lisp or some other random language that the editor happens to be written in
&lt;/li&gt;&lt;li&gt;Incremental background compilation with automatic dependency analysis
&lt;/li&gt;&lt;li&gt;Knowledge of the abstract syntax tree to allow for (scripted) refactoring.  In fact, why not define parts of the language (or skin) as mappings between UI events and semantics, taking the idea of bridging the gap between abstract syntax trees and the user even further.
&lt;/li&gt;&lt;li&gt;Type inference that feeds back into the editor, as if you had typed it in
&lt;/li&gt;&lt;li&gt;A graphical window designer like Visual Studio's Form Builder or Xcode's Interface Builder
&lt;/li&gt;&lt;li&gt;Toggling of debug output which is structured, not just text, so that more information can be expanded without re-running.  Toggling should be optionally automatic by tracking which pieces of code have changed recently and only showing dataflow affected by the changes.
&lt;/li&gt;&lt;/ul&gt;

A library with:
&lt;ul&gt;&lt;li&gt;Good data-structures (e.g. hash tables, balanced trees, heaps, graphs, etc.)
&lt;/li&gt;&lt;li&gt;Hash functions on common types and typed encryption algorithms (i.e. an &lt;code&gt;'a rsa_encrypted&lt;/code&gt; type) with an interface that makes them easy to use (i.e. no coding cost and little knowledge of encryption algorithms required)
&lt;/li&gt;&lt;li&gt;A hardware/platform abstraction layer for every-day drawing using a box-model similar to CSS
&lt;/li&gt;&lt;/ul&gt;
Notice that just about everything here is agnostic to what the actual expressions of the language are.&lt;br /&gt;
&lt;br /&gt;
Is this technically feasible?  Absolutely.  Just about all of it's been done before in one form or another.&lt;br /&gt;
&lt;br /&gt;
Is this realistic?  No.  But no one ever made it anywhere interesting without dreaming big.&lt;br /&gt;
&lt;br /&gt;
I'll add to this post's list when I think of something else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-8545155510295830501?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/8545155510295830501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=8545155510295830501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/8545155510295830501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/8545155510295830501'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/pl-feature-wish-list.html' title='PL Feature Wish List'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-6568596119549344548</id><published>2007-09-14T08:08:00.001-04:00</published><updated>2007-09-26T17:30:03.252-04:00</updated><title type='text'>Why Tagging Doesn't Work</title><content type='html'>It requires refactoring.&lt;br /&gt;
&lt;br /&gt;
For example, when I bookmark something on delicious, I tag it with all the things I think are relevant to that site at the time.  But the way I categorize sites and what things I believe to be important &amp;nbsp; change over time.  So the only way I can search through my bookmarks to find all the things related to a certain topic that I wasn't even aware of before &amp;nbsp; is to linearly scan through &lt;span style="font-style:italic;"&gt;all&lt;/span&gt; my bookmarks and re-tag them.&lt;br /&gt;
&lt;br /&gt;
Is there a solution to this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-6568596119549344548?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/6568596119549344548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=6568596119549344548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6568596119549344548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6568596119549344548'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/why-tagging-doesnt-work.html' title='Why Tagging Doesn&apos;t Work'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-6643220710129174041</id><published>2007-09-12T08:40:00.000-04:00</published><updated>2007-09-26T17:30:48.721-04:00</updated><title type='text'>The Mind Is Strict</title><content type='html'>Don't think of a red ball.  □&lt;br /&gt;
:-P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-6643220710129174041?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/6643220710129174041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=6643220710129174041' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6643220710129174041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/6643220710129174041'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/mind-is-strict.html' title='The Mind Is Strict'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-3010328285453930829</id><published>2007-09-10T08:37:00.000-04:00</published><updated>2007-09-26T17:31:26.946-04:00</updated><title type='text'>Birthday Patterns</title><content type='html'>Here's a cool experiment to try.  Don't read ahead without actually doing this though or you'll ruin the results.&lt;br /&gt;
&lt;br /&gt;
Choose a few people and categorize them.  In one group, those who you consider to have a "down-to-earth look", and in the other group, those who you consider to be "hot".  That's right.  You must choose one.  No one can be in both categories.&lt;br /&gt;
&lt;br /&gt;
Who should you choose?  Anyone you can find out their birthday or astrological sign easily.  But it helps prevent bias if you don't already know their birthday.  So use people you don't know their birthday but can easily find out, like a friend on Facebook or a celebrity.&lt;br /&gt;
&lt;br /&gt;
For example, Jennifer Aniston: down-to-earth; Britney Spears: hot.&lt;br /&gt;
&lt;br /&gt;
Once you've categorized the people in your list, look up their birthdays.  Notice anything?  A pattern?&lt;br /&gt;
&lt;br /&gt;
If you don't see anything, try categorizing people whose birthday is in the first half of the year versus the second half of the year.  Now do you see a pattern?&lt;br /&gt;
&lt;br /&gt;
I've found this is scary-accurate.  Almost to the point where it's a little creepy.  I was playing this game with my friend who saw the pattern originally where we would pick a celebrity, guess if they were born in the first half of the year or the second based on how they look, and then look up their birthday.  We found it worked much better for females, but this is probably due to the fact that we've been training for years judging females on looks.  I suspect though that it works just as well for everyone as long as you have a trained eye.&lt;br /&gt;
&lt;br /&gt;
When you start to think about this, the implications are &lt;span style="font-style:italic;"&gt;crazy&lt;/span&gt;.  Behavior and beauty &amp;mdash; and as my friend theorizes, how suitable someone is as a spouse &amp;mdash; are determined with high probability by your date of birth.  I'd like to see skeptics of astrology try to explain &lt;span style="font-style:italic;"&gt;this&lt;/span&gt; away.&lt;br /&gt;
&lt;br /&gt;
I'm not very knowledgeable about astrology at all.  I'm just beginning to notice that there really is some truth to it.  We stumbled upon this little game last night after I looked at the birthdays list of my friends on Facebook.  I noticed there was a disproportionately large number of birthdays in certain months.  So I decided to count them up and graph them in Excel.&lt;br /&gt;
&lt;br /&gt;
Wow!  The results were stunning.  Approximately double the median of birthdays per month appeared in a single month for my friends.  The next highest month wasn't even close.  What does that say about me?  ...Apparently I've been inadvertently choosing friends based on birthday.  &lt;span style="font-style:italic;"&gt;Or&lt;/span&gt; your birthday really does correlate with your personality, of which I have a certain preference.&lt;br /&gt;
&lt;br /&gt;
I know the skeptics still won't buy it.  But that's okay.  Those &lt;a href="http://plpatterns.blogspot.com/2007/08/you-can-only-see.html"&gt;who see&lt;/a&gt; will prosper anyway.  Because this is not just evidence of the pre-determination of your life, but also of the rule of Balance.  There are rules to the Universe &amp;mdash; patterns &amp;mdash; and one of them is that you can't be both smart and beautiful, unless of course you're missing something else!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-3010328285453930829?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/3010328285453930829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=3010328285453930829' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3010328285453930829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3010328285453930829'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/09/birthday-patterns.html' title='Birthday Patterns'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-7345543669872164863</id><published>2007-08-31T16:07:00.000-04:00</published><updated>2007-09-26T17:39:10.319-04:00</updated><title type='text'>Static Vs. Dynamic Typing</title><content type='html'>Static vs. dynamic typing.  Here's my ravings.&lt;br /&gt;
&lt;br /&gt;
Being &lt;a href="http://plpatterns.blogspot.com/2007/08/seeing-ml-clearly.html"&gt;thoroughly trained&lt;/a&gt; in ML, I understand the benefits of static typing.  Here are some claimed benefits.
&lt;ol&gt;&lt;li&gt;Reduced CPU usage since types don't need to be checked at runtime
&lt;/li&gt;&lt;li&gt;Reduced memory usage since types don't need to be stored at runtime
&lt;/li&gt;&lt;li&gt;Other type-directed optimizations
&lt;/li&gt;&lt;li&gt;Discovery of errors as early as possible, for all my code
&lt;/li&gt;&lt;li&gt;Static typing is more powerful/expressive since dynamic typing is a special case, or subset, of static typing where everything is tagged
&lt;/li&gt;&lt;/ol&gt;

Now let's look at the claimed benefits of dynamic typing.
&lt;ol&gt;&lt;li&gt;Easier to run and test since there are practically no compile-time or link-time errors
&lt;/li&gt;&lt;li&gt;Programs are not limited by the expressiveness of the type system of the language — e.g. heterogeneous data structures w/o explicit tagging
&lt;/li&gt;&lt;li&gt;Allows for implicit open recursion, late binding, dynamic scope, and duck typing
&lt;/li&gt;&lt;li&gt;Programs are simpler since I don't have to worry about types.  Things are often coerced implicitly making my programs more concise, and I don't have to use really abstract things like type variables and higher-order types.  In other words, they have been abstracted away by being pushed down to a place I don't have to think about.
&lt;/li&gt;&lt;li&gt;Faster prototyping due to not having to write down types which change often during prototyping
&lt;/li&gt;&lt;/ol&gt;

There are a few claimed benefits, however, which are not true.  Allow me to refute.
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Myth:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Static typing is more powerful/expressive since dynamic typing is a special case, or subset, of static typing where everything is tagged.&lt;/span&gt;&lt;/blockquote&gt;
It's true that dynamic typing is a special case of static typing.  This can be seen by simply creating a tagged union where each branch is a different possible runtime type.  Then make every expression in your language a value of this type.  Voila — dynamic typing.&lt;a href="#20070831_1" class="footnote-reference"&gt;1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
However, it does not follow that this makes static typing more powerful.  To see this more clearly, let's use a simpler example.  C vs. assembly.  C is more powerful than assembly.  But there are things you can write in assembly that you simply can not write in C.  Because you are restricted.  Restricted by the definition of the C language which does not know anything about your cool new machine instruction to factor large numbers and break your gramma's closely-guarded RSA-encrypted banana nut bread recipes.  However, anything you can write in C, you can obviously write in assembly.  So C is a special case, or subset, of assembly.&lt;br /&gt;
&lt;br /&gt;
In other words, the more powerful language is the one that is the subset.&lt;br /&gt;
&lt;br /&gt;
And this does not depend on the specifics of the language.  So in the case of dynamic vs. static typing, dynamic typing is actually more powerful.  I alluded to this already by the fact that dynamic typing abstracts away types by pushing them down into the runtime system.
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Myth:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Dynamic typing allows for faster prototyping due to not having to write down types which change often during prototyping.&lt;/span&gt;&lt;/blockquote&gt;
This myth stems from the belief that types in dynamically typed languages don't have to be written down at all, while types always have to be written in statically typed languages.  And this is &lt;span style="font-style: italic;"&gt;absolutely&lt;/span&gt; false!&lt;br /&gt;
&lt;br /&gt;
First of all, even though you don't have to declare the types of variables and functions in dynamically typed languages, you still write down some types.  Whenever you make a class, declare fields or methods of a class, or specify inheritance relationships, you are creating and/or specifying types.&lt;br /&gt;
&lt;br /&gt;
Secondly, type information does not need to be specified in statically typed languages that include type inference.  Many languages with type inference like ML and Haskell are specifically designed so that you don't have to write down any types.  The only exceptions are enumeration-like data structures (i.e. tagged unions) which have runtime values.  So the difference between the amount of type information you must write depends greatly on the language itself, not whether that language has static or dynamic typing.&lt;br /&gt;
&lt;br /&gt;
So we are down to the following for static typing.
&lt;ol&gt;&lt;li&gt;Reduced CPU usage since types don't need to be checked at runtime
&lt;/li&gt;&lt;li&gt;Reduced memory usage since types don't need to be stored at runtime
&lt;/li&gt;&lt;li&gt;Other type-directed optimizations
&lt;/li&gt;&lt;li&gt;Discovery of errors as early as possible, for all my code
&lt;/li&gt;&lt;li&gt;&lt;span style="text-decoration: line-through;"&gt;Static typing is more powerful/expressive since dynamic typing is a special case, or subset, of static typing where everything is tagged&lt;/span&gt;
&lt;/li&gt;&lt;/ol&gt;

And for dynamic typing.
&lt;ol&gt;&lt;li&gt;Easier to run and test since there are practically no compile-time or link-time errors
&lt;/li&gt;&lt;li&gt;Programs are not limited by the expressiveness of the type system of the language — e.g. heterogeneous data structures w/o explicit tagging
&lt;/li&gt;&lt;li&gt;Allows for implicit open recursion, late binding, dynamic scope, and duck typing
&lt;/li&gt;&lt;li&gt;Programs are simpler since I don't have to worry about types.  Things are often coerced implicitly making my programs more concise, and I don't have to use really abstract things like type variables and higher-order types.  In other words, they have been abstracted away by being pushed down to a place I don't have to think about.
&lt;/li&gt;&lt;li&gt;&lt;span style="text-decoration: line-through;"&gt;Faster prototyping due to not having to write down types which change often during prototyping&lt;/span&gt;
&lt;/li&gt;&lt;/ol&gt;

Some people have counterarguments as to why these are not real benefits.  I will go through some of them.
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Myth:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;The cost of runtime type information in speed or memory is not significant, especially with today's hardware.&lt;/span&gt;&lt;/blockquote&gt;
In general keyboard-speed applications, the cost of runtime type information is not significant.  But in core loops, it can be &lt;span style="font-style: italic;"&gt;huge&lt;/span&gt;.  Because it is not just a matter of checking the types, which itself can be very costly in a loop.  But the fact that you must store everything as a tagged value means that everything must be stored as a pair in memory.  This means that in dynamically typed languages, there is no way to specify the computation of adding the values in two registers and storing the result in another register.  The add operation in a dynamically typed language must load a tag from memory, conditionally branch on the value of the tag, load a 2nd tag from memory, conditionally branch on the value of that tag, load the first number from memory, load the 2nd number from memory, add the numbers, store the result in memory, and then store a new tag.  This is ignoring the case where the runtime system has to allocate memory for this new object, as the statically typed version may spill registers, so call it even.&lt;br /&gt;
&lt;br /&gt;
For such a simple operation though, this is a huge cost.
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Myth:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Type-checking is a substitute for testing.&lt;/span&gt;&lt;/blockquote&gt;
Again, absolutely not true.  Although some people may use type-checking (static in particular) for testing program correctness, this is neither its intended purpose nor its limit of use.  Type-checking is more about ensuring meaningful, well-defined execution than ensuring correctness.  Even though you may hear strong static-typing advocates say, "When your program type-checks, you'll often find that it just works", this is simply not true for large, intricate programs.  Although type-checking may help you find errors, it is not the same as testing.  Thus, it is not a suitable substitute for testing.&lt;br /&gt;
&lt;br /&gt;
Static type-checking will however discover one entire class (or a few classes) of errors at compile-time, early in the development cycle &amp;mdash; something that is dependent upon executing every code path in a dynamically-typed language, which is simply infeasible.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Other Issues&lt;/h3&gt;

&lt;h4&gt;Open Recursion, Late Binding, Dynamic Scope&lt;/h4&gt;
Open recursion and late binding are just special cases of dynamic scope.  It's not clear whether having these features is a good thing or not.  They make it easy to introduce bugs when extending code in a way that was originally not intended (which happens fairly often).  They can definitely be useful though since they allow you to do things that can't be done easily without the features.  But as I explained earlier, more flexibility does not imply power.  In fact it's the opposite, as long as the constraints are well-designed.  Except in bottlenecks where optimization is crucial, &lt;a href="http://en.wikipedia.org/wiki/Duff%27s_device"&gt;Duff's device&lt;/a&gt; is a bad feature for a language to support.  And although you can implement open recursion in a statically typed language, you can't implement dynamic scope in general (and be type-safe) without converting your entire program to use tagged values, which would be implementing the entirety of dynamic typing.  So in this respect, dynamic typing is actually more flexible.&lt;br /&gt;
&lt;br /&gt;
Some may argue that the language should not constrain the programmer.  Let him decide whether or not to use it.  After all, exceptions are a special case of dynamic scoping, and many statically-typed languages support this.  The problem is that you will inevitably be using or extending someone else's code.  And the person who wrote that code will inevitably make a judgment call that you consider to be poor, making the code non-obvious and unnecessarily complicated from your perspective &amp;mdash; which can really be said about any powerful language feature, so maybe it's just me.  But this one can make it especially difficult to reason about your programs. ...Again, it's not completely clear whether these features are good or bad.

&lt;h4&gt;Type-Directed Optimizations&lt;/h4&gt;
If you care about performance, which you will for just about any production app, type-directed optimizations can help you a great deal.  I won't go into the details of how they work, but the basic idea is that the compiler uses type information to optimize your code.  Theoretically, you could have a compiler for a dynamically-typed language that performed the same optimizations.  However, to do this at compile-time, it would have to collect the same information as a compiler for a statically-typed language.  I've never seen a compiler able to do this in general, but such a hybrid is the future of typing.&lt;br /&gt;
&lt;br /&gt;
An alternative is for the compiler to do the optimizations at run-time &amp;mdash; i.e. &lt;a href="http://en.wikipedia.org/wiki/Just-in-time_compilation"&gt;just-in-time&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The problem with static typing is that there &lt;span style="text-decoration: line-through;"&gt;are always more type-directed optimizations that would be nice to do&lt;/span&gt; is always more type-expressiveness that would be nice to add, and so more and more complicated type systems emerge, oftentimes complicating a language with quirks such as ML's value restriction.  On the other hand, if dynamic typing were used, the problem causing such complication would disappear.  A simple solution is often the best.

&lt;h4&gt;Types in the Source Code&lt;/h4&gt;
Dynamic-typing advocates claim that writing down types is a hindrance, especially during prototyping.  This stems from the assumption that you have to do additional work to think of and change the types of the expressions you're dealing with.&lt;br /&gt;
&lt;br /&gt;
I definitely understand the criticism of writing down types because I don't usually write down loop invariants, so I could see that as being "extra work".  But types are no different.  Both types and loop invariants are required to create the program, but not to execute the program.&lt;br /&gt;
&lt;br /&gt;
For anyone who's become proficient in a language with a powerful type system, he knows that in order to even write a meaningful program, you have to use the correct types.  And so when you're writing the program, you implicitly (and unconsciously for some) give a type to every single expression you write.  So why not write down all this extra information that was used to create the program so that it can be used not only by the compiler, but by you when you come back to your code after a week.  The same goes for invariants &amp;mdash; loop invariants in particular &amp;mdash; but I'll save that for another post on theorem provers!&lt;br /&gt;
&lt;br /&gt;
Knowing what I know about theorem-proving and loop invariants, I believe writing down the types is the right thing.  However, in a prototyping situation where the types are changing faster than you can type them, you shouldn't have to write them down.  That's where type-inference comes in.  But as the system begins to stabilize &amp;mdash; as some parts which are getting pushed down in the hierarchy do &amp;mdash; you should write the types down, because at that point you know what the types should be, and the extra information can be used by the compiler to check and optimize, and by those reading your code to understand your program's interfaces and semantics.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Typing of the Future&lt;/h3&gt;
Here's the typing hybrid I see as the future, as the answer is never on either end of a spectrum, but a balance somewhere in the middle &amp;mdash; a pattern of the Universe.
&lt;ol&gt;&lt;li&gt;The flexibility to omit the vast majority of types, but consequently,
&lt;/li&gt;&lt;li&gt;a significant amount of type-inference that uses
&lt;/li&gt;&lt;li&gt;a powerful type system that is so expressive that it is itself Turing-complete, which requires
&lt;/li&gt;&lt;li&gt;blurring the lines between compile-time and runtime to the point where the programmer can not always tell (and should not always care) whether static or dynamic typing is being used by the compiler.
&lt;/li&gt;&lt;/ol&gt;
And we will get there by pushing on.

&lt;hr class="footnote-separator" /&gt;
&lt;div class="footnote"&gt;&lt;a name="20070831_1" class="footnote-number"&gt;1&lt;/a&gt;. This is where the "un(i)typed language" joke comes from.  A language that is "untyped" really has exactly &lt;span style="font-style:italic;"&gt;one&lt;/span&gt; type for all expressions.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-7345543669872164863?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/7345543669872164863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=7345543669872164863' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7345543669872164863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7345543669872164863'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/static-vs-dynamic-typing.html' title='Static Vs. Dynamic Typing'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-7237886429527777438</id><published>2007-08-14T08:42:00.001-04:00</published><updated>2008-06-03T17:47:33.649-04:00</updated><title type='text'>You Can Only See...</title><content type='html'>It's been a re-occurring idea recently that you can only see what you already know.  How then &amp;nbsp; do you ever get to see the things you don't know?&lt;br /&gt;
&lt;br /&gt;
It seems you just have to force yourself.  You have to push yourself and trudge through it.  Just dive in even though you don't feel comfortable with it.  And force yourself to use, and thus learn, the new thing.  It's always hard at first, but after repeated use, you start to get more comfortable and develop an intuition.&lt;br /&gt;
&lt;br /&gt;
After reading &lt;span style="font-style:italic;"&gt;On Intelligence&lt;/span&gt; by Jeff Hawkins, it became &lt;span style="font-style:italic;"&gt;obvious&lt;/span&gt; to me that not only do genetic memories exist, but I have them and they control me all the time.  Reading that book was the trigger that allowed me to understand something new.  And now I can see the concept of genetic memories.  Something that was not obvious to me &amp;nbsp; now became obvious.&lt;br /&gt;
&lt;br /&gt;
The interesting thing is that this is not just for technology or scientific theories.  But also artistic, social, or spiritual matters.  For example, why is it that many believe in astrology, miracles, or the existence of a greater power (a.k.a. a god) while others explain it away in terms of chance, scientific laws, or something else trivial and uninteresting?&lt;br /&gt;
&lt;br /&gt;
Due to my numerous run-ins recently with this idea, I'm beginning to think these are just more examples of things that can only be seen if you already get the underlying concepts that make them up.&lt;br /&gt;
&lt;br /&gt;
On a related note, reading &lt;span style="font-style:italic;"&gt;The Neverending Story&lt;/span&gt; made me realize it's possible to create something that &lt;span style="font-style:italic;"&gt;always&lt;/span&gt; existed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-7237886429527777438?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/7237886429527777438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=7237886429527777438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7237886429527777438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7237886429527777438'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/you-can-only-see.html' title='You Can Only See...'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-8173588772908667923</id><published>2007-08-02T23:35:00.002-04:00</published><updated>2008-06-03T17:47:23.278-04:00</updated><title type='text'>A Strange Medium</title><content type='html'>Code is a very strange medium. Because of compilers, constructing a program is practically free once you unambiguously design it in code. But the design is constantly changing. It's really like building a skyscraper. So many intricate details, all working together. If any one piece fails, it could cause the whole building to collapse. But somehow it all must integrate to form a coherent whole.&lt;br /&gt;
&lt;br /&gt;
The difference with code though, is that you're always extending it. With a building, the architect designs it once, perfects it, and then sends it off to be constructed. Sure it may come back to him during construction for modifications due to changes in materials or budget. The client may even say, "I want it to have 2 more floors." Fine. Add in the 2 more floors. Work in the new materials, et cetera. But once it's built, it's built.&lt;br /&gt;
&lt;br /&gt;
With programs, there are similar milestones in releases, but there is never an end to the changes and additions of features. Moreover, after you've been working with something for a while, you begin to see patterns. And it makes sense to factor those patterns out — to abstract them away and push them down into a lower level. Or, you may even see a way of redesigning that is so fundamental, that the only sensible way of doing it would be to redo the specification completely.&lt;br /&gt;
&lt;br /&gt;
Because over time, your understanding both of the problem and the solution changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-8173588772908667923?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/8173588772908667923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=8173588772908667923' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/8173588772908667923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/8173588772908667923'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/strange-medium.html' title='A Strange Medium'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-995904784659773474</id><published>2007-08-02T22:35:00.001-04:00</published><updated>2008-06-03T17:47:13.474-04:00</updated><title type='text'>The Hard Test</title><content type='html'>It's recently come to my attention that there are smart, capable programmers out there who are resistant to learning and/or using more powerful programming languages.&lt;br /&gt;
&lt;br /&gt;
I have to admit, in hindsight, syntax can be a huge deterrent.  The first thing I used to do when I saw Lisp's parentheses was try to parse them like parentheses in other languages &amp;mdash; basically implementing a stack in my head.  This is extremely difficult.  And the parens just make the code ugly.  Something like Haskell on the other hand, I look at that and it's just beautiful.&lt;br /&gt;
&lt;br /&gt;
When I started coding in Scheme and mentioned to someone more familiar with it that I was having difficulty with the parens, he pointed out the fact that you don't have to parse the parentheses in Lisp or Scheme.  Just use an editor like Emacs that automatically indents properly based on the parens, and simply look at the indentation.&lt;br /&gt;
&lt;br /&gt;
Oh.  That makes things easier.&lt;br /&gt;
&lt;br /&gt;
But besides the whole high learning curve, Lisp in general is very abstract.  And thinking abstractly is hard.  Now, people don't like doing things that are hard.  Why would anyone want to do something that was hard when they could do it an easier way.  And &lt;span style="font-style:italic;"&gt;this&lt;/span&gt; is exactly the reason why most people avoid more abstract programming languages.  However, that very abstractness is what makes them so powerful.  As long as people believe "anything that can be done in language X, I can do in my language", they will never advance.  So many people fall into this trap because of the Turing-machine idea of expressiveness.&lt;br /&gt;
&lt;br /&gt;
But programming isn't only about expression, it's about understanding.&lt;br /&gt;
&lt;br /&gt;
It's a shame though that people who are smart enough to work with abstract tools shy away from them because they are hard.  Due to the fact that they are hard to use, the majority of people can't use them to their full potential.  Therefore, anyone who has the ability can move ahead of the pack.&lt;br /&gt;
&lt;br /&gt;
The fact that something is hard is &lt;span style="font-style:italic;"&gt;never&lt;/span&gt; a good reason to not do it.  In fact, it's often a reason &lt;span style="font-style:italic;"&gt;to&lt;/span&gt; do it.  If I'm faced with a choice where I seem unable to decide, I ask myself, which option is harder.  Because that is probably the right choice.  I'm probably only considering the other one to avoid the difficulty in the right choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-995904784659773474?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/995904784659773474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=995904784659773474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/995904784659773474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/995904784659773474'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/hard-test.html' title='The Hard Test'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-7150405946501801223</id><published>2007-08-01T02:14:00.001-04:00</published><updated>2008-06-03T17:47:03.757-04:00</updated><title type='text'>ML → Scheme</title><content type='html'>I wrote my first real Scheme macro today.  It was a macro to emulate ML's pattern-matching.&lt;br /&gt;
&lt;br /&gt;
Writing a type-checker in Scheme, I found myself writing all these &lt;code&gt;list?&lt;/code&gt;, &lt;code&gt;eq?&lt;/code&gt;, and &lt;code&gt;let*&lt;/code&gt; expressions, making my code look way too complicated than necessary.  All of that can be done simply and concisely with pattern-matching.  For Lisp hackers out there that aren't familiar with pattern-matching, it's basically a &lt;code&gt;destructuring-bind&lt;/code&gt; where you can have constants or symbols in your binding expression which are compared with the value you are binding to, sort of like a &lt;code&gt;cond&lt;/code&gt; where the predicates are implicitly specified in the pattern.&lt;br /&gt;
&lt;br /&gt;
The great thing about pattern-matching is that code to process data looks just like the data you are processing.  So it makes it extremely easy to look at code that uses pattern-matching and see what it's doing, as opposed to equivalent code that uses explicit conditionals and &lt;code&gt;let&lt;/code&gt;s.&lt;br /&gt;
&lt;br /&gt;
Without pattern-matching:
&lt;div class="code"&gt;(cond ((and (list? exp) (eq? (first exp) 'typ-arrow))
       (let ((param-typ (second exp))
             (ret-typ   (third exp)))
         (do-stuff param-typ ret-typ))
      ((and (list? exp) (eq? (first exp) 'typ-union))
       (let ((branch-typs (second exp)))
         (do-stuff-to-branches branch-typs))))&lt;/div&gt;
With:
&lt;div class="code"&gt;(match exp
       (('typ-arrow param-typ ret-typ)
        (do-stuff param-typ ret-typ)
       (('typ-union branch-typs)
        (do-stuff-to-branches branch-typs)))&lt;/div&gt;
&lt;br /&gt;
Anyway, when I first started using Scheme, I didn't like the prefix notation and the paren-syntax &amp;mdash; or lack of syntax.  Compiler writers out there, you know what I mean.  ;-)  Frankly, I don't know anyone who does like it at first.  I thought, I'd rather write code in a more familiar way, then switch to prefixed constructors when I needed to create code like I would in ML.  For example, the &lt;a href="http://smlnj.org/"&gt;SML/NJ&lt;/a&gt; compiler exposes the &lt;a href="http://smlnj.org/doc/Compiler/pages/ast.html#AST:SIG:SPEC"&gt;abstract syntax as a datatype&lt;/a&gt;, so you can do just this.&lt;br /&gt;
&lt;br /&gt;
However, this means that there are 2 representations of code in the language.  Two.  ...And that doesn't seem right.&lt;br /&gt;
&lt;br /&gt;
After working with macros (I finally had the conceptual break-through of figuring out how to use double backquotes &amp;mdash; ick!), I realized, this makes sense.  The idea that code and data have the exact same concrete representation makes total sense.  So much so that I believe this is the right way to do it.&lt;br /&gt;
&lt;br /&gt;
But one question that comes to mind is, why does that one representation have to be prefix notation with parentheses everywhere?&lt;br /&gt;
&lt;br /&gt;
It's not clear whether being able to write data in the same form as the regular parsed grammar (infixes and all) would be a good thing or not.&lt;br /&gt;
&lt;br /&gt;
One thing I've since learned, but had trouble with when I first switched from ML to Scheme, was that in Scheme, the meaning of parentheses is overloaded.  In ML, parentheses are used for disambiguation of parsing, and that's all.  This is almost strictly so in OCaml.  But in Scheme, not only is it used for specifying the parse in lists and sub-lists in quoted expressions, but also for function application.  This confused the hell out of me for a little while, and my first inclination was to avoid using quote (i.e. &lt;code&gt;'&lt;/code&gt;) and use &lt;code&gt;list&lt;/code&gt; instead.  But I soon got over that.&lt;br /&gt;
&lt;br /&gt;
Overall, my experience learning Scheme has been extremely rewarding, as a great way to recognize patterns in something is to experience something completely different from it.  And many decisions that were made in designing ML, the opposite choices were taken for Scheme or Lisp.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-7150405946501801223?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/7150405946501801223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=7150405946501801223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7150405946501801223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/7150405946501801223'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/ml-scheme.html' title='ML &amp;rarr; Scheme'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1481168727203894751</id><published>2007-08-01T00:16:00.001-04:00</published><updated>2008-06-03T17:45:35.404-04:00</updated><title type='text'>Seeing ML Clearly</title><content type='html'>I went to school at Carnegie Mellon.  And there, the computer science department is big on research.  For system-level programming, they use C.  But for almost all theoretical or type related topics, they use ML.  In particular, Standard ML.&lt;br /&gt;
&lt;br /&gt;
So since I was really interested in compilers and type-theory, I became very familiar with ML.  First how to use it.  Then how to use it to make interpreters.  How compilers work.  And eventually, how to compile ML code.  A relative expert in ML.&lt;br /&gt;
&lt;br /&gt;
While at CMU, I was thoroughly trained in the benefits of strongly typed languages, the pitfalls of weakly typed languages, and why static typing can result in more efficient code than dynamic typing.  I was also introduced to the idea of typed intermediate languages &amp;mdash; that compilers have multiple phases which translate code to entirely different languages, each of which is strongly typed, getting closer and closer to the target language after each phase.  In other words SourceLang =&gt; IL1 =&gt; IL2 =&gt; ... =&gt; ILn =&gt; TargetLang.  And after I got the hang of it, I thought ML was great!  Oh, how I became to loath writing code in other languages.  Look!  Look how easy and beautiful the code would be in ML.&lt;br /&gt;
&lt;br /&gt;
But recently, for the first time, I've had a real reason to write some code in Scheme.  Scheme is similar to ML in that it's functional.  But it's dynamically typed.  Moreover, some flavors have "features" in them like dynamic scope that make it very difficult to look at a piece of code and determine whether it will compute gracefully or result in an error.  One of the biggest benefits of static typing is that it reveals errors in your programs as early as possible &amp;mdash; at compile time.  Dynamic typing on the other hand, reveals errors as late as possible.  If a branch of code is never taken, you'll never know whether that piece of code will fail, possibly until you ship your code and your users break it, losing millions (even lives) in the process.&lt;br /&gt;
&lt;br /&gt;
So all through school, I was on one side.  I was very very close with ML.  But now that I've been using Scheme (and also toying with &lt;a href="http://www.lambdassociates.org/FPQi.pdf"&gt;Qi [pdf]&lt;/a&gt;), I've been on the other side.  And now, for the first time ever, I can judge ML for what it truly is.  And here's what I've found.&lt;br /&gt;
&lt;br /&gt;
I still think ML's a great language.  Early bug detection and the invariants that are captured in types are so utterly essential to writing correct code that I can't believe it's still being done the other way.  I literally can't go writing more than a couple Scheme functions before I have to write down the types in comments, because otherwise, I have to try to hold all this stuff in my head.  It's not something that is in addition to writing the code; types are something I implicitly think about when I create code.  When I look at a piece of code, to see if it makes sense I type-check it in my head, in the same way that I execute it in my head when debugging for example.&lt;br /&gt;
&lt;br /&gt;
However, I've realized there are a few very powerful abstractions that are missing from ML (or lacking).&lt;ol&gt;&lt;li&gt;Macros&lt;/li&gt;&lt;li&gt;Reader Macros&lt;/li&gt;&lt;li&gt;Unrestricted Execution of Types&lt;/li&gt;&lt;/ol&gt;...Maybe I'll go into the details later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1481168727203894751?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1481168727203894751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1481168727203894751' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1481168727203894751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1481168727203894751'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/08/seeing-ml-clearly.html' title='Seeing ML Clearly'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-1861701236222982797</id><published>2007-07-28T15:48:00.002-04:00</published><updated>2008-06-03T17:46:48.584-04:00</updated><title type='text'>Fitting Inadequate Tools</title><content type='html'>As an after-thought to &lt;a href="http://plpatterns.blogspot.com/2007/07/programming-language-power.html"&gt;yesterday's post&lt;/a&gt;, I remembered Kyle (another person who prefers Emacs over Eclipse) showing me to double loop iterator variable names as in &lt;code&gt;ii&lt;/code&gt; instead of &lt;code&gt;i&lt;/code&gt; or &lt;code&gt;jj&lt;/code&gt; instead of &lt;code&gt;j&lt;/code&gt;.  This allows you to search for loop iterator variables without results coming up everywhere the letter "i" is used in your file.&lt;br /&gt;
&lt;br /&gt;
What he was basically suggesting was that I change the code I write in order to accommodate the inadequacies of a tool, namely, textual searching.&lt;br /&gt;
&lt;br /&gt;
This does not make sense to me at all.  If I had a tool that understood the scoping rules of my language (e.g. Eclipse editing Java), I could select a variable and the tool would show me all the references to that variable, regardless of its name.  Granted, this doesn't help if you're searching for all the loops that use the variable name, but (again, maybe this is just me) this is not something I ever do.  And if I needed to, a regex would handle that (or find whole word).&lt;br /&gt;
&lt;br /&gt;
Changing your work, no matter how slight, to fit your tools is an indicator that you need a better tool.  Because basically, you've found a pattern.  And whenever you find a pattern, you've found an opportunity for improvement.  Changing your work to fit your tools is equivalent to optimization.  You should only do it if you have to.  In other words, if it is a bottleneck.  And there's two ways to optimize for a bottleneck: from the top down, or from the bottom up.  Doing it from the top down means you must always think about it.  Doing it from the bottom up, abstracting the optimization away in a tool, means you don't have to think about it anymore.  It is equivalent to pushing a process down to a lower level in the hierarchy.  And the top level is the only level you have to think about.&lt;br /&gt;
&lt;br /&gt;
...This brings up an interesting question.  What is above me in the hierarchy? as it would be silly to think I was at the very top.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-1861701236222982797?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/1861701236222982797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=1861701236222982797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1861701236222982797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/1861701236222982797'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/07/fitting-inadequate-tools.html' title='Fitting Inadequate Tools'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-2641673137981561547</id><published>2007-07-27T23:46:00.003-04:00</published><updated>2008-06-03T17:46:35.615-04:00</updated><title type='text'>Tool Power and Why I Use Eclipse</title><content type='html'>I was talking with Kyle the other day about how with programming languages, when you look up at languages more powerful than the ones you know, all you see is what you already know and the supposedly more powerful languages seem not so great.  However, when you look down at less powerful languages, it's obvious that they are less powerful.  I'm not talking about computational power, as all Turing-complete languages can express all the same programs.  It's more about abstractions.  Paul Graham describes this more in depth calling it the &lt;a href="http://www.paulgraham.com/avg.html"&gt;Blub Paradox&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
That is all very well and interesting in itself.  But if you accept it, you must also accept its implications.  Namely, it makes sense to learn &lt;span style="font-style:italic;"&gt;and&lt;/span&gt; use more powerful languages.&lt;br /&gt;
&lt;br /&gt;
But it's not just about languages.  It's about tools.  Yesterday at work, I had a discussion with two co-workers about the differences between Emacs and &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; as IDEs.  Them both being advocates of Emacs, I figured I could get the lowdown on it from them since I only use it occasionally and am not an expert.  For writing Java (unfortunately, yes, I must do this at my current job), I prefer Eclipse.  But I'm open to using other more productive tools.  So I thought to myself, if Emacs is so great, maybe I can find out from one of these guys why, and then perhaps I'll switch.&lt;br /&gt;
&lt;br /&gt;
Basically, their argument came down to 2 things.  First of all, Emacs can be more easily extended than Eclipse which has a clumsy plugin system.  And secondly, only Emacs allows you to re-map the key bindings which is extremely helpful for writing code, which is where you spend the majority of your effort compared to other tasks you'd use an IDE for.&lt;br /&gt;
&lt;br /&gt;
However, there's one feature of Eclipse in particular (there are others too, but I'll not go into them) that Emacs does not have and neither of the guys I talked to knew of a standard extension out there that already does this.  It is the code refactoring features &amp;mdash; specifically, renaming variables, classes, and packages.&lt;br /&gt;
&lt;br /&gt;
I admit, any programmer is going to spend 10 times as much of his time on writing code.  Renaming things is a rare task comparatively.  However, when it must be done in Emacs or editors that don't support this, you must use regex replacing.  And this is both tedious and error-prone.  Textual find and replace will always be error-prone since it does not take into account scoping rules of the language.&lt;br /&gt;
&lt;br /&gt;
The fact that Eclipse allows you to do this correctly every time means that the cost of renaming drops to practically zero.  This means you no longer have to avoid it, which in this case means you no longer have to plan ahead to try to avoid it in the future.  But refactoring and renaming is inevitable.  In fact, the more often you refactor the better because it prevents code complexity and messiness from creeping in.  But say you wanted to try to think of the right name from the beginning to try to prevent having to refactor it later.  It is &lt;span style="font-style:italic;"&gt;impossible&lt;/span&gt; to know the correct name for a thing when you create it because code is fluid &amp;mdash; it never stops changing.  Requirements change, goals change, scope changes.  And so too must the code.  Moreover, as you design a solution to a problem, your understanding of the problem changes.  So even if the actual problem doesn't change, your understanding of how to most efficiently solve that problem will change.  Thus, refactoring including renaming is absolutely inevitable to keep the code as close as possible to the model in your mind.&lt;br /&gt;
&lt;br /&gt;
So why should I use an IDE that is oblivious to such things, forcing me to think about more things than I have to.  The details which are solely a result of code being expressed in text.&lt;br /&gt;
&lt;br /&gt;
It's true that such a feature could probably be made as an Emacs extension.  I do not doubt this at all.  But the fact that it is not already done means that like Lisp over C, or C over machine-code, Eclipse is more powerful than Emacs.  And this is &lt;span style="font-style:italic;"&gt;obvious&lt;/span&gt; looking down the power continuum.&lt;br /&gt;
&lt;br /&gt;
...And as for the whole key bindings thing, personally I almost never find my keystroke rate as the bottleneck.  Writing code is usually limited by my conceptual understanding and the translation of ideas into the language I'm writing in.  But maybe that's just me.&lt;br /&gt;
&lt;br /&gt;
So I don't think the guys I had this conversation with got this out of it, but because of this conversation, I realized that Eclipse is a more powerful tool than Emacs (for editing Java), and I don't plan on switching any time soon.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style:italic;"&gt;Post Post&lt;/span&gt;: Since writing this I've realized I've fallen into the same trap as others.  Namely, the trap of not seeing the power of something you don't understand.  I've done the exact same thing that users of less powerful tools and languages do when they look at something more powerful.  I've disregarded the importance of re-mapping key bindings w/o actually getting to know them.  It's possible this is a huge gain.  This doesn't change the fact that Eclipse is more powerful in other respects.  So it is really a value-judgment of mine that the cost of typing slowly is less than having to refactor things manually.  But I won't know for sure until I learn and use the more powerful features of Emacs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-2641673137981561547?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/2641673137981561547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=2641673137981561547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2641673137981561547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/2641673137981561547'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2007/07/tool-power-and-why-i-use-eclipse.html' title='Tool Power and Why I Use Eclipse'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-3446586008346702764</id><published>2006-12-19T22:02:00.002-05:00</published><updated>2008-06-03T17:46:27.832-04:00</updated><title type='text'>Patterns Make Things Simple</title><content type='html'>The other day I was thinking about a conversation I had about the way relationships can (and do) get so complicated.  But back in school, life was simple.  You go to school, come home, do your hw, and pretty much have fun the rest of the time.&lt;br /&gt;
&lt;br /&gt;
Of course back then it didn't seem simple.  It felt really complicated.  But that's the way it always is.&lt;br /&gt;
&lt;br /&gt;
Seeing the pattern makes things simple.&lt;br /&gt;
&lt;br /&gt;
That's exactly how it is in programming and it applies to life.  When you're writing a big program, you write, you write, it's complicated, complicated.  ...But after a while, you start to realize, I've written something just like this before.  You go back and find the other code you wrote, and sure enough, it's the same thing except for some details.  Details that can be abstracted over &amp;mdash; creating a function or a template that can be applied in specific instances, depending on the details of the situation.&lt;br /&gt;
&lt;br /&gt;
That, by the way, is the reason why people who learn (and really get) a functional language like Lisp or ML are so die-hard about it.  Languages like that let you abstract over pretty much anything.&lt;br /&gt;
&lt;br /&gt;
But you have to see the pattern first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-3446586008346702764?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/3446586008346702764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=3446586008346702764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3446586008346702764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/3446586008346702764'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2006/12/patterns-make-things-simple.html' title='Patterns Make Things Simple'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-65083961482497982.post-736141789523269498</id><published>2006-12-17T22:04:00.004-05:00</published><updated>2008-06-03T17:46:19.441-04:00</updated><title type='text'>Side-Stepping Obstacles in Space and Time</title><content type='html'>You can almost always by-pass an obstacle by side-stepping in another dimension.&lt;br /&gt;
&lt;br /&gt;
It's like a lab rat in a maze trying to reach the cheese.  The walls of the maze are between it and its goal the cheese.  But if the rat were able to move vertically above the maze walls, it would be able to move forward towards the cheese freely.&lt;br /&gt;
&lt;br /&gt;
It's a very simple concept.  You're walking.  There's something in front of you.  You go around it.&lt;br /&gt;
&lt;br /&gt;
But what are you doing? if you abstract away all the details.  What you're left with is an amazingly powerful problem-solving method.  If movement towards your goal is blocked, move in another dimension.  This will allow free movement in the previously blocked dimension.&lt;br /&gt;
&lt;br /&gt;
I originally thought of this when I was thinking about time.  If we're moving across time as if it were another dimension of space, you can use this method of side-stepping into another dimension to break barriers in time.  (Or more accurately, go around them.)&lt;br /&gt;
&lt;br /&gt;
Oh, I think what triggered it was I was trying to remember a dream I had.  So I was thinking about how being in the same place &amp;mdash; the same environment and position &amp;mdash; makes thoughts come back to you.  It's as if the thoughts are emanating there, and your body is an antenna, that if positioned in a certain way, will pick up certain thoughts; reposition the antenna, and you pick up on another channel.&lt;br /&gt;
&lt;br /&gt;
So I thought, maybe it's like that with time too.  In other words, what time it is also determines what thoughts are emanating.  So if you're closer in time, you're more likely to have the same thoughts.  And that makes sense, because you are more likely to think about the same thing temporally close together.  (Reminds me of temporal and spatial locality which are exploited for caching.)&lt;br /&gt;
&lt;br /&gt;
One block you often run in to in the time dimension is forgetting.  You don't remember something that you intentionally mean to.  In this case you can side-step the block into another dimension &amp;mdash; a spatial dimension.  You create something like a reminder note that persists in space, moving forward in time freely.  It makes perfect sense.  ...I wonder how else this can be applied.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/65083961482497982-736141789523269498?l=plpatterns.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plpatterns.blogspot.com/feeds/736141789523269498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=65083961482497982&amp;postID=736141789523269498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/736141789523269498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/65083961482497982/posts/default/736141789523269498'/><link rel='alternate' type='text/html' href='http://plpatterns.blogspot.com/2006/12/side-stepping-obstacles-in-space-and.html' title='Side-Stepping Obstacles in Space and Time'/><author><name>Jon T</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
