{"id":11,"date":"2014-01-12T14:12:17","date_gmt":"2014-01-12T14:12:17","guid":{"rendered":"http:\/\/procyonic.org\/blog\/?p=11"},"modified":"2014-01-23T13:59:21","modified_gmt":"2014-01-23T13:59:21","slug":"hey-what-is-up-with-you-and-lisp","status":"publish","type":"post","link":"https:\/\/procyonic.org\/blog\/hey-what-is-up-with-you-and-lisp\/","title":{"rendered":"Hey, what is up with you and Lisp?"},"content":{"rendered":"<p>Yeah. What <i>is<\/i> up with me and Lisp? Maybe you are a Lisp programmer and you&#8217;re interested in why I choose to spend so much time in parentheses. Or maybe you&#8217;ve never programmed in Lisp and you&#8217;re interested in why someone might choose to.<\/p>\n<p>Well, these days, the question of why a person might choose Lisp is somewhat difficult to definitively answer. Time was, Lisp could make the claim, along with cousins, like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Smalltalk\">Smalltalk<\/a>, to be among the most forward thinking of programming languages, but contemporary life is littered with languages just as <a href=\"http:\/\/www.lua.org\/\">clever<\/a><a>, <\/a><a href=\"https:\/\/www.ruby-lang.org\/en\/\">dynamic<\/a>, <a href=\"http:\/\/www.python.org\/\">ergonomic<\/a>, or <a href=\"http:\/\/www.haskell.org\/haskellwiki\/Haskell\">mathematically sound<\/a>. So while the question is, in many ways, more difficult to answer than ever, it is also more salient than it has ever been<sup>1<\/sup>.<\/p>\n<h3>(Maybe it&#8217;s not the) Metaprogramming<\/h3>\n<p>It bears emphasis that Lisp isn&#8217;t a single language, but a family of dialects with widely varying semantics, and significantly varying syntaxes. This misperceived closeness among dialects is a somewhat unusual aspect of the Lisp family or the culture around the culture around Lisp<sup>1<\/sup>. For instance, Lua and Javascript are much more closely related than, say, Clojure and Common Lisp, yet we do not instantly group the former pair into a language family, say of, `table based dynamic programming languages`.<\/p>\n<p>However, the one thing Lisp dialects tend to have in common is the ease with which one can metaprogram, and I think this is a major component of the Lisp experience and this at least seems to be related to their distinctive, fully parenthesized, s-expression based syntaxes. And I would like to advance that it is in the area of syntactic simplicity that Lisp&#8217;s true appeal lies, at least to this author.<\/p>\n<p>So what, right? The observation that metaprogramming is the reason to use and\/or like Lisp is hardly new. Sure. But what is true is that metaprogramming is now hardly the exclusive domain of Lisp. Contemporary programming languages all support aspects of metaprogramming in one form or another. In Ruby, for instance, <a href=\"http:\/\/www.robertsosinski.com\/2008\/12\/21\/understanding-ruby-blocks-procs-and-lambdas\/\">blocks<\/a> give you 70% of what you want out of metaprogramming for 10% of the price you pay in Lisp<sup>2<\/sup>, Python uses <a href=\"http:\/\/placidrage.github.io\/kb\/development\/languages\/python\/1-decorators\/1-metaprogramming\/index.html\">decorators<\/a> to expose a limited set of metaprogrammatic techniques, C++ allows psychopaths<sup>3<\/sup> to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Template_metaprogramming\">template metaprogram<\/a>, language-level support for <a href=\"http:\/\/www.haskell.org\/haskellwiki\/Monad\">monads<\/a> in Haskell constitutes a kind of metaprogramming in that it exposes an interface for the nature of binding in certain contexts<sup>4<\/sup>. And if these language features don&#8217;t strike you as rich enough to compete with Lisp&#8217;s `just mess with the code before the compiler gets it` approach, <a href=\"http:\/\/www.haskell.org\/haskellwiki\/Template_Haskell\">most<\/a> <a href=\"https:\/\/pypi.python.org\/pypi\/MetaPython\">languages<\/a> have <a href=\"http:\/\/jlongster.com\/Stop-Writing-JavaScript-Compilers--Make-Macros-Instead\">these sorts of facilities<\/a> these days.<\/p>\n<p>So what is it that you can&#8217;t get from other languages that you can get in Lisp?<\/p>\n<h3>What you get<\/h3>\n<p>At the outset, I want to say that I&#8217;ve had the luck to work in Common Lisp for the past two years and that, after an initial period of adjustment, I&#8217;ve come to see the language as extraordinarily well designed, if lacking, somewhat, in modern sensibilities. So if you choose to work in Common Lisp, you get a very pragmatic, extensively well thought out, extremely powerful base language to work with. As a matter of comparison, Common Lisp is more cleverly and extensibly object oriented than Ruby, with semantics carefully thought out so that most implementations can acheive significantly better performance. So if you have the expertise and the temperment, you can rely on a good Common Lisp implementation to get you where you need to to go.<\/p>\n<p>But that isn&#8217;t really the point of this little essay. I&#8217;m not primarily interested in the best language for getting a project to completion. If that is your interest, lots of factors will influence your decision that don&#8217;t have anything to do with the fact that Lisp might feel like a really well broken in pair of jeans.<\/p>\n<p>Ultimately, I think Lisp&#8217;s real strength is the unpretentiousness with which it exposes the underlying nature of the programming system. While the Lisp community might be accused of pretention from time to time, I think the language is decidedly straightforward: in most languages you go through the, in my opinion, silly exercise of denoting a program tree using some large set of syntactic conventions, and then the language runtime converts that into a syntax tree, which is then operated upon to produce executable instructions of some kind. In Lisp, you are able to pretend, at least<sup>5<\/sup>, that you are denoting that intermediate tree directly.<\/p>\n<p>This is not profound. On the contrary, it is essentially pragmatic<sup>6<\/sup>, and it has the appeal of the essentially pragmatic.<\/p>\n<p>One source of feelings of alienation, in my opinion, is to be expected or forced to act in ways which one knows are meaningless. It might be argued that your average algol-syntaxed language is asking you to do that which is alienating: denote what you know is simply a tree as something which requires a complex transformation to arrive there.<\/p>\n<p>The benefits of this simplicity extend beyond vague feelings of empowerment. They enable, for instance, one to engage in code transformations without the <i>conceptual<\/i> overhead of source to source transformation. Of course, the runtime is performing a source-to-tree transformation, but it feels trivial, and your own code which operates on the parse tree can, most of the time, be written as though it is operating on the thing you typed, rather than the thing which is produced by the runtime. Once you encompass backquote, unquote, and unquote splice, denoting program transformations requires very little conceptual overhead<sup>7<\/sup>.<\/p>\n<p>But the other benefit is the fact that your toolchain benefits in kind from the simplicity of the language. Tools like <a href=\"http:\/\/www.emacswiki.org\/emacs\/ParEdit\">paredit<\/a> or the excellent <a href=\"http:\/\/racket-lang.org\/\">Dr Racket<\/a><sup>8<\/sup> further close the gap between typing individual characters and denoting and manipulating, directly, the code tree.<\/p>\n<h3>The Anticlimax<\/h3>\n<p>So this isn&#8217;t exactly a resounding endorsement of the language, but that is exactly my point. I don&#8217;t think it is credible, in the contemporary programming language ecosystem, to claim that Lisp is significantly better as an existential matter, than a lot of languages out there. In many respects, languages like Haskell are much better considered intellectually, and a language like Javascript is much better positioned to actually deliver a product to someone.<\/p>\n<p>But I do think that Lisp&#8217;s simplicity in the arena of &#8220;source to parse tree to executable code&#8221; gives it a distinctly pleasant, distinctly empowering &#8220;feel,&#8221; and that probably accounts for a significant number of its deep adherents.<\/p>\n<p>And that is the deal with me and Lisp.<\/p>\n<h3>Footnotes<\/h3>\n<p><sup>1<\/sup>: That is to say, the similarity is not itself a property of the languages, nor a property of the immediate Lisp community, who somewhat close to the languages in question, tend not to confuse them, but a property of the community of programmers `at large`.<\/p>\n<p><sup>2<\/sup>: Of course Smalltalk did blocks earlier and better.<\/p>\n<p><sup>3<\/sup>: No shortage of these, somehow.<\/p>\n<p><sup>4<\/sup>: A given monad can be thought of as specifying alternative semantics for the act of binding a value to a variable and handling the result of an expression evaluated in the context of that binding. A surprisingly large space of `mini-languages` can be reached by controlling exactly what these two operations constitute.<\/p>\n<p><sup>5<\/sup>: I say pretend because it turns out that your average Lisp reader is really doing a lot of work, and that the data structure you denote and its denotation are, as a consequence, not as close to one another as you might imagine. The key is that they are close enough that you <i>can<\/i> avoid thinking too hard about it most of the time.<\/p>\n<p><sup>6<\/sup>: Literally. The original intent was to denote Lisp programs using <a href=\"http:\/\/en.wikipedia.org\/wiki\/M-expression\">m-expressions<\/a>, but it was an extra complication that never really caught on, since most programmers found it simpler to just use parenthesized notation.<\/p>\n<p><sup>7<\/sup>: Or so it seems. One shortcoming of Lisp, it might be argued, is that it makes thinking about program transformation seem easier than it actually is. Correct program transformations, in which the resulting code does what you expect it to do in <i>all<\/i> scenarios is a pretty hard problem. A hard problem which is not even generally conceived of in its entirety by those writing macros, as evidenced by the frequency with which one hears the false claim that `gensym` is sufficient to avoid unexpected behavior.<\/p>\n<p><sup>8<\/sup>: To be fair, Racket goes way beyond Lisp in general in this area.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yeah. What is up with me and Lisp? Maybe you are a Lisp programmer and you&#8217;re interested in why I choose to spend so much time in parentheses. Or maybe you&#8217;ve never programmed in Lisp and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"footnotes":""},"categories":[47],"tags":[2,3,5,4,6],"class_list":["post-11","post","type-post","status-publish","format-standard","hentry","category-programming","tag-lisp","tag-programming","tag-racket","tag-scheme","tag-weak-evangelism"],"_links":{"self":[{"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/posts\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":7,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":24,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/posts\/11\/revisions\/24"}],"wp:attachment":[{"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/media?parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/categories?post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/procyonic.org\/blog\/wp-json\/wp\/v2\/tags?post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}