<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>i’m a dude
twitter
github
facebook
aim: alandipert
alan.dipert@gmail
resume
work: nuklei
friends
Ashley
Julio
</description><title>alan dipert</title><generator>Tumblr (3.0; @alandipert)</generator><link>http://alan.dipert.org/</link><item><title>The Most Officialest SkiFree Home Page!</title><description>&lt;a href="http://ski.ihoc.net/"&gt;The Most Officialest SkiFree Home Page!&lt;/a&gt;: &lt;p&gt;&lt;img height="549" src="http://ski.ihoc.net/ski.gif" width="537"/&gt;&lt;/p&gt;
&lt;p&gt;The history and implementation of SkiFree.&lt;/p&gt;</description><link>http://alan.dipert.org/post/21717635998</link><guid>http://alan.dipert.org/post/21717635998</guid><pubDate>Tue, 24 Apr 2012 08:43:00 -0700</pubDate></item><item><title>A Sigh of Datomic</title><description>&lt;p&gt;Over a year ago I had the great pleasure of working with the &lt;a href="http://datomic.com/"&gt;Datomic&lt;/a&gt; team through my wonderful employer, &lt;a href="http://thinkrelevance.com/"&gt;Relevance&lt;/a&gt;, while the project was still secret.  Datomic, which was &lt;a href="http://datomic.com/news/datomic_early_experience"&gt;released on Monday&lt;/a&gt;, is a new kind of database with a unique and powerful set of properties.&lt;/p&gt;
&lt;p&gt;I believe Datomic makes new kinds of applications possible and old kinds of applications easier, and I encourage you to &lt;a href="http://datomic.com/product/early_experience"&gt;try it out&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My experience working on and around Datomic was incredibly formative technically and professionally.  The only downside has been the agony of waiting to talk with people about it and to apply it to public projects and products.  I&amp;#8217;m excited and relieved that Datomic is now in the open.&lt;/p&gt;
&lt;p&gt;As a technical influence, Datomic solidified a perspective on computing that I was first exposed to through &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, also designed by Rich Hickey.  I have found this perspective - which might be loosely characterized as emphasizing simplicity, immutability, and the importance of data - a powerful tool by itself, irrespective of either Clojure or Datomic.  It is this perspective that Rich elaborates on in his &lt;a href="https://thestrangeloop.com/"&gt;Strange Loop&lt;/a&gt; 2011 keynote, &lt;a href="http://www.infoq.com/presentations/Simple-Made-Easy"&gt;Simple Made Easy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Simplicity, immutability, and data are powerful ideas to think about software in terms of, whether you are creating something new or assessing something that already exists.&lt;/p&gt;
&lt;p&gt;As a software consultant at Relevance, I divide my time between creating solutions and choosing existing solutions in order to solve problems.  Combined with deliberate thought, research, and discussion with colleagues and clients, these ideas have helped me do both things better, to the extent that it sometimes feels like cheating.&lt;/p&gt;
&lt;p&gt;Professionally, my involvement with the Datomic team taught me many things, the most influential of which was perhaps the importance of questions to problem solving.&lt;/p&gt;
&lt;p&gt;I work in a totally intangible world of software, trade-offs, conceptions, and domains that has technical, social, and financial dimensions.  This world disappears when I try to imagine it all at once, which is my first instinct when I try to solve a problem within it.&lt;/p&gt;
&lt;p&gt;Specific questions and their answers are a tool for considering this intangible world one piece at a time in the context of a particular problem.  If you ask and answer enough of them for yourself, you can build a practical mental model of the intangible.  This model allows you to make sensible decisions and form grounded opinions.  Questions are a big piece of the problem solving approach Rich discusses in his &lt;a href="http://blip.tv/clojure/hammock-driven-development-4475586"&gt;&amp;#8220;Hammock-driven development&amp;#8221; keynote&lt;/a&gt; at &lt;a href="http://clojure-conj.org/"&gt;Clojure Conj&lt;/a&gt; 2010.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s not always easy to ask questions, especially if you know it will be hard to find the answer, or if the answer might be unfavorable.  But, unless you value your ego over your ability to solve problems, you should never hesitate.&lt;/p&gt;
&lt;p&gt;Rich Hickey, Stu Halloway, Justin Gehtland, and the rest of the Datomic team did not hesitate, and now the world has a new database of singular vision and capability.&lt;/p&gt;</description><link>http://alan.dipert.org/post/18947900609</link><guid>http://alan.dipert.org/post/18947900609</guid><pubDate>Thu, 08 Mar 2012 06:25:20 -0800</pubDate></item><item><title>Structural Editing Redux</title><description>&lt;p&gt;I gave a quick lightning talk at the most recent &lt;a href="http://www.meetup.com/TriClojure/"&gt;TriClojure&lt;/a&gt; about structure editing.  Structural editing is an idea I can&amp;#8217;t seem to shake, and my efforts to wrap my head around its implications continue.&lt;/p&gt;
&lt;p&gt;After the meeting, I followed up with a few interested parties about my discoveries, and thought to post them here for the benefit of the wider Internets:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The &lt;a href="http://web.archive.org/web/20100919114103/http://bywicket.com/users/mikel/weblog/126a4/Bard.html"&gt;blog post that originally got me thinking&lt;/a&gt; caused me to write &lt;/span&gt;&lt;span&gt;&lt;a href="http://alan.dipert.org/post/445462664/the-s-expression-editor"&gt;my own blog post&lt;/a&gt;, and a little while later I &lt;a href="https://gist.github.com/1167234"&gt;published a gist&lt;/a&gt; of a simple structural editor for Clojure using zippers.&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span&gt;The code in the gist has a lot of bugs.  In particular, the zipper function I&amp;#8217;m &lt;/span&gt;&lt;span&gt;using doesn&amp;#8217;t handle vectors or hash maps gracefully.  I&amp;#8217;ve thought &lt;/span&gt;&lt;span&gt;about tightening the REPL loop so that every key press instantly &lt;/span&gt;&lt;span&gt;triggers zipper movement.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The whole structure editor thing has also &lt;/span&gt;&lt;span&gt;turned me on to the idea of touch/tablet IDE for Lisps - form bubbles &lt;/span&gt;&lt;span&gt;that can be nested, similar to the &lt;a href="http://fidelvanegas.net/wordpress/wp-content/uploads/2010/05/Screenshot-ScratchPongGame1.png"&gt;Scratch project&lt;/a&gt; (but data).  I &lt;/span&gt;&lt;span&gt;think this might ultimately be a better way to represent structure and sequence &lt;/span&gt;&lt;span&gt;than characters and parentheses.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Once I found out about &lt;a href="http://larry.masinter.net/interlisp-ieee.pdf"&gt;Interlisp&lt;/a&gt; (pdf), I went nuts, but information and &lt;/span&gt;&lt;span&gt;screenshots are hard to come by.  Rich Hickey told me once that there is a video &lt;/span&gt;&lt;span&gt;floating around somewhere of the Interlisp-D UI in action, but I&amp;#8217;ve &lt;/span&gt;&lt;span&gt;never been able to find it.&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span&gt;I&amp;#8217;ve investigated what it would take for a real-time structure editor, &lt;/span&gt;&lt;span&gt;and I think it&amp;#8217;s a very hard problem.  Synchronizing data structures &lt;/span&gt;&lt;span&gt;with their pretty-printed representation on a character display is no &lt;/span&gt;&lt;span&gt;small feat.  Bernard Greenberg (pictured below) documents some approaches in his &lt;/span&gt;&lt;span&gt;&lt;a href="http://www.multicians.org/mepap.html"&gt;history of the implementation of Emacs&lt;/a&gt;.&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span&gt;More recently, &lt;a href="http://blog.fogus.me/"&gt;Michael Fogus&lt;/a&gt; pointed me at &lt;a href="http://www.youtube.com/watch?v=HB6HvhOw_MY"&gt;Nokolisp&lt;/a&gt;, an old Lisp &lt;/span&gt;&lt;span&gt;for DOS that features an interesting-looking structure editor, among &lt;/span&gt;&lt;span&gt;other features (like &amp;#8220;uncompiling&amp;#8221; functions!)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;My current thinking on the implications of a structural editor goes beyond convenience of representation and into the idea of programs constructed by query.  I imagine a world where code is stored and shared structurally instead of with text.  Programming with available libraries then becomes querying instead of explicitly programming.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As the programmer types, their editor might search these libraries in real-time and do things like suggest improvements using probability heuristics, or suggest substitution of their code with available library code that is a structural match.  This is an extension into a networked world of some of the ideas built into Interlisp.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Code as truly data also abolishes the need for git or other text-based source revision tools, as source would be stored at the granularity of expression - not the character or line.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img alt="Bernard Greenberg teaching Lisp" height="653" src="http://tailrecursion.com/~alan/pix/bsg-lisp-big.jpg" width="504"/&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/17375691572</link><guid>http://alan.dipert.org/post/17375691572</guid><pubDate>Fri, 10 Feb 2012 08:48:00 -0800</pubDate></item><item><title>"Bass was used very infrequently until their later songs, and live shows often saw Remmler playing..."</title><description>“Bass was used very infrequently until their later songs, and live shows often saw Remmler playing some simple preprogrammed rhythms and melodies on his small Casio VL-1 keyboard while Behrens played his drums single-handedly while eating an apple.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Trio_(band)"&gt;Wikipedia - Trio (Band)&lt;/a&gt;&lt;/em&gt;</description><link>http://alan.dipert.org/post/8200952788</link><guid>http://alan.dipert.org/post/8200952788</guid><pubDate>Thu, 28 Jul 2011 20:44:44 -0700</pubDate></item><item><title>Discover Lisp in Your Web Browser with Javascript</title><description>&lt;p&gt;&lt;em&gt;This post is &lt;a href="http://tailrecursion.com/~alan/writing/discover-lisp-in-your-browser.pdf"&gt;available as a PDF&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Many ideas introduced originally in Lisp, such as conditional execution (the &lt;code&gt;if-then-else&lt;/code&gt; construct), garbage collection, and first-class functions&lt;sup&gt;&lt;a id="fnref1" href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;, can be found in modern non-Lisp programming languages.&lt;/p&gt;
&lt;p&gt;Other ideas pioneered by Lisp, like the idea that programs can be composed solely of &lt;em&gt;expressions&lt;/em&gt;, and &lt;em&gt;homoiconicity&lt;/em&gt;, or the idea that a program can be written in its own data structures, are rarer.&lt;/p&gt;
&lt;p&gt;Learning a Lisp dialect, whether it&amp;#8217;s Clojure, Scheme, or Common Lisp, is a great way to see for yourself how powerful all of these ideas can be when combined.&lt;/p&gt;
&lt;p&gt;An even better way to understand the ideas is to implement your own Lisp&lt;sup&gt;&lt;a id="fnref2" href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;&lt;a id="fnref3" href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;After we explore some fundamental concepts, we&amp;#8217;ll look at how a language like Javascript works.&lt;/p&gt;
&lt;p&gt;Then, we&amp;#8217;ll build our own small Lisp to Javascript compiler on top of Javascript in about 32 lines of Javascript code.&lt;/p&gt;
&lt;h2 id="expression-vs.-statement"&gt;Expression vs. Statement&lt;/h2&gt;
&lt;p&gt;Programs in languages like Javascript are composed of two things:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;statements&lt;/li&gt;
&lt;li&gt;expressions&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Lisp programs are composed only of expressions.&lt;/p&gt;
&lt;p&gt;Both statements and expressions are, in some sense, instructions for the computer to do some piece of work. The difference between them is that a statement does not return a value, but an expression does.&lt;/p&gt;
&lt;p&gt;Consider Javascript&amp;#8217;s &lt;code&gt;if-then-else&lt;/code&gt; statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (x &amp;gt; 10) {
  alert("x was bigger than 10!");
} else {
  alert("x was not bigger than 10!")
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We call &lt;code&gt;alert&lt;/code&gt; inside both the &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt; bodies of the expression because &lt;code&gt;if&lt;/code&gt; does not return a value. If it did, we could pass it directly to a single &lt;code&gt;alert&lt;/code&gt; call, as this wishful pseudo-Javascript demonstrates:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alert(if (x &amp;gt; 10) {
  return "x was bigger than 10!"
} else {
  return "x was not bigger than 10!"
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we eliminate statements from our wishful pseudo-Javascript entirely, there&amp;#8217;s no longer a need for the &lt;code&gt;return&lt;/code&gt; operator. It&amp;#8217;s assumed that values &amp;#8220;return&amp;#8221; themselves:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alert(if (x &amp;gt; 10) {
   "x was bigger than 10!"
} else {
   "x was not bigger than 10!"
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Javascript actually provides an &lt;code&gt;if-then-else&lt;/code&gt; construct that returns a value, the &lt;em&gt;ternary operator&lt;/em&gt;&lt;sup&gt;&lt;a id="fnref4" href="#fn4"&gt;4&lt;/a&gt;&lt;/sup&gt;, but it is seldom used and often discouraged&lt;sup&gt;&lt;a id="fnref5" href="#fn5"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;With expressions, it&amp;#8217;s possible to write code in the &lt;em&gt;imperative style&lt;/em&gt; the first example demonstrated. The opposite, writing expressions in terms of statements, is not.&lt;/p&gt;
&lt;p&gt;If we agree that &amp;#8220;power&amp;#8221; means &amp;#8220;possibility&amp;#8221;, then languages like Lisp, which are based on expressions instead of statements, might be considered powerful.&lt;/p&gt;
&lt;h2 id="homoiconicity"&gt;Homoiconicity&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Homoiconicity&lt;/em&gt; is a property of a programming language&amp;#8217;s syntax, and means that programs in a language are expressed using that language&amp;#8217;s own data structures. The property of homoiconicity is key to the way Lisp empowers the programmer to fabricate and manipulate syntax.&lt;/p&gt;
&lt;p&gt;Homoiconicity might be understood by exploring the properties of source code and interpretation of that source code in a non-homoiconic language first.&lt;/p&gt;
&lt;p&gt;Javascript, while influenced by Lisp in other ways&lt;sup&gt;&lt;a id="fnref6" href="#fn6"&gt;6&lt;/a&gt;&lt;/sup&gt;, is not homoiconic, and its popularity, availability, and conventional syntax make it a candidate for exploration.&lt;/p&gt;
&lt;h2 id="implementing-javascript"&gt;Implementing Javascript&lt;/h2&gt;
&lt;h3 id="how-a-javascript-interpreter-works"&gt;How a Javascript Interpreter Works&lt;/h3&gt;
&lt;p&gt;Consider this fragment of Javascript code, which passes the sum of 1 and the product of 2 and 3 to a web browser&amp;#8217;s &lt;code&gt;alert&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alert(1 + 2 * 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a browser passes this code, or data, as a string to its Javascript interpreter, something like the following happens:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The interpreter &lt;em&gt;lexically analyzes&lt;/em&gt;&lt;sup&gt;&lt;a id="fnref7" href="#fn7"&gt;7&lt;/a&gt;&lt;/sup&gt; the string, turning it into a stream of &lt;em&gt;tokens&lt;/em&gt;. Tokens are objects in source code upon which other constructs are defined, such as function names, operators, and literals like numbers or strings. The tokens in the above fragment might be:
&lt;ul&gt;&lt;li&gt;&lt;code&gt;alert&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;1&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;2&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;3&lt;/li&gt;
&lt;li&gt;&lt;code&gt;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;The interpreter &lt;em&gt;parses&lt;/em&gt; the token stream, attempting, recursively, to match the pattern of tokens to known language constructs. For instance, when the interpreter sees the function name &lt;code&gt;alert&lt;/code&gt; followed by &lt;code&gt;(&lt;/code&gt;, it knows to expect zero or more tokens that must be succeeded by a closing &lt;code&gt;)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The interpreter &lt;em&gt;evaluates&lt;/em&gt; the constructs it found from the inside out:
&lt;ul&gt;&lt;li&gt;&lt;code&gt;2 * 3&lt;/code&gt; happens first, because, &lt;code&gt;*&lt;/code&gt; has higher precedence than &lt;code&gt;+&lt;/code&gt; and because the interpreter knows it needs a value or identifier to pass to &lt;code&gt;alert&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The product, 6, is returned.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 + 6&lt;/code&gt; is evaluated, returning 7.&lt;/li&gt;
&lt;li&gt;Finally, &lt;code&gt;alert(7)&lt;/code&gt; is evaluated, and a message is displayed.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If you were to write your own Javascript interpreter or compiler, you would need to implement a &lt;code&gt;lexical analyzer&lt;/code&gt;, a &lt;code&gt;parser&lt;/code&gt;, and an &lt;code&gt;evaluator&lt;/code&gt; in order to complete the above steps.&lt;/p&gt;
&lt;p&gt;Even if you were to implement your interpreter in Javascript, you&amp;#8217;d have a long way to go, because none of these functions are provided by Javascript interpreters to Javascript programmers.&lt;/p&gt;
&lt;p&gt;Javascript provides the &lt;code&gt;eval&lt;/code&gt; function, but it accepts only strings, and you need to create source code strings yourself. Creating source code strings to pass to &lt;code&gt;eval&lt;/code&gt; is effectively compilation, and done correctly could be as difficult as writing a compiler.&lt;/p&gt;
&lt;p&gt;The task is not as daunting if we take the Lisp approach and build our programs in a data format richer than strings. Let&amp;#8217;s meet the problem half way, and invent a Javascript syntax based on Javascript data.&lt;/p&gt;
&lt;h2 id="a-homoiconic-javascript-subset-jsonscript"&gt;A Homoiconic Javascript Subset: JSONScript&lt;/h2&gt;
&lt;h3 id="s-expressions"&gt;S-expressions&lt;/h3&gt;
&lt;p&gt;Consider this alternative representation of the code fragment, in a language we just invented, JSONScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;['alert', ['+', 1, ['*', 2, 3]]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unlike the earlier example, which was a string that required multiple phases of analysis to understand and run, the above code is written using data structures native to Javascript: string, number, and array.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;JSON&lt;/em&gt;, which stands for &amp;#8220;Javascript Object Notation&amp;#8221;, is a notation for expressing data in terms of Javascript data structures. JSON is expressive enough for us to use it to represent code for a simple programming language.&lt;/p&gt;
&lt;p&gt;We could easily write a function called &lt;code&gt;compile_jsonjs&lt;/code&gt; that converted this representation into a string that could be passed to &lt;code&gt;eval&lt;/code&gt;, because:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;We don&amp;#8217;t need to write a lexical analyzer or parser: our code is already rich enough to express how it should be evaluated.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compile_jsonjs&lt;/code&gt; doesn&amp;#8217;t need to know about operator precedence because we&amp;#8217;re using &lt;em&gt;s-expressions&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;S-expressions, short for &amp;#8220;symbolic expressions&amp;#8221;, are a convention for writing code that allows us to represent a function call with an array. This convention is also known as &lt;em&gt;prefix notation&lt;/em&gt;. The first element of the array is the function, and subsequent elements are arguments to that function that are evaluated first.&lt;/p&gt;
&lt;p&gt;S-expressions leave no ambiguity about the order in which functions must be applied. In the original example, the expression &lt;code&gt;1 + 2 * 3&lt;/code&gt; evaluated to 7 because it&amp;#8217;s in the Javascript specificaton that &lt;code&gt;*&lt;/code&gt; must evaluate before &lt;code&gt;+&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In JSONScript, we express our intent to multiply first by making &lt;code&gt;['*', 2, 3]&lt;/code&gt; an argument to &lt;code&gt;+&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;S-expressions don&amp;#8217;t have to be arrays. &lt;code&gt;42&lt;/code&gt; and &lt;code&gt;"hamster dance"&lt;/code&gt; are also s-expressions, because they also evaluate, but to themselves.&lt;/p&gt;
&lt;p&gt;Lisp uses lists instead of arrays as s-expressions, but the idea is the same.&lt;/p&gt;
&lt;h3 id="some-implementation-details"&gt;Some Implementation Details&lt;/h3&gt;
&lt;p&gt;There are at least two implementation details we face in implementing &lt;code&gt;compile_jsonjs&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;In JSONScript, as in Lisp, there is no distinction between function and operator. Functions, whether they are &lt;code&gt;alert&lt;/code&gt; or &lt;code&gt;*&lt;/code&gt;, must only appear as a string and as the first element of an array.
&lt;ul&gt;&lt;li&gt;&lt;code&gt;compile_jsonjs&lt;/code&gt; needs to recognize functions that Javascript considers to be operators, and return the correct syntax for them.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;In Javascript, functions are identified by symbols, not strings. For instance, this syntax is not correct: &lt;code&gt;'alert'(7)&lt;/code&gt;.
&lt;ul&gt;&lt;li&gt;&lt;code&gt;compile_jsonjs&lt;/code&gt; must return function names as symbols.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conflating symbol and string is necessary but has unfortunate implications. For instance, it will be impossible to pass a function name as an argument to a function in JSONScript.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Adding the ability to pass function names as arguments equires us to go beyond JSON as our source data format, because JSON permits symbol literals only as an object field names.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3 id="building-the-compiler"&gt;Building the Compiler&lt;/h3&gt;
&lt;p&gt;We&amp;#8217;re now equipped to reason about how &lt;code&gt;compile_jsonjs&lt;/code&gt; will work.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;First, we check if the input is an array.&lt;/li&gt;
&lt;li&gt;If it is an array, we:
&lt;ul&gt;&lt;li&gt;Compile the arguments&lt;/li&gt;
&lt;li&gt;Check if the first element is an operator like &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt;
&lt;ul&gt;&lt;li&gt;If it is an operator, interpose the compiled arguments with the operator, and concatenate everything into a single string. &lt;code&gt;compile_jsonjs(['+', 1, 2])&lt;/code&gt; should return &lt;code&gt;"1+2"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If it&amp;#8217;s not an operator, like &lt;code&gt;alert&lt;/code&gt;, we return a function call. &lt;code&gt;compile_jsonjs(['alert', 'hello'])&lt;/code&gt; should return &lt;code&gt;"alert('hello')"&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;If it isn&amp;#8217;t an array, we return it as a string. &lt;code&gt;compile_jsonjs(42)&lt;/code&gt; should return &lt;code&gt;"42"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;h3 id="the-implementation"&gt;The Implementation&lt;/h3&gt;
&lt;p&gt;Next, we can translate our plan into code. We know that &lt;code&gt;compile_jsonjs&lt;/code&gt; will need helper functions for:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Testing if an object is an array: This is how we&amp;#8217;ll determine at the beginning of &lt;code&gt;compile_jsonjs&lt;/code&gt; whether we&amp;#8217;re compiling a function call or a &lt;em&gt;literal&lt;/em&gt;. Literals are data that evaluate to themselves, like numbers or strings.&lt;/li&gt;
&lt;li&gt;Testing if an array contains a particular object: We&amp;#8217;ll need to make a list of functions that are Javascript operators, because we must emit different Javascript syntax for them.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The first helper function we need, &lt;code&gt;isArray()&lt;/code&gt;, isn&amp;#8217;t available on some browsers, and is actually difficult to write in a widely compatible way.&lt;/p&gt;
&lt;p&gt;So, we can borrow it from the &lt;code&gt;underscore.js&lt;/code&gt;&lt;sup&gt;&lt;a id="fnref8" href="#fn8"&gt;8&lt;/a&gt;&lt;/sup&gt; library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var isArray = function (obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need a function for testing if an object is in an array. Such a function is also not available in some browsers, but we can implement it like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var inArray = function(array, item) {
  for(var i = 0; i &amp;lt; array.length; i++)
    if (array[i] === item) return true;
  return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With these functions in place, we can finally write our compiler:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var compile_jsonjs = function(expression) {

  var operators = ['*', '+'];

  if (isArray(expression)) {

    var func_name = expression[0];
    var func_args = expression.slice(1);

    var compiled_args = [];
    for (var i = 0; i &amp;lt; func_args.length; i++)
      compiled_args.push(compile_jsonjs(func_args[i]));

    if(inArray(operators, func_name)) {
      return compiled_args.join(func_name);
    } else {
      return func_name + "(" + compiled_args.join(',') + ")";
    }

  } else {
    return expression.toString()
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The full source listing, which you can copy and paste into a web browser&amp;#8217;s Javascript console, follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var isArray = function (obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}

var inArray = function(array, item) {
  for(var i = 0; i &amp;lt; array.length; i++)
    if (array[i] === item) return true;
  return false;
}

var compile_jsonjs = function(expression) {

  var operators = ['*', '+'];

  if (isArray(expression)) {

    var func_name = expression[0];
    var func_args = expression.slice(1);

    var compiled_args = [];
    for (var i = 0; i &amp;lt; func_args.length; i++)
      compiled_args.push(compile_jsonjs(func_args[i]));

    if(inArray(operators, func_name)) {
      return compiled_args.join(func_name);
    } else {
      return func_name + "(" + compiled_args.join(',') + ")";
    }

  } else {
    return expression.toString()
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="trying-it-out"&gt;Trying it Out&lt;/h3&gt;
&lt;p&gt;We can test our compiler by seeing what code it generates with our JSONScript fragment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compile_jsonjs(['alert', ['+', 1, ['*', 2, 3]]]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we can evaluate our compiled code by passing that result to &lt;code&gt;eval&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eval(compile_jsonjs(['alert', ['+', 1, ['*', 2, 3]]]));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="going-further"&gt;Going Further&lt;/h2&gt;
&lt;p&gt;JSONScript probably isn&amp;#8217;t a language you would want to use for your next programming project, but hopefully you now have a better understanding of what Lisp is and why it is different.&lt;/p&gt;
&lt;p&gt;Further extending JSONScript will help you understand Lisp even more.&lt;/p&gt;
&lt;p&gt;You can begin by adding support for other Javascript operators.&lt;/p&gt;
&lt;p&gt;Next, you might implement &lt;code&gt;lambda&lt;/code&gt; and &lt;code&gt;quote&lt;/code&gt;. These will allow you to define functions in JSONScript, and to pass arrays to functions without evaluating them.&lt;/p&gt;
&lt;p&gt;Once you have &lt;code&gt;lambda&lt;/code&gt; and &lt;code&gt;quote&lt;/code&gt;, you can implement other &lt;em&gt;special forms&lt;/em&gt;, using Paul Graham&amp;#8217;s &lt;em&gt;The Roots of Lisp&lt;/em&gt; as a guide&lt;sup&gt;&lt;a id="fnref9" href="#fn9"&gt;9&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re feeling particularly ambitious, you might consider adding support for one of Lisp&amp;#8217;s most famous and unique features - &lt;em&gt;macros&lt;/em&gt;, or functions that:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;are run before evaluation&lt;/li&gt;
&lt;li&gt;do not evaluate their arguments&lt;/li&gt;
&lt;li&gt;return JSONScript code&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;ol&gt;&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="http://www.paulgraham.com/diff.html"&gt;What Made Lisp Different&lt;/a&gt; by Paul Graham &lt;a title="Jump back to footnote 1" href="#fnref1"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="http://www.paulgraham.com/rootsoflisp.html"&gt;The Roots of Lisp&lt;/a&gt; by Paul Graham &lt;a title="Jump back to footnote 2" href="#fnref2"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="http://pagesperso-systeme.lip6.fr/Christian.Queinnec/WWW/LiSP.html"&gt;Lisp in Small Pieces&lt;/a&gt; &lt;a title="Jump back to footnote 3" href="#fnref3"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Ternary_operation#C.2C_C.2B.2B.2C_C.23.2C_Vala.2C_Objective-C.2C_Java.2C_JavaScript.2C_ActionScript"&gt;Wikipedia: Ternary operation (Javascript)&lt;/a&gt; &lt;a title="Jump back to footnote 4" href="#fnref4"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="http://docs.jquery.com/JQuery_Core_Style_Guidelines#Blocks"&gt;jQuery Core Style Guide: Blocks&lt;/a&gt; &lt;a title="Jump back to footnote 5" href="#fnref5"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html"&gt;Popularity&lt;/a&gt; by Brendan Eich &lt;a title="Jump back to footnote 6" href="#fnref6"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn7"&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Lexical_analysis"&gt;Wikipedia: Lexical analysis&lt;/a&gt; &lt;a title="Jump back to footnote 7" href="#fnref7"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn8"&gt;
&lt;p&gt;&lt;a href="https://github.com/documentcloud/underscore/blob/96dbdaf9295f5598b631411d1553b04b43594152/underscore.js#L641"&gt;_.isArray in underscore.js&lt;/a&gt; &lt;a title="Jump back to footnote 8" href="#fnref8"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="http://www.paulgraham.com/rootsoflisp.html"&gt;The Roots of Lisp&lt;/a&gt; by Paul Graham &lt;a title="Jump back to footnote 9" href="#fnref9"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description><link>http://alan.dipert.org/post/7193534410</link><guid>http://alan.dipert.org/post/7193534410</guid><pubDate>Sun, 03 Jul 2011 08:59:00 -0700</pubDate></item><item><title>"Choking hazard! This is an expensive puzzle cut to exacting tolerances. Children leaving teeth marks..."</title><description>“Choking hazard! This is an expensive puzzle cut to exacting tolerances. Children leaving teeth marks on the pieces are apt to be choked.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://gosper.org/"&gt;Bill Gosper&lt;/a&gt;&lt;/em&gt;</description><link>http://alan.dipert.org/post/3286197215</link><guid>http://alan.dipert.org/post/3286197215</guid><pubDate>Sun, 13 Feb 2011 19:58:34 -0800</pubDate></item><item><title>“It has the singularity of outsider art, though the...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lcbfuoN91j1qzqgjfo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;span&gt;“It has the singularity of outsider art, though the conscious rejection of spatial dynamics could only come from an intimacy with the conventions of picture-making.”&lt;/span&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/1654274791</link><guid>http://alan.dipert.org/post/1654274791</guid><pubDate>Mon, 22 Nov 2010 18:20:48 -0800</pubDate></item><item><title>An XML Rant</title><description>&lt;p&gt;&lt;em&gt;This rant is brought to you by my reaction to Daniel Lemire&amp;#8217;s post, &lt;a href="http://lemire.me/blog/archives/2010/11/17/you-probably-misunderstand-xml/"&gt;&amp;#8220;You probably misunderstand XML&amp;#8221;&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In school I took a class called &amp;#8220;Data Interchange&amp;#8221; or something, that taught primarily XML and the ecosystem around it.  We learned about XSD, RELAX NG, XSLT, XPath, JAXB, SOAP, and lots of other things I thought to be loads of horrendous bullshit at the time.  I hated that class.&lt;/p&gt;
&lt;p&gt;I made a special effort to go, though.  I was on a personal mission to point out every counterexample to, failing of, and argument against XML that I could.  &amp;#8221;It&amp;#8217;s the illegitimate half-brother of the holiest representation of all time, the S-expression, and it&amp;#8217;s slower than shit to boot!&amp;#8221; I cried.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve learned a lot since then.  The biggest thing I&amp;#8217;ve learned is that it&amp;#8217;s easy to dismiss any technology with cultural baggage on religious terms.  It&amp;#8217;s also easy to conflate your hatred of some technology, like SOAP, with some other technology, like XML, that is only loosely or incidentally related.  Without assessing pragmatically to yourself whether SOAP sucks because it uses XML, or SOAP just plain sucks, you have not adequately justified your hatred.&lt;/p&gt;
&lt;p&gt;The more you work without asking yourself these questions, the more likely you are to commit the cardinal sin of anyone in the computing profession who gives a shit about what they do - use the wrong tool for the job.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s much harder, and much more useful, is to take a pragmatic approach to determining a technology&amp;#8217;s deficiencies and capabilities.  I still don&amp;#8217;t do this enough.  This was one of the themes of Rich Hickey&amp;#8217;s &amp;#8220;Hammock Time&amp;#8221; talk at &lt;a href="http://clojure-conj.org/"&gt;the first Clojure Conj&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But it&amp;#8217;s not what led me to later realize the legitimate use cases for XML.  I digress.&lt;/p&gt;
&lt;p&gt;What I later realized about XML as I programmed more is that the intrinsic structure, semi-structure, or non-structure of the data you are working with is only part of the question, and only leads you to a conclusion - well, opinion, mostly - on how to best represent it.  The more complicated the domain, the more complicated your opinion, and the hairier the ultimate representation.&lt;/p&gt;
&lt;p&gt;As you bang out your implementation, the less intuitive but really insidious part of the question lurks: &amp;#8220;Will people in the future working with this thing I created be able to use it and modify it for their own needs?  Will they know my intent well enough to improve upon it, or determine if some variant of it is &amp;#8220;valid&amp;#8221; in the sense that it is true to my original opinion, on which other consumers of this thing may depend?&amp;#8221;&lt;/p&gt;
&lt;p&gt;For domains that are simple in the ontological sense, it seems really dumb to use XML, because that question doesn&amp;#8217;t seem worth addressing.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s because you&amp;#8217;re confident other people could sit down, read a few your examples, and be comfortable adapting and extending your stuff.  JSON and YAML are great for applications that fit this scenario, especially when you don&amp;#8217;t have to worry about transport to or from places outside of your control.  Like on a web app, when you&amp;#8217;re doing Ajax stuff with your own backend.&lt;/p&gt;
&lt;p&gt;Sometimes though, you need to transfer data between applications - applications that are coded by different people, who might have different perspectives of the underlying domain that the data being transported is derived from.  And that&amp;#8217;s when you need to look into XML, because of all the formats out there, it has the most tooling and documentation around writing schemas.  XML schemas let you express your understanding of the domain, and how you chose to interpret pieces of it, &lt;em&gt;declaratively&lt;/em&gt;, in an almost human readable format.  More readable than BNF in my opinion, anyway.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s easy to know when you&amp;#8217;re doing it wrong.  Is your code littered with assertions about the structure of data coming from some outside source?  Are there failure cases for your application that can be triggered by malformed data sneaking in?  Do you have tons of unit tests around this?&lt;/p&gt;
&lt;p&gt;If you do, you might be comfortable.  You might feel good.  But what about the other guys?  If you have multiple developers working multiple code bases, all of which depend on some common interchange format, then the data on Bob&amp;#8217;s box running application Q actually depends on the unit tests running on Sally&amp;#8217;s box running application Z.  You can commit another cardinal sin and duplicate the tests, version and integration-test all of these apps together, or you can suck it up and investigate a transfer format that supports schemas.  Depending on your transport and other requirements, this might be XML, or it might be something like &lt;a href="http://thrift.apache.org/"&gt;Thrift&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Schemas are not the answer to every question, and, like any tool, they can be the wrong one for the job.  But in my limited experience, there&amp;#8217;s a place for XML and it is easy to overlook because of your own cultural bias.&lt;/p&gt;</description><link>http://alan.dipert.org/post/1606016275</link><guid>http://alan.dipert.org/post/1606016275</guid><pubDate>Wed, 17 Nov 2010 19:09:00 -0800</pubDate></item><item><title>Sending Small Secrets with Perl</title><description>&lt;p&gt;Suppose you&amp;#8217;d like to send a short message, like an account number, to a friend, but have no secure way to transfer it and can&amp;#8217;t hand the number off in person.&lt;/p&gt;
&lt;p&gt;If there&amp;#8217;s something that only you and your friend know, and this something in text is at least as long as the secret you&amp;#8217;d like to send, you&amp;#8217;re in luck.&lt;/p&gt;
&lt;p&gt;Using your shared secret, Perl, Base64, and the XOR cipher, you can communicate small secrets securely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;An Example&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Alice needs to send a 7 digit account number, like 9876543, to her friend Bob over e-mail.  Alice knows that Bob&amp;#8217;s first phone number was 555-4241 .  To encode the account number using this &lt;a href="http://en.wikipedia.org/wiki/Shared_secret"&gt;shared secret&lt;/a&gt;, she can &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt; encode the result of &lt;a href="http://en.wikipedia.org/wiki/XOR_cipher"&gt;XORing&lt;/a&gt; &amp;#8220;5554241&amp;#8221; and &amp;#8220;9876543&amp;#8221;.&lt;/p&gt;
&lt;p&gt;On her computer, she runs this small Perl script:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;perl -MMIME::Base64 -e 'print encode_base64("5554241"^"9876543")'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;which returns the string &amp;#8220;DA0CAgcAAg==&amp;#8221;&lt;/p&gt;
&lt;p&gt;Next, she composes an e-mail to Bob:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hey Bob, here is that account number. Run the following command, substituting the asterisks for your first phone number, no area code, and without the dash: perl -MMIME::Base64 -e &amp;#8216;print &amp;#8220;*******&amp;#8221;^decode_base64(&amp;#8220;DA0CAgcAAg==&amp;#8221;)&amp;#8217;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When Bob gets the message, he runs the command on his machine:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;perl -MMIME::Base64 -e 'print "5554241"^decode_base64("DA0CAgcAAg==")'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;which prints &lt;span&gt;9876543.&lt;/span&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/1588976216</link><guid>http://alan.dipert.org/post/1588976216</guid><pubDate>Mon, 15 Nov 2010 22:30:03 -0800</pubDate></item><item><title>alikins</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_l7y3fhqqCP1qzqgjfo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/alikins/"&gt;alikins&lt;/a&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/1034595982</link><guid>http://alan.dipert.org/post/1034595982</guid><pubDate>Sun, 29 Aug 2010 20:09:17 -0700</pubDate></item><item><title>"The canoe is hollowed out of a single, gigantic hardwood log. When they go stroking out to see in..."</title><description>“The canoe is hollowed out of a single, gigantic hardwood log. When they go stroking out to see in their big dugout canoe and you’re sitting outside looking at them paddling towards you, you think they’re coming out with their forks to have you for dinner. They couldn’t speak English and Mike couldn’t speak their language. They paddled by and said something like “Om Gowa Mungie Wung Ow.” Mike smiled and said, “Yeah man, hang ten.” They thought that was great, they went stroking out saying, “Hang ten, hang ten.” The only English word they know is “Hang Ten.” That has to be unique.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://www.santabarbarasurfing.com/endlesssummer.html"&gt;The Endless Summer&lt;/a&gt;&lt;/em&gt;</description><link>http://alan.dipert.org/post/990412759</link><guid>http://alan.dipert.org/post/990412759</guid><pubDate>Sat, 21 Aug 2010 19:39:42 -0700</pubDate></item><item><title>"A novice was trying to fix a broken Lisp machine by turning the power off and on.
Knight, seeing..."</title><description>“A novice was trying to fix a broken Lisp machine by turning the power off and on.&lt;br/&gt;
Knight, seeing what the student was doing, spoke sternly: “You cannot fix a machine by just power-cycling it with no understanding of what is going wrong.”&lt;br/&gt;
Knight turned the machine off and on.&lt;br/&gt;
The machine worked.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Hacker_koan#Master_Foo"&gt;Tom Knight&lt;/a&gt;&lt;/em&gt;</description><link>http://alan.dipert.org/post/988577308</link><guid>http://alan.dipert.org/post/988577308</guid><pubDate>Sat, 21 Aug 2010 11:42:52 -0700</pubDate></item><item><title>"The complexity of software is an essential property, not an accidental one. Hence, descriptions of a..."</title><description>“The complexity of software is an essential property, not an accidental one. Hence, descriptions of a software entity that abstract away its complexity often abstract away its essence. For three centuries, mathematics and the physical sciences made great strides by constructing simplified models of complex phenomena, deriving properties from the models, and verifying those properties by experiment. This paradigm worked because the complexities ignored in the models were not the essential properties of the phenomena. It does not work when the complexities are the essence.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Frederick P. Brooks, Jr., &lt;a&gt;No Silver Bullet: Essence and Accidents of Software Engineering&lt;/a&gt;&lt;/em&gt;</description><link>http://alan.dipert.org/post/457135087</link><guid>http://alan.dipert.org/post/457135087</guid><pubDate>Thu, 18 Mar 2010 12:32:19 -0700</pubDate></item><item><title>The S-expression Editor</title><description>&lt;p&gt;The other week I was reading about &lt;a href="http://bywicket.com/users/mikel/weblog/126a4/Bard.html"&gt;Bard&lt;/a&gt;, a new Lisp dialect, and ran into this:&lt;/p&gt;
&lt;p&gt;&amp;#8220;Historically, and in most other Lisp dialects, source code is explicitly or implicitly &lt;em&gt;not&lt;/em&gt; text; it is s-expressions. &lt;strong&gt;Text is just a print representation of the s-expressions.&lt;/strong&gt;&amp;#8221;&lt;/p&gt;
&lt;p&gt;Emphasis added.  This got me thinking.&lt;/p&gt;
&lt;h3&gt;for lisp, text editors are overkill&lt;/h3&gt;
&lt;p&gt;Good text editors like vim and Emacs are really good at everything having to do with text editing.  In fact, they&amp;#8217;re so good at such a wide variety of things, that their features wildly exceed the sort of operations one really needs to do when working on Lisp programs.&lt;/p&gt;
&lt;p&gt;For instance, even the idea of a &amp;#8220;newline&amp;#8221; (or any other character the average &lt;a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node13.html"&gt;Reader&lt;/a&gt; considers whitespace) doesn&amp;#8217;t really have any meaning in s-expression land outside of quoted strings.  Everything in the editor about them needn&amp;#8217;t be accessible to the programmer.&lt;/p&gt;
&lt;p&gt;So, what if instead of accepting text as our source editing medium, we operated directly on data structures?  That is, what if key strokes performed some operation directly on the program&amp;#8217;s data, and the editor simply pretty printed a nicely formatted representation of the current program following edits?&lt;/p&gt;
&lt;p&gt;This is my idea, and I&amp;#8217;m not sure it hasn&amp;#8217;t been done before.&lt;/p&gt;
&lt;h3&gt;some pros&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;Plugins&lt;/em&gt;: Plugin functions don&amp;#8217;t have to worry at all about dealing with or parsing text.  They&amp;#8217;re handed the data structure representing the current program (or arbitrary s-expression), along with a function representing the &amp;#8220;point&amp;#8221; or cursor location.  They transform it somehow, and return the new data structure.  The point might be stored as a &lt;a href="http://www.fatvat.co.uk/2009/01/functional-tree-editing.html"&gt;zipper&lt;/a&gt; partial.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Visualization: &lt;/em&gt;By separating editing from representation, it becomes simpler to develop alternative visualizations.  I think there might be a lot of interesting work to be done here, with things like contours, bubbles, and snippets.  For some cool ideas along these lines, check out Michael Weber&amp;#8217;s &lt;a href="http://www.foldr.org/~michaelw/emacs/"&gt;Emacs hackery page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Universal formatting:&lt;/em&gt; Since the programmer is no longer dealing directly with shareable, revisionable text, the text visualizer would serve also as the exporter when it came to source control and storage.  In the case of Clojure, this would effectively make the *code-dispatch* dispatch table for clojure.contrib.pprint the &lt;a href="http://gofmt.com/"&gt;gofmt&lt;/a&gt; of the language.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Evaluation: &lt;/em&gt;SLIME-like evaluation for Clojure would be trivial, assuming this editor was written in Clojure.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;some cons&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;Comments:&lt;/em&gt; Comments, and anything else in source code normally stripped by the Reader, would be completely lost.  This means that any such data would have to be metadata, something which seems cumbersome at best.  Maybe not.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Another editor?: &lt;/em&gt;Both vim and Emacs, and particularly Emacs with Paredit, have served me exceptionally well when it comes to editing Clojure.  I&amp;#8217;m not sure a new editor is warranted; but the idea of an editor written in Clojure that takes advantage of STM (for undo) and zippers (for commands and plugins) sounds pretty appealing.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;status&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve started playing with SWT in an effort to build a prototype.  I&amp;#8217;ll github it soon.  In the meantime, does anyone know if this has this been done before?  Are there unsurmountable pitfalls that make the idea pointless?  Thanks in advance!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;*update*&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I learned recently that the INTERLISP programming environment featured just such a structural editor.  Code was data, all the way down, and this was the late 1960s.  Screen display and output files were pretty-printed serializations.  Based on what I&amp;#8217;ve read, this capability took INTERLISP the IDE to a level of capability that blows away anything we have today.&lt;/p&gt;
&lt;p&gt;The wisdom of the ancients&amp;#8230;&lt;/p&gt;</description><link>http://alan.dipert.org/post/445462664</link><guid>http://alan.dipert.org/post/445462664</guid><pubDate>Sat, 13 Mar 2010 06:40:00 -0800</pubDate></item><item><title>go: git precommit hook for gofmt </title><description>&lt;a href="http://golang.tumblr.com/post/439868556/git-precommit-hook-for-gofmt"&gt;go: git precommit hook for gofmt &lt;/a&gt;: &lt;blockquote&gt;
&lt;p&gt;It’s no surprise I like Ruby, and &lt;a href="http://golang.org/cmd/gofmt/"&gt;gofmt&lt;/a&gt; is a great idea I wish Ruby could enforce. Instead of forgetting to run it constantly, let’s have git run it. In your &lt;code&gt;.git/hooks/pre-commit&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby
Dir["**/*.go"].each do |go| if File.basename(go) !~ /^_/ puts "gofmt #{go}" system("gofmt...&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ruby with enforced gofmt… ah yes, Python :)&lt;/p&gt;</description><link>http://alan.dipert.org/post/440474006</link><guid>http://alan.dipert.org/post/440474006</guid><pubDate>Wed, 10 Mar 2010 20:27:58 -0800</pubDate></item><item><title>NCSA Mosaic on Github</title><description>&lt;p&gt;&lt;img height="269" width="406" alt="NCSA Mosaic 2.7 viewing GitHub.com" src="http://github.com/downloads/alandipert/ncsa-mosaic/github.png"/&gt;&lt;/p&gt;
&lt;p&gt;In 1994, when I was in fourth grade, &lt;a href="http://dipert.org/"&gt;my dad&lt;/a&gt; brought me along with him to see a friend of his in the CS department at the University of Buffalo.  My dad&amp;#8217;s friend, &lt;a href="http://www.cse.buffalo.edu/~rapaport/"&gt;Bill Rapaport&lt;/a&gt;, was running NCSA Mosaic on a Sun workstation.  I vividly remember the moment he brought up &lt;a href="http://www.louvre.fr/llv/commun/home.jsp?bmLocale=en"&gt;the Louvre&amp;#8217;s website&lt;/a&gt; and a beautiful full color image of the Mona Lisa was magically beamed across the ocean from Paris, and onto the screen.&lt;/p&gt;
&lt;p&gt;My dad had shown me &lt;a href="http://en.wikipedia.org/wiki/Gopher_(protocol)"&gt;gopher&lt;/a&gt; before, but nothing was ever in color.  In fact, everything I&amp;#8217;d seen about computers up to that point seemed pretty boring.&lt;/p&gt;
&lt;p&gt;The moment I saw the Mona Lisa in full color on a computer monitor was one of only a handful of moments that led me to where I am now, which is a state of continual curiosity and wonder about these things, these machines, these computers.&lt;/p&gt;
&lt;p&gt;Thanks in &lt;a href="http://seanm.ca/mosaic/"&gt;great part to the work of others&lt;/a&gt;, I was able to pretty easily get Mosaic to compile and run on my machine, and to relive for a moment my childhood renaissance.&lt;/p&gt;
&lt;p&gt;What is the Mosaic, the Mona Lisa, that we can show children today?&lt;/p&gt;
&lt;p&gt;&lt;i&gt;If you&amp;#8217;re on GNU/Linux-Ubuntu (or something else, and you know your way around your package manager) you can compile and run NCSA Mosaic yourself: &lt;/i&gt;&lt;a href="http://github.com/alandipert/ncsa-mosaic"&gt;&lt;i&gt;&lt;a href="http://github.com/alandipert/ncsa-mosaic"&gt;http://github.com/alandipert/ncsa-mosaic&lt;/a&gt;&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/435071716</link><guid>http://alan.dipert.org/post/435071716</guid><pubDate>Mon, 08 Mar 2010 11:09:05 -0800</pubDate></item><item><title>Xerox Alto</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_kxt07miUDi1qzqgjfo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Xerox_Alto"&gt;Xerox Alto&lt;/a&gt;&lt;/p&gt;</description><link>http://alan.dipert.org/post/387937678</link><guid>http://alan.dipert.org/post/387937678</guid><pubDate>Sat, 13 Feb 2010 15:35:46 -0800</pubDate></item><item><title>Rich Hickey talks about the Clojure in Clojure project</title><description>&lt;iframe src="http://player.vimeo.com/video/9090935" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Rich Hickey talks about the Clojure in Clojure project&lt;/p&gt;</description><link>http://alan.dipert.org/post/362105151</link><guid>http://alan.dipert.org/post/362105151</guid><pubDate>Sat, 30 Jan 2010 15:33:05 -0800</pubDate></item><item><title>Passing Methods like Blocks in Ruby</title><description>&lt;p&gt;&lt;b&gt;Ruby&amp;#8217;s Functions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Ruby has four flavors of function, each with various nuances: methods, &lt;a href="http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/"&gt;blocks, Procs, and lambdas&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;A Simple Example&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The object Array has a bunch of methods on it that take blocks.  Normally, you write these blocks inline:&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;[1,2,3].map{|x| x+1} # → [2,3,4]
&lt;/pre&gt;
&lt;p&gt;But what if you have a method you&amp;#8217;d like to pass to map?&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;def addone(n)
  n+1
end
[1,2,3].map(addone) # → Doesn't work&lt;/pre&gt;
&lt;p&gt;The above example doesn&amp;#8217;t work because map is expecting a block.  We&amp;#8217;re not passing it one; instead, we&amp;#8217;re invoking addone with no arguments and attempting to pass the result of that invocation to map.&lt;/p&gt;
&lt;p&gt;To get a value representing the addone method, we can use Object.method, which takes the symbol of the name of the method as an argument:&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;def addone(n)
  n+1
end
[1,2,3].map(method(:addone)) # → Still doesn't work&lt;/pre&gt;
&lt;p&gt;That still doesn&amp;#8217;t work, but we&amp;#8217;re close.  Map expects a block, but we&amp;#8217;re passing it a Method. The key to this conversion is the &lt;a href="http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html"&gt;unary ampersand &amp;amp;&lt;/a&gt;, which will convert anything to a Proc that has a to_proc method, and then convert any Proc to a block.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s give it another shot:&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;def addone(n)
  n+1
end
[1,2,3].map(&amp;amp;method(:addone)) # → [2,3,4]&lt;/pre&gt;
&lt;p&gt;Voila! The point? This is just another way to consolidate and modularize code.  If you find yourself writing the same block over and over, and if it makes sense, you can write a method and reference to it.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Getting Complicated&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a &lt;a href="http://en.wikipedia.org/wiki/Polish_notation"&gt;Polish notation&lt;/a&gt; calculator that groups operators and arguments as &lt;a href="http://en.wikipedia.org/wiki/S-expression"&gt;S-expressions&lt;/a&gt;, with Arrays:&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;def evl(exp)
  if exp.is_a? Array
    exp.slice(1..-1).map(&amp;amp;method(:evl)).inject(exp.first)
  else
    exp
  end
end

evl(3) # → 3
evl([:+, 4, 5]) # → 9
evl([:+, 1, 2, [:-, 10, 7]]) # → 6
&lt;/pre&gt;
&lt;p&gt;If the input to evl is an Array, evl maps every element of the Array except the first to itself, and then reduces the resulting Array with the first term, which should be a Symbol representing a binary function.  evl takes advantage of the fact that inject automatically &lt;a href="http://weblog.raganwald.com/2008/02/1100inject.html"&gt;casts Symbols to blocks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This example is different from the one above, in that &amp;amp;method(:evl) occurs inside of evl, which doesn&amp;#8217;t actually work in Ruby 1.8.7.  It seems to work in 1.9.1, though.&lt;/p&gt;</description><link>http://alan.dipert.org/post/339368222</link><guid>http://alan.dipert.org/post/339368222</guid><pubDate>Sun, 17 Jan 2010 09:30:00 -0800</pubDate></item><item><title>Lazy Sequences in Javascript</title><description>&lt;p&gt;I&amp;#8217;ve played around a bit more with the &lt;a href="http://peter.michaux.ca/articles/lazy-function-definition-pattern"&gt;Lazy Function Definition pattern&lt;/a&gt; I mentioned in my &lt;a href="http://alan.dipert.org/post/332027463/lazy-function-definitions-and-undo-in-javascript"&gt;last post&lt;/a&gt;, and implemented a Javascript object for creating lazy sequences.  Here&amp;#8217;s what the fibonacci sequence looks like, a nearly direct port (minus destructuring) of Christophe Grand&amp;#8217;s &lt;a href="http://groups.google.com/group/clojure/msg/cb3db6e6ac94092f"&gt;Clojure version&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="sh_javascript"&gt;function fibo() {
  return new LazySeq(
    function(pair){
      return [pair[1],pair[0]+pair[1]];
    },
    [0,1])
    .map(first);
}

fibo().take(10);
//0,1,1,2,3,5,8,13,21,34
&lt;/pre&gt;
&lt;p&gt;LazySeq.map is itself lazily applied, and values are only actually &amp;#8220;realized&amp;#8221; with either LazySeq.take or LazySeq.nth.&lt;/p&gt;
&lt;p&gt;For the LazySeq code, check out &lt;a href="http://gist.github.com/276966"&gt;the Gist&lt;/a&gt;.  It doesn&amp;#8217;t include my crappy Array.prototype.reduce implementation, but you could easily substitute in &lt;a href="http://documentcloud.github.com/underscore/#reduce"&gt;Underscore.js&amp;#8217;s reduce&lt;/a&gt;.  Happy Javascripting!&lt;/p&gt;</description><link>http://alan.dipert.org/post/333763676</link><guid>http://alan.dipert.org/post/333763676</guid><pubDate>Wed, 13 Jan 2010 23:14:00 -0800</pubDate></item></channel></rss>

