<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkEMRnk5fip7ImA9WhRUEEs.&quot;"><id>tag:blogger.com,1999:blog-6454006</id><updated>2012-01-20T14:11:27.726Z</updated><category term="scheme" /><category term="ui" /><category term="psychology" /><category term="names" /><category term="type" /><category term="clojure" /><category term="haskell" /><category term="security" /><category term="terms" /><category term="arc" /><category term="macros" /><category term="history" /><category term="games" /><category term="keyboards" /><category term="setf" /><category term="lisp" /><category term="rebol" /><category term="common-lisp" /><category term="syntax" /><category term="c++" /><category term="library" /><category term="function of the day" /><title>Arcane Sentiment</title><subtitle type="html">about programming languages and other user interfaces.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://arcanesentiment.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>179</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ArcaneSentiment" /><feedburner:info uri="arcanesentiment" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DE4BRn8-fSp7ImA9WhdXF00.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-2897769496351206985</id><published>2011-08-30T12:21:00.000Z</published><updated>2011-08-30T12:22:37.155Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-30T12:22:37.155Z</app:edited><title>Superficial features affect style</title><content type="html">&lt;p&gt;While translating some code from Perl to a toy Lisp, I noticed I was treating something differently in the two languages: variables with one-letter names look much worse in Lisp than in Perl. &lt;code&gt;$s&lt;/code&gt; obviously doesn't collide with anything predefined, but &lt;code&gt;s&lt;/code&gt; looks like it might collide with something (perhaps the &lt;code&gt;s&lt;/code&gt; combinator?), so I felt obliged to give it a longer name in Lisp, even though this didn't really help readability. But I was perfectly comfortable with the one-letter name in the original Perl.

&lt;p&gt;There are some good reasons for worrying less about name collisions in Perl. Variable sigils reduce the risk of collisions by putting functions and scalars in separate namespaces. Perl doesn't have many predefined names, and entirely avoids one-letter names, so there's less need to worry about collisions with them. But I suspect my main reason was just that &lt;code&gt;$s&lt;/code&gt; doesn't &lt;em&gt;look&lt;/em&gt; like a one-letter name.
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-2897769496351206985?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/D_RPW96DJOM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/2897769496351206985/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=2897769496351206985" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2897769496351206985?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2897769496351206985?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/D_RPW96DJOM/superficial-features-affect-style.html" title="Superficial features affect style" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/superficial-features-affect-style.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEECRng6eCp7ImA9WhdXEE8.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-162412378149436637</id><published>2011-08-22T13:44:00.003Z</published><updated>2011-08-22T14:17:47.610Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-22T14:17:47.610Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="function of the day" /><title>Closures of sets</title><content type="html">&lt;p&gt;Some operations are common in mathematical reasoning, but are not traditionally used in programming, even when they make sense. I stumbled on one of these recently: I described something as the closure of a set under an operation, and then sought some other way to compute it, because the mathematical description didn't sound like an implementation. After a few minutes I realized there was no reason it shouldn't be:

&lt;pre&gt;&lt;code&gt;(defn &lt;b&gt;closure-unary&lt;/b&gt; "Closure of a set under a function." [f xs]
  (loop [done #{}
	 pending xs]
    (if (empty? pending)
      done
      (let [x (first pending)]
        (if (contains? done x)
	  (recur done (rest pending))
	  (recur (conj done x) (cons (f x) (rest pending))))))))&lt;/code&gt;

user=&amp;gt; &lt;code&gt;(closure-unary - (range 3))&lt;/code&gt;
#{0 1 2 -2 -1}
user=&amp;gt; &lt;code&gt;(closure-unary #(mod (inc %) 10) [0])&lt;/code&gt;
#{0 1 2 3 4 5 6 7 8 9}
user=&amp;gt; &lt;code&gt;(defn collatz [n] (if (even? n) (quot n 2) (inc (* n 3))))&lt;/code&gt;
#'user/collatz
user=&amp;gt; &lt;code&gt;(closure-unary collatz [27])&lt;/code&gt;
#{160 1 161 577 2 1154 1186 322 866 2051 35 4 2308 484 1732 5 3077
 325 4102 70 3238 71 103 167 263 8 40 488 4616 41 137 233 425 10
 6154 106 650 107 395 1132 364 46 2158 142 206 334 526 2734 47 175
 719 911 16 9232 80 976 433 593 82 242 274 466 754 850 1619 20 244
 1300 1780 53 182 214 310 502 566 790 23 1079 1367 7288 184 1336
 121 377 122 4858 890 27 91 155 251 283 92 124 1276 412 3644 668
 700 61 2429 445 62 94 350 1438 638 1822 958 31 319 479}&lt;/pre&gt;

&lt;p&gt;That was the version I wanted, but closure under a binary operator is probably more common:

&lt;pre&gt;&lt;code&gt;(defn &lt;b&gt;closure-binary&lt;/b&gt; "Closure of a set under a binary operator." [f xs]
  (loop [done #{}
	 pending xs]
    (if (empty? pending)
      done
      (let [x (first pending)]
	(if (contains? done x)
	  (recur done (rest pending))
	  (recur (conj done x)
		 (concat (map #(f x %) done)
			 (map #(f % x) done) &lt;small&gt;;in case it's not associative&lt;/small&gt;
			 (list (f x x))
			 (rest pending))))))))&lt;/code&gt;

user=&amp;gt; &lt;code&gt;(closure-binary #(not (or %1 %2)) [false])&lt;/code&gt;
#{true false}
user=&amp;gt; &lt;code&gt;(closure-binary #(mod (- %1 %2) 11) [1])&lt;/code&gt;
#{0 1 2 3 4 5 6 7 8 9 10}&lt;/pre&gt;

&lt;p&gt;The two variants are identical except in how they generate new elements. The common part could be factored out...

&lt;pre&gt;&lt;code&gt;(defn closure* "Closure of a set under a function generating new elements:
(children element old-elements) should return a seq of elements to add."
  [children xs]
  (loop [done #{}
	 pending xs]
    (if (empty? pending)
      done
      (let [x (first pending)]
        (if (contains? done x)
	  (recur done (rest pending))
	  (recur (conj done x) (into (rest pending) (children x done))))))))

(defn closure-unary [f xs]
  (closure* (fn [x done] (list (f x))) xs))

(defn closure-binary [f xs]
  (closure* (fn [x done]
	       (concat (map #(f x %) done)
		       (map #(f % x) done)
		       (list (f x x))))
	    xs))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...but passing &lt;code&gt;done&lt;/code&gt; to &lt;code&gt;children&lt;/code&gt; is not very intuitive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-162412378149436637?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/LmuYpS0S8K4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/162412378149436637/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=162412378149436637" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/162412378149436637?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/162412378149436637?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/LmuYpS0S8K4/closures-of-sets.html" title="Closures of sets" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/closures-of-sets.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AAR3s-fCp7ImA9WhdQF0g.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-6033762872619978714</id><published>2011-08-19T12:05:00.003Z</published><updated>2011-08-19T13:15:46.554Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-19T13:15:46.554Z</app:edited><title>Special behaviour for interactive redefinitions</title><content type="html">&lt;p&gt;Dynamism &amp;mdash; allowing definitions to be replaced in a running program &amp;mdash; is a hugely convenient feature, because it can shorten the edit-test loop by so much. But like many powerful features, it makes some errors harder to detect &amp;mdash; in this case, name collisions. It's easy to catch these automatically in a static language: simply make redefinition of an existing variable an error. But in a dynamic language, redefinition is a feature, so we can't simply reject it. We can give a warning, so collisions won't go undetected, but this will annoy users whenever they interactively redefine something. Can we do better?

&lt;p&gt;In some Lisps, &lt;code&gt;defvar&lt;/code&gt; has a related problem, and illustrates a possible solution. Its purpose is to create a (global) variable with a given initial value. There's a problem with redefining: what do you do if the variable already exists, and has a different value?

&lt;p&gt;In both Common Lisp and Emacs Lisp, &lt;code&gt;defvar&lt;/code&gt; has the curious feature that it sets the variable only if it doesn't already have a value &amp;mdash; if it already exists, it's not changed. This is intended to make re-&lt;code&gt;load&lt;/code&gt;ing sourcefiles safe: otherwise, it would reset your global variables.

&lt;p&gt;If you think this is surprising behavior, you're not alone. Alan Crowe once &lt;a href='http://groups.google.com/group/comp.lang.lisp/msg/61c6c2902ae44cdb'&gt;suggested&lt;/a&gt; that it would be less confusing if &lt;code&gt;defvar&lt;/code&gt; were called something like &lt;code&gt;def-perv-noclobber&lt;/code&gt; instead, because neither its pervasive &lt;code&gt;special&lt;/code&gt;ness nor its clobber-avoidance are what you would expect from something called &lt;code&gt;defvar&lt;/code&gt;. (&lt;a href='http://clojuredocs.org/clojure_core/clojure.core/defonce'&gt;&lt;code&gt;defonce&lt;/code&gt;&lt;/a&gt; is a better name.)

&lt;p&gt;When a user reevaluates a single &lt;code&gt;defvar&lt;/code&gt; interactively, however, they probably &lt;em&gt;do&lt;/em&gt; want to clobber the value, or they wouldn't bother. Both &lt;a href='http://www.gnu.org/s/emacs/manual/html_node/elisp/Defining-Variables.html'&gt;Emacs&lt;/a&gt; and &lt;a href='http://www.cliki.net/SLIME%20Features'&gt;Slime&lt;/a&gt; therefore have a special case: when a &lt;code&gt;defvar&lt;/code&gt; is evaluated interactively (as by C-M-x), it &lt;em&gt;will&lt;/em&gt; clobber any existing value. This is ugly, of course, but like C-t's irregular behaviour at end-of-line, it does what the user wants.

&lt;p&gt;Something similar might be useful for detecting errors of redefinition. Can we allow redefinitions when a definition is evaluated interactively, but not when it's loaded as part of a file? No, because it's normal to reload a source file after editing it, which replaces every definition in the file, but shouldn't produce any warnings. Nor should we disable the warning for all interactive evaluation, including &lt;code&gt;load&lt;/code&gt;, because that's when the warnings are most useful. Interactivity alone is not a sufficient reason to suppress warnings.

&lt;p&gt;What we really want is to warn about redefinition only &lt;em&gt;within a single interactive operation&lt;/em&gt;. It's generally OK for a &lt;code&gt;load&lt;/code&gt; to replace old definitions; it's only suspicious if a definition is made twice without user intervention. So if a name is defined twice in a single &lt;code&gt;load&lt;/code&gt; (directly, or in any other files it loads), that's an error or warning, but when it's defined twice in two separate batches, that's OK. This is easily to implement (by e.g. recording each definition made in the current &lt;code&gt;load&lt;/code&gt;), and gives much more precise warnings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-6033762872619978714?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/q5NKDZ8wXOM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/6033762872619978714/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=6033762872619978714" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6033762872619978714?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6033762872619978714?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/q5NKDZ8wXOM/special-behaviour-for-interactive.html" title="Special behaviour for interactive redefinitions" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/special-behaviour-for-interactive.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcHR3w8fip7ImA9WhdQF08.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-6086105400410041246</id><published>2011-08-19T01:13:00.005Z</published><updated>2011-08-19T02:13:56.276Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-19T02:13:56.276Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>If it's good enough for a real antivirus, it's good enough for a fake one</title><content type="html">&lt;p&gt;I encountered a piece of scareware recently &amp;mdash; "Windows Vista Antispyware", which claimed to be part of Windows and to have detected viruses and other malware, and demanded money to "remove" them.

&lt;p&gt;It was slickly done. The UI looked like part of the Windows Security Center control panel, there were only a few typos and stylistic missteps, and the infections it reported were the (randomly selected) names of real malware. But it would have been more convincing if it hadn't claimed the machine was infected with the dreaded &lt;a href='http://en.wikipedia.org/wiki/EICAR_test_file'&gt;EICAR-Test-File&lt;/a&gt;.
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-6086105400410041246?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/sw1jfkjk73c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/6086105400410041246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=6086105400410041246" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6086105400410041246?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6086105400410041246?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/sw1jfkjk73c/if-its-good-enough-for-real-antivirus.html" title="If it's good enough for a real antivirus, it's good enough for a fake one" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/if-its-good-enough-for-real-antivirus.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cGQ3o6cSp7ImA9WhdQEUw.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-8447582475353188060</id><published>2011-08-12T02:08:00.000Z</published><updated>2011-08-12T02:10:22.419Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-12T02:10:22.419Z</app:edited><title>State is not always to blame</title><content type="html">&lt;p&gt;Nelson Elhage describes &lt;a href='http://blog.nelhage.com/2010/12/cve-2010-4258-from-dos-to-privesc/'&gt;a cute Linux vulnerability&lt;/a&gt;, of which the heart is that Linux sometimes temporarily turns off its pointer validity checks, and then does things that aren't safe without those checks.

&lt;p&gt;My reaction (after the initial &lt;i&gt;wow, Linux has stupid mistakes too&lt;/i&gt;, as if it should be a surprise) was interestingly wrong: I blamed the problem on the use of state, and briefly supposed it should have been done with something like dynamic scope instead. But actually state had nothing to do with it. The problem was in turning off the checks over an unnecessarily large scope, and in not being clear about what operations were safe with the checks turned off. That they were turned off statefully was irrelevant; the result would have been the same regardless of the mechanism.

&lt;p&gt;Zealous functional puritans blame all kinds of problems on state, and they have an unwholesome influence on other functional programmers. We learn that state is an acceptable target, that it's the usual suspect for any problem, that no evidence is necessary to accuse it. And so we do so even in cases like this vulnerability, where a moment's thought would reveal that state was innocent, and for many other problems whose causes are not so obvious. How many really have anything to do with state?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-8447582475353188060?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/n4hc3pd5maA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/8447582475353188060/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=8447582475353188060" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8447582475353188060?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8447582475353188060?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/n4hc3pd5maA/state-is-not-always-to-blame.html" title="State is not always to blame" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>4</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/state-is-not-always-to-blame.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIBQH8yfSp7ImA9WhdRGUU.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-8746330703343948912</id><published>2011-08-10T13:56:00.004Z</published><updated>2011-08-10T14:29:11.195Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-10T14:29:11.195Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><title>Why use keywords as symbols?</title><content type="html">&lt;p&gt;From the beginning, Lisp has been associated with symbolic programming, for which symbols have always been the canonical type. So it's odd that many Lisps also have a separate &lt;code&gt;:keyword&lt;/code&gt; type, which they use instead of symbols for all symbolic purposes except representing their own programs. Why bother? Why have two separate types that mean the same thing?

&lt;p&gt;The motivation, in Common Lisp and (AFAIK) Clojure, is that these languages' symbols aren't pure symbols: in addition to identity and name, they include some other features, in particular a package or namespace. That's useful for representing programs, but most other applications of symbols don't want namespaces, so the languages also have keywords to serve as pure symbols. Lisps whose symbols don't have packages don't usually bother with keywords, but Racket and elisp have them anyway for use with keyword arguments. (In Racket, they need to be distinct from symbols because the function call form handles them specially rather than just passing them as part of the arglist. In elisp, they're only cosmetic; plain symbols could have been used instead.)

&lt;p&gt;Avoiding namespaces is a good reason to use keywords, but I don't think it's the only reason, because users don't see keywords as a workaround; they seldom have to be told to avoid symbols because they're more complex than they appear. Instead, they overwhelmingly prefer keywords, not just for keyword arguments but as symbolic values. Even in elisp, where there's no reason not to use ordinary symbols, keywords are sometimes used instead. Why?

&lt;p&gt;For one thing, they help distinguish programs from data. Humans, even Lispers who know better, tend to see these as two different things, and get confused when they mistake one for the other. When programs are written with symbols and data is written with keywords, it's easy to tell them apart.

&lt;p&gt;Keywords are also more regular in appearance, because they're self-evaluating. It's tempting (for beginners, and as an unconscious heuristic for non-beginners) to think of symbols and keywords as differing only in their prefix character: &lt;code&gt;'x&lt;/code&gt; is the practical equivalent of &lt;code&gt;:x&lt;/code&gt;, right? But they're not equivalent, because symbols have a quote only when they appear as forms. When they appear in a larger piece of quoted data, or as output from the REPL, or in non-evaluated contexts, they don't have the quote. This is only a superficial inconsistency, but it's annoying:

&lt;pre&gt;CL-USER&amp;gt; &lt;code&gt;(list 'a 'b 'c)&lt;/code&gt;
(A B C)
CL_USER&amp;gt; &lt;code&gt;(second '(a b c))&lt;/code&gt;
B
CL-USER&amp;gt; &lt;code&gt;(defclass foo () ((a type integer initarg a accessor foo-a)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(That last is not valid CL, obviously; it's what &lt;code&gt;defclass&lt;/code&gt; would look like without keywords. I suspect users would perennially forget that most of the slot options aren't evaluated, even more than they already do, and put in quotes anyway, because they're not accustomed to writing unquoted symbols.)

&lt;p&gt;Keywords, because they're self-evaluating, don't have this variation. They look the same whether they're in quoted data, or in the output of the REPL, or standing alone as forms, or as non-forms:

&lt;pre&gt;CL-USER&amp;gt; &lt;code&gt;(list :a :b :c)&lt;/code&gt;
(:A :B :C)
CL-USER&amp;gt; &lt;code&gt;(second '(:a :b :c))&lt;/code&gt;
:B
CL-USER&amp;gt; &lt;code&gt;(defclass foo () ((a :type integer :initarg :a :accessor foo-a)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;More comfortable, isn't it? I wonder if this explains some of the popularity of keywords. (And also of Clojure's vectors, which while not strictly self-evaluating are similarly more regular in appearance than lists, because they don't usually require quoting.) If so, this is an disappointment to me, because it means this seemingly pointless distinction, like that between symbols and strings, is actually doing something important, and can't necessarily be simplified away.
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-8746330703343948912?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/raIiVFOWCFQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/8746330703343948912/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=8746330703343948912" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8746330703343948912?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8746330703343948912?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/raIiVFOWCFQ/why-use-keywords-as-symbols.html" title="Why use keywords as symbols?" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>5</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/why-use-keywords-as-symbols.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4BR3gzeyp7ImA9WhdRFkU.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-7130047376399395854</id><published>2011-08-07T01:39:00.004Z</published><updated>2011-08-07T02:42:36.683Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T02:42:36.683Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="common-lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="macros" /><title>An anaphoric-macro-defining macro</title><content type="html">&lt;p&gt;&lt;i&gt;Attention conservation notice: this post is about a special-purpose macro-defining macro. I doubt it will be of much interest to anyone but macro fans.&lt;/i&gt;

&lt;p&gt;A year ago, Vladimir Sedach &lt;a href='http://carcaddar.blogspot.com/2010/08/input-needed.html'&gt;asked&lt;/a&gt; for arguments about why macros are and aren't useful. (He didn't get many; most of the people who can make such arguments are tired of doing so and not confident they're right.) In the same post, he mentioned that he uses the &lt;a href='http://www.common-lisp.net/project/anaphora/'&gt;Anaphora&lt;/a&gt; macro library. Anaphora itself provides an example of how macros are useful, not only because it defines some handy ones, but because many of their &lt;a href='http://common-lisp.net/viewvc/anaphora/src/anaphora.lisp?revision=1.8&amp;view=markup'&gt;definitions&lt;/a&gt; are repetitive:

&lt;pre&gt;&lt;code&gt;(defmacro awhen (test &amp;body body)
  "Like WHEN, except binds the result of the test to IT (via LET) for the scope
of the body."
  `(anaphoric when ,test ,@body))

(defmacro swhen (test &amp;body body)
  "Like WHEN, except binds the test form to IT (via SYMBOL-MACROLET) for the
scope of the body. IT can be set with SETF."
  `(symbolic when ,test ,@body))

(defmacro acase (keyform &amp;body cases)
  "Like CASE, except binds the result of the keyform to IT (via LET) for the
scope of the cases."
  `(anaphoric case ,keyform ,@cases))

(defmacro aetypecase (keyform &amp;body cases)
  "Like ETYPECASE, except binds the result of the keyform to IT (via LET) for
the scope of the cases."
  `(anaphoric etypecase ,keyform ,@cases))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the sort of repetition that could be addressed with a macro. We can generate these definitions automatically, docstrings and all:

&lt;pre&gt;&lt;code&gt;(defmacro &lt;b&gt;defanaphoric&lt;/b&gt; (name (firstarg &amp;amp;rest moreargs) original &amp;amp;key settable)
  "Define NAME as a macro like ORIGINAL, but binding IT to the result of FIRSTARG.
If SETTABLE is true, IT will be a symbol-macro which can be set with SETF."
  (let ((whole (gensym "WHOLE")))
    `(defmacro ,name (&amp;amp;whole ,whole ,firstarg ,@moreargs)
       ,(format nil "Like ~S, except binds the result of ~S to IT (via ~S) for the scope of the ~A.~A"
          original
          firstarg
          (if settable 'let 'symbol-macrolet)
          (if (and moreargs (member (car moreargs) '(&amp;amp;body &amp;amp;rest))) (cadr moreargs) "body")
          (if settable " IT can be set with SETF." ""))
       ,@(mapcan (lambda (a) (unless (member a lambda-list-keywords)
                               `((declare (ignore ,a)))))
                 (cons firstarg moreargs))
       `(,',(if settable 'symbolic 'anaphoric) ,',original ,@(cdr ,whole)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then it's easy to define individual anaphoric macros:

&lt;pre&gt;&lt;code&gt;(defanaphoric awhen (test &amp;body body) when)
(defanaphoric swhen (test &amp;body body) when :symbolic t)
(defanaphoric acase (keyform &amp;body cases) case)
(defanaphoric aetypecase (keyform &amp;body cases) etypecase)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that almost half the code about generating docstrings. Anaphoric macros, like many other things, would be much simpler to define if they didn't need documentation.

&lt;p&gt;The argument list &lt;code&gt;(firstarg &amp;amp;rest moreargs)&lt;/code&gt; also exists purely for documentation purposes. We don't need it to define the macros &amp;mdash; a simple &lt;code&gt;&amp;amp;rest&lt;/code&gt; would do &amp;mdash; but we need to pass it to &lt;code&gt;defmacro&lt;/code&gt; so tools like SLIME and &lt;code&gt;describe&lt;/code&gt; can display it. But repeating it as a parameter is ugly; it would be better to get the &lt;code&gt;original&lt;/code&gt;'s argument list automatically. There's no standard way to do this, but every implementation supports it; if we have a portability wrapper like &lt;code&gt;swank-backend:arglist&lt;/code&gt; (or some non-Swank-dependent equivalent), we can do away with the explicit argument list:

&lt;pre&gt;&lt;code&gt;(defmacro &lt;b&gt;defanaphoric&lt;/b&gt; (name original &amp;amp;key settable)
  "Define NAME as a macro like ORIGINAL, but binding IT to the result of the first argument.
If SETTABLE is true, IT will be a symbol-macro which can be set with SETF."
  (let ((whole (gensym "WHOLE"))
        (arglist (swank-backend:arglist original)))
    `(defmacro ,name (&amp;amp;whole ,whole ,@arglist)
       ,(format nil "Like ~S, except binds the result of ~S to IT (via ~S) for the scope of the ~A.~A"
          original
          (car arglist)
          (if settable 'let 'symbol-macrolet)
          (if (and (cdr arglist) (member (cadr arglist) '(&amp;amp;body &amp;amp;rest)))
       (caddr arglist)
       "body")
          (if settable " IT can be set with SETF." ""))
       ,@(mapcan (lambda (a) (unless (member a lambda-list-keywords)
                               `((declare (ignore ,a)))))
                 arglist)
       `(,',(if settable 'symbolic 'anaphoric) ,',original ,@(cdr ,whole)))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes the definitions of anaphoric macros transparently simple:

&lt;pre&gt;&lt;code&gt;(defanaphoric awhen when)
(defanaphoric swhen when :settable t)
(defanaphoric acase case)
(defanaphoric aetypecase etypecase)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This might be useful for simplifying Anaphora, or even as a tool to expose to its users, but it's not much good as an answer to Vladimir's request for arguments for and against macros &amp;mdash; macro-defining macros do not look useful to anyone who doesn't already think macros are useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-7130047376399395854?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/j661U3WHdGA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/7130047376399395854/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=7130047376399395854" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7130047376399395854?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7130047376399395854?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/j661U3WHdGA/anaphoric-macro-defining-macro.html" title="An anaphoric-macro-defining macro" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/08/anaphoric-macro-defining-macro.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUGRH85fip7ImA9WhZQFEk.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-4874006895361435003</id><published>2011-04-22T03:18:00.005Z</published><updated>2011-04-22T04:23:45.126Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T04:23:45.126Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="psychology" /><title>Quantitative results are rewarding</title><content type="html">&lt;p&gt;Recently I spent some time profiling and optimizing a certain program, and tripled its performance. My reaction was predictable. &lt;i&gt;I am awesome&lt;/i&gt;, I thought. &lt;i&gt;I made this three times as good as it was before. I'm three times as good a programmer as whoever wrote that slow code.&lt;/i&gt; (Even though "whoever wrote that slow code" was me.)

&lt;p&gt;The results of optimization are easy to quantify: not just &lt;i&gt;faster&lt;/i&gt;, but &lt;i&gt;three times as fast&lt;/i&gt;. I suspect this accounts for some of the lure of optimization. Comparing performance numbers provides an obvious indication of improvement, and exaggerates its value, so even a modest optimization feels like a triumph. Adding a new feature usually has much less emotional reward, especially if it's not technically impressive or immediately useful. Fixing a bug may bring feelings of disgust at the bug, and guilt (if I created it) or contempt (if &lt;del&gt;some other idiot&lt;/del&gt; someone else did), but it seldom feels like much of an accomplishment. Optimization, though, feels good, because it's measurable and therefore &lt;em&gt;obviously&lt;/em&gt; valuable (even when it's not).

&lt;p&gt;I also enjoy cleaning up code, for the same reason: if I make something 50 lines shorter, that tells me &lt;em&gt;how much&lt;/em&gt; I've accomplished, so I have something to feel good about. Predictably, I feel better about making code shorter than about merely making it more readable, because readability doesn't come with numerical confirmation.

&lt;p&gt;If this effect is real, it would be valuable to have a similar quantification of bugs and features, to make improvements emotionally rewarding. An automated test framework can provide this by conspicuously reporting the &lt;em&gt;number&lt;/em&gt; of tests passed, and perhaps the change from previous versions. (It's probably best to report the number passed, not the number failed, so writing more tests makes the number better rather than worse.) If you've used a test framework with this feature, have you noticed any effect on your motivation to fix bugs?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-4874006895361435003?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/UDiEuJDesqk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/4874006895361435003/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=4874006895361435003" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4874006895361435003?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4874006895361435003?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/UDiEuJDesqk/quantitative-results-are-rewarding.html" title="Quantitative results are rewarding" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/04/quantitative-results-are-rewarding.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cNSH07eyp7ImA9WhZSGEg.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-2878489710668662855</id><published>2011-04-03T15:04:00.005Z</published><updated>2011-04-03T18:24:59.303Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-03T18:24:59.303Z</app:edited><title>Irregular indentation reflects semantic structure</title><content type="html">&lt;p&gt;There are well-known rules for indenting Lisp code, but it's sometimes convenient to break the rules when the code has semantic structure not reflected in the S-expressions. This sometimes happens when there are alternating sequences, as in some versions of &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;cond&lt;/code&gt; and &lt;code&gt;setf&lt;/code&gt;. It's also common to leave forms unindented when they're supposed to be top-level but something has been wrapped around them anyway, such as &lt;code&gt;eval-when&lt;/code&gt;, or the &lt;code&gt;library&lt;/code&gt; or &lt;code&gt;unit&lt;/code&gt; forms required in some Scheme module systems. In either case, the indentation reflects the structure a human reader understands the program by, rather than the structure of its S-expressions.

&lt;p&gt;JRM recently posted &lt;a href='http://funcall.blogspot.com/2011/03/erf.html'&gt;a particularly extreme example&lt;/a&gt; of irregular indentation:

&lt;pre&gt;&lt;code&gt;(define (polynomial-erf z)
  ;; Numerical Recipies 6.2
  ;; fractional error &amp;lt; 1.2e-7
  (let* ((t (/ 1.0 (+ 1.0 (* .5 (abs z)))))
         (ans (- 1.0 (* t
                        (exp (+ (- (* z z))
                                &lt;b&gt;(+ -1.26551223
                                   (* t (+ 1.00002368
                                   (* t (+ .37409196
                                   (* t (+ .09678418
                                   (* t (+ -.18628806 
                                   (* t (+ .27886807 
                                   (* t (+ -1.13520398
                                   (* t (+ 1.48851587
                                   (* t (+ -.82215223 
                                   (* t .17087277))))))))))))))))))&lt;/b&gt;))))))
    (if (&amp;gt;= z 0) ans (- ans))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the big polynomial written in sequential multiply-and-add style. It has two semantic structures: it's a tree of arithmetic expressions, but it's also a sequence of polynomial terms. The latter interpretation is more useful, and the indentation reflects this: it's intended to be read as a sequence, so it's indented as a sequence. If it were indented normally, according to its tree structure, its semantic sequentiality would be less obvious, not to mention it would be impractically wide:

&lt;pre&gt;&lt;code&gt;(+ -1.26551223
   (* t (+ 1.00002368
           (* t (+ .37409196
                   (* t (+ .09678418
                           (* t (+ -.18628806 
                                   (* t (+ .27886807 
                                           (* t (+ -1.13520398
                                                   (* t (+ 1.48851587
                                                           (* t (+ -.82215223 
                                                                   (* t .17087277))))))))))))))))))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Either way, that's an imposing pile of right-parens. (You could avoid this with a simple &lt;code&gt;polynomial&lt;/code&gt; function or macro, but it's not worth the trouble for one polynomial.)

&lt;p&gt;One of the reasons expression-based languages are so convenient is that their program structure reflects the semantic structure humans understand them by. Irregular indentation is a reminder that they don't always do so perfectly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-2878489710668662855?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/r0hcYlYSl3M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/2878489710668662855/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=2878489710668662855" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2878489710668662855?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2878489710668662855?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/r0hcYlYSl3M/irregular-indentation-reflects-semantic.html" title="Irregular indentation reflects semantic structure" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/04/irregular-indentation-reflects-semantic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMNSHk-eip7ImA9WhZSGU4.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-1566152306589934333</id><published>2011-04-03T14:10:00.006Z</published><updated>2011-04-04T15:21:39.752Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T15:21:39.752Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="common-lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="clojure" /><title>Clojure is almost as big as Common Lisp</title><content type="html">&lt;p&gt;How big is Clojure's standard library? Never mind the Java library, or even &lt;code&gt;clojure.contrib&lt;/code&gt;; how much is built in to clojure.jar?

&lt;p&gt;One way to answer this is to count definitions, in the form of public &lt;code&gt;Var&lt;/code&gt;s:

&lt;pre&gt;&lt;code&gt;(defn &lt;b&gt;ns-size&lt;/b&gt; "How many public Vars does this namespace have?" [name]
  (&lt;a href='http://clojuredocs.org/v/1928'&gt;require&lt;/a&gt; name)
  (count (&lt;a href='http://clojuredocs.org/v/1561'&gt;ns-publics&lt;/a&gt; (&lt;a href='http://clojuredocs.org/v/1899'&gt;find-ns&lt;/a&gt; name))))

(def builtins '(clojure.core clojure.core.protocols clojure.data
                clojure.inspector clojure.java.browse clojure.java.browse-ui
                clojure.java.io clojure.java.javadoc clojure.java.shell
                clojure.main clojure.pprint ;clojure.parallel &lt;small&gt;;deprecated&lt;/small&gt;
                clojure.reflect clojure.repl clojure.set clojure.stacktrace
                clojure.string clojure.template clojure.test clojure.test.junit
                clojure.test.tap clojure.walk clojure.xml clojure.zip))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Clojure 1.3.0a6:

&lt;pre&gt;user=&amp;gt; &lt;code&gt;(ns-size 'clojure.core)&lt;/code&gt;
563
user=&amp;gt; &lt;code&gt;(reduce + (map ns-size builtins))&lt;/code&gt;
826&lt;/pre&gt;

&lt;p&gt;So Clojure is already approaching Common Lisp's 1064 definitions&lt;sup&gt;1&lt;/sup&gt;. This measure probably overstates Clojure's size relative to CL, because it compares all of Clojure to only the &lt;em&gt;standard&lt;/em&gt; parts of Common Lisp, but every CL implementation includes other libraries in addition to the standard. CL also tends to pack more features into each definition, through keyword arguments and complex embedded languages like &lt;code&gt;format&lt;/code&gt; and &lt;code&gt;loop&lt;/code&gt;, so counting definitions understates its size. On the other hand, many CL features are of dubious value, so Clojure may already have surpassed it in &lt;em&gt;useful&lt;/em&gt; library.

&lt;p&gt;If it hasn't, it will soon, because Clojure's library is still growing. The &lt;code&gt;Var&lt;/code&gt; count has increased by 50% in the last two years:

&lt;table&gt;&lt;tr&gt;&lt;th&gt;Version&lt;th&gt;Date&lt;th&gt;&lt;code&gt;clojure.core&lt;/code&gt;&lt;th&gt;&lt;code&gt;clojure.*&lt;/code&gt;
&lt;tr&gt;&lt;td&gt;1.0.0&lt;td&gt;May 2009&lt;td&gt;458&lt;td&gt;543
&lt;tr&gt;&lt;td&gt;1.1.0&lt;td&gt;Dec 2009&lt;td&gt;502&lt;td&gt;576
&lt;tr&gt;&lt;td&gt;1.2.0&lt;td&gt;Aug 2010&lt;td&gt;546&lt;td&gt;782
&lt;tr&gt;&lt;td&gt;1.3.0a6&lt;td&gt;Mar 2011&lt;td&gt;563&lt;td&gt;826
&lt;/table&gt;

&lt;p&gt;At this rate, Clojure 1.6 will have a bigger standard library than Common Lisp. (The timing depends on how quickly parts of &lt;code&gt;clojure.contrib&lt;/code&gt; get assimilated into &lt;code&gt;clojure.core&lt;/code&gt;.) I suppose when that happens, Common Lisp will still be perceived as huge and bloated, and Clojure as relatively small and clean. Any perceived complexity in Clojure will be blamed on Java, even though Java interoperation accounts for only a tiny part of Clojure's library. Scheme will still be considered small and elegant, no matter how big its libraries (or its core semantics) get. (R5RS Scheme has 196 definitions, and R6RS about 170, or 680 with its standard libraries. Racket is much bigger.) Traditional beliefs about language sizes are not very sensitive to data.

&lt;p class=edit&gt;Update: riffraff on HN &lt;a href='http://news.ycombinator.com/item?id=2405758'&gt;counts Python's definitions&lt;/a&gt;: &lt;code&gt;len(__builtins__.__dict__.values())&lt;/code&gt; ⇒ 143 definitions in the default namespace, plus &lt;code&gt;len(set(chain( *[dir(o) for o in __builtins__.__dict__.values()])))&lt;/code&gt; ⇒ 250 method names, so about 400 built-in definitions. There are also over 200 other modules in the standard distribution, so its full standard library is much bigger — the first 24 modules have &lt;code&gt;sum([len(dir(__import__(n))) - 4 for n in "string re struct difflib StringIO cStringIO textwrap codecs unicodedata stringprep fpformat datetime calendar collections heapq bisect array sets sched mutex weakref UserDict UserList UserString".split()])&lt;/code&gt; ⇒ 476 definitions, so the total is something like 5000. "Batteries included" indeed.

&lt;p&gt;However, standard library size is less important than it used to be. When every language has an automatic library fetcher like Leiningen or &lt;a href='http://www.quicklisp.org/beta/'&gt;Quicklisp&lt;/a&gt; or &lt;a href='http://docs.racket-lang.org/planet/Using_PLaneT.html'&gt;PLaneT&lt;/a&gt;, built-in libraries aren't much more readily available than other well-known libraries. The main obstacle to library use is no longer finding suitable libraries, or downloading them, but learning to use them.

&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; Common Lisp has 978 symbols, but symbols ≠ definitions: some symbols have definitions in more than one namespace, and some have no definition. Common Lisp has 752 definitions in the function namespace (636 functions, 91 macros, and 25 special forms), 116 variables, 85 classes, 66 &lt;code&gt;setf&lt;/code&gt; functions, and 45(?) type specifiers, for a total of 1064 definitions. There are about 30 symbols without definitions: &lt;code&gt;declare&lt;/code&gt; and its declarations and optimization qualities, a few locally bound symbols like &lt;code&gt;call-next-method&lt;/code&gt;, and eight lambda-list keywords. There's also plenty of room for disagreement about what counts as a definition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-1566152306589934333?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/UqKaFcwzbQ4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/1566152306589934333/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=1566152306589934333" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1566152306589934333?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1566152306589934333?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/UqKaFcwzbQ4/clojure-is-almost-as-big-as-common-lisp.html" title="Clojure is almost as big as Common Lisp" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>3</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/04/clojure-is-almost-as-big-as-common-lisp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08ERXg_fyp7ImA9WhZSEkU.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-2793781740793979482</id><published>2011-03-28T02:41:00.003Z</published><updated>2011-03-28T03:10:04.647Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-28T03:10:04.647Z</app:edited><title>Good and bad syntax-coloring</title><content type="html">&lt;p&gt;David Nolen &lt;a href='http://dosync.posterous.com/a-preview'&gt;pretty-printed some Clojure&lt;/a&gt; with &lt;a href='http://evalwhen.com/slatex/'&gt;SLaTeX&lt;/a&gt;. The result, as usual for SLaTeX, is typographically impressive but rather painful to read. The problem is that SLaTeX has horrible defaults for syntax coloring. It shows most code, including this Clojure, in only two faces:

&lt;ul&gt;
  &lt;li&gt;Special form names are in bold.
  &lt;li&gt;Other names are in italics.
&lt;/ul&gt;

&lt;p&gt;Italics are harder to read than plain ("Roman") text, because they're less familiar, so using them for most symbols hurts readability. (SLaTeX also uses proportional fonts; I'm not sure whether that helps or hurts.) But there's a much bigger problem: misplaced emphasis.

&lt;p&gt;&lt;b&gt;Bold&lt;/b&gt;, like bright colors, draws attention. This is very useful: it can help the reader quickly find important bits of code they might otherwise overlook. But special forms, however semantically special, are not such important bits. When reading a program, occurrences of &lt;code&gt;lambda&lt;/code&gt; or &lt;code&gt;begin&lt;/code&gt; are hardly ever the parts that deserve notice. They do deserve some subtle syntax-coloring, but printing them in bold makes code considerably less readable, because it directs attention to the irrelevant.

&lt;p&gt;It's much more useful to emphasize binding occurrences, especially top-level ones. One of the most common operations when reading code is to look for a definition, and showing the names prominently makes it easier to find the right one. Emacs, as usual, gets this right: for most languages it shows top-level binding occurrences in bright colors, which makes them easy to find.

&lt;p&gt;Clojure-mode also colors names in &lt;code&gt;clojure.core&lt;/code&gt;. I've found this quite helpful for learning the language, because it provides an edit-time hint of whether I've guessed the right name. I think it's also a small help when reading code, because the color used is low-contrast, so it makes calls to standard-library functions &lt;em&gt;less&lt;/em&gt; conspicuous — which is good, because they're usually less deserving of attention than calls to my own functions. It may also be helpful when reading an unfamiliar language, because it tells the reader when to guess what a name means or look it up with &lt;code&gt;doc&lt;/code&gt; or &lt;a href='http://clojuredocs.org'&gt;clojuredocs&lt;/a&gt; rather than look for its definition elsewhere in the program.

&lt;p&gt;It's easy to change SLaTeX's fonts to something less annoying:

&lt;pre&gt;&lt;code&gt;\def\keywordfont#1{{\it#1\/}}
\def\constantfont#1{{\rm#1}}
\def\variablefont#1{{\rm#1}}
\let\datafont\constantfont&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you don't mind abusing &lt;code&gt;\setkeyword&lt;/code&gt;, you can also make it recognize names from the standard library, by pretending they're special forms:

&lt;pre&gt;&lt;code&gt;\setkeyword{sorted-map read-line re-pattern keyword? ClassVisitor
  asm-type VecSeq print-defrecord val IVecImpl ProcessBuilder chunked-seq?
  Enum find-protocol-impl SuppressWarnings
  %and so on for the rest of (keys (ns-map (find-ns 'clojure.core)))
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately SLaTeX doesn't support this directly, nor does it support recognizing top-level binding occurrences, but neither would be hard to add; it already recognizes similar things like macro-defining forms and quoted literals. If you're writing a pretty-printer (or a syntax-coloring editor), I encourage you to add these two features, because they're much more useful than highlighting special forms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-2793781740793979482?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/W-jx7QCX5nI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/2793781740793979482/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=2793781740793979482" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2793781740793979482?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/2793781740793979482?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/W-jx7QCX5nI/good-and-bad-syntax-coloring.html" title="Good and bad syntax-coloring" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/03/good-and-bad-syntax-coloring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYEQHgyfip7ImA9WhZbFUw.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-8389813109262130285</id><published>2011-03-20T05:05:00.004Z</published><updated>2011-06-19T19:01:41.696Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-19T19:01:41.696Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="syntax" /><title>Another problem with non-ASCII operators</title><content type="html">&lt;p&gt;Unicode offers many symbols that make beautiful names for operators, but in addition to the usual problems (they're hard to identify with their ASCII equivalents, and almost impossible to type, and they become unintelligible when encodings get confused) there's a rendering problem: rare characters are often displayed poorly, because most fonts don't cover them very well.

&lt;p&gt;I encountered this recently in &lt;a href='http://conal.net/blog/posts/a-trie-for-length-typed-vectors/'&gt;one of Conal Elliott's posts&lt;/a&gt; which uses the character &lt;code&gt;↛&lt;/code&gt;. The font I saw it in didn't contain that character, so it was rendered in some other font, but scaled wrong, so it was illegibly small. I had to triple the font size to figure out what it was supposed to be a slashed arrow, not a squashed gnat. Amusingly, a change note on that post says this character was a replacement for another that was even more badly rendered:

&lt;blockquote&gt;2011-01-31: Switched trie notation to "&lt;code&gt;k ↛ v&lt;/code&gt;" to avoid missing character on iPad.&lt;/blockquote&gt;

&lt;p&gt;Even fonts that have a character may not render it well. The composition operator &lt;code&gt;∘&lt;/code&gt; (which also appears in that post) is one of the best candidates for a non-ASCII name, because it's so well known and has no good ASCII equivalent. Unfortunately, all the fixed-pitch fonts on my machine display it too high and with too much space on the right, making it look more like the degree sign ° than composition. Making a font with good glyphs for 95 ASCII characters is not prohibitively difficult, but making one for a few thousand Unicode characters is apparently a challenge even for the professionals.

&lt;p&gt;Unfamiliar operators like the trie constructor aren't very compelling candidates for symbolic names anyway, so it's not much of a loss to use ASCII for them, but it's sad that we still can't use the familiar symbols for composition and set membership. (Although composition may be moot — I tend to write it as &lt;code&gt;.&lt;/code&gt; even on paper, because of Haskell.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-8389813109262130285?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/yGvEYnpRD1Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/8389813109262130285/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=8389813109262130285" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8389813109262130285?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/8389813109262130285?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/yGvEYnpRD1Q/another-problem-with-non-ascii.html" title="Another problem with non-ASCII operators" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/03/another-problem-with-non-ascii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcBQ3c-eyp7ImA9WhZTFUo.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-7824086343763186591</id><published>2011-03-19T21:58:00.003Z</published><updated>2011-03-19T22:17:32.953Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-19T22:17:32.953Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="syntax" /><title>Quote should not terminate tokens</title><content type="html">&lt;p&gt;Haskell allows the single-quote character in identifiers, so you can use variable names with primes, like &lt;code&gt;x'&lt;/code&gt;. This is so convenient (especially for naming "revised" versions of variables, which seems to happen a lot when assignment isn't available) that I've been missing it in Clojure recently.

&lt;p&gt;There's no reason lisps can't have this. Common Lisp supports "nonterminating" macro characters — characters that have special meaning when they appear on their own, but not when they appear in the middle of a token. Like many of CL's features (generic functions, anyone?) this isn't used much in the standard library; by default there's only one nonterminating macro character, &lt;code&gt;#&lt;/code&gt;, and that's only for historical reasons (compatibility with Maclisp, I think). But it's easy to make new ones, which solves the &lt;code&gt;x'&lt;/code&gt; problem in one line:

&lt;pre&gt;CL-USER&amp;gt; &lt;code&gt;(set-macro-character #\' (get-macro-character #\') t)&lt;/code&gt;
T
CL-USER&amp;gt; &lt;code&gt;'(x x' y y')&lt;/code&gt;
(X |X'| Y |Y'|)&lt;/pre&gt;

&lt;p&gt;(&lt;code&gt;T&lt;/code&gt; as the third argument of &lt;code&gt;set-macro-character&lt;/code&gt; means "nonterminating".) Note that &lt;code&gt;quote&lt;/code&gt; still works. Symbols with primes print funny, because the printer doesn't realize nonterminating macro characters don't have to be escaped, but they work fine; you can name variables with primes to your heart's content.

&lt;p&gt;This should be the default in any new lisp: &lt;code&gt;'&lt;/code&gt; should not terminate tokens. Neither should any macro character except &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;}&lt;/code&gt; and &lt;code&gt;;&lt;/code&gt;, really — termination only matters when you leave out spaces between tokens, and who does that?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-7824086343763186591?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/HXMG-N5LMco" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/7824086343763186591/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=7824086343763186591" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7824086343763186591?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7824086343763186591?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/HXMG-N5LMco/quote-should-not-terminate-tokens.html" title="Quote should not terminate tokens" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>6</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/03/quote-should-not-terminate-tokens.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8GRH0ycCp7ImA9Wx9aEU8.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-6990751263417537143</id><published>2011-03-03T03:18:00.002Z</published><updated>2011-03-03T03:27:05.398Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-03T03:27:05.398Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="names" /><category scheme="http://www.blogger.com/atom/ns#" term="history" /><title>How typep got its name</title><content type="html">&lt;p&gt;Paul McJones has a large &lt;a href='http://www.softwarepreservation.org/projects/LISP/'&gt;collection of old Lisp manuals&lt;/a&gt;, which shed a lot of light on historical questions like how unary &lt;code&gt;typep&lt;/code&gt; got its irregular name. The earliest reference I've found is in a &lt;a href='http://www.saildart.org/prog/DOC/_UP_DOC/.html/001120?1119,310400'&gt;1973 Maclisp manual&lt;/a&gt;, which describes it thus, immediately after the other type predicates:

&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;typep&lt;/code&gt;  SUBR 1 arg
  &lt;code&gt;typep&lt;/code&gt; is a general type-predicate.  It returns an atomic symbol
  describing the type of its argument, chosen from the list
    &lt;code&gt;(fixnum flonum bignum list symbol string random)&lt;/code&gt;
  &lt;code&gt;symbol&lt;/code&gt; means atomic symbol.  &lt;code&gt;Random&lt;/code&gt; is for all types that don't
  fit in any other category.&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;A "general type-predicate"? This wording suggests &lt;code&gt;typep&lt;/code&gt; got its name because it was seen as a generalization of the regular type predicates. This makes sense: as Maclisp acquired an increasingly unwieldy number of type predicates, its maintainers would want to merge them into one operation, and would probably think of that operation as "a general type-predicate", even though it's not actually a predicate.

&lt;p&gt;(That &lt;code&gt;random&lt;/code&gt; type is probably just an implementation detail showing through, but it's still adorable. Rudimentary type systems are to languages what tiny clumsy paws are to kittens.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-6990751263417537143?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/tNiXlIL1eQ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/6990751263417537143/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=6990751263417537143" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6990751263417537143?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6990751263417537143?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/tNiXlIL1eQ8/how-typep-got-its-name.html" title="How typep got its name" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/03/how-typep-got-its-name.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YBRn84fyp7ImA9Wx9bGU0.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-6156310101299053754</id><published>2011-02-28T14:57:00.001Z</published><updated>2011-02-28T14:59:17.137Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-28T14:59:17.137Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="names" /><title>The curious attraction of one-argument typep</title><content type="html">&lt;p&gt;&lt;a href='http://www.maclisp.info/pitmanual/typep.html#2.1.2'&gt;In Maclisp&lt;/a&gt;, the function &lt;code&gt;typep&lt;/code&gt; takes one argument and returns its type in the form of a symbol. This is a fundamental operation, and it's egregiously misnamed, as it's not a predicate. (The &lt;code&gt;-p&lt;/code&gt; convention is much older than &lt;code&gt;typep&lt;/code&gt;, so the name was misleading even in Maclisp.) Lisp Machine Lisp preserved it for compatibility, but Common Lisp fixes the confusion by calling it &lt;code&gt;type-of&lt;/code&gt; and using &lt;code&gt;typep&lt;/code&gt; only for the two-argument type membership predicate.

&lt;p&gt;I've never used Maclisp, nor any dialect with one-argument &lt;code&gt;typep&lt;/code&gt;, so this misnaming should interest me only as historical trivia. But I find it oddly compelling. When I read &lt;code&gt;typep&lt;/code&gt;, I think of the unary version first, and only remember the type membership test when context reminds me. When I refer to the "what type is this?" operation without having a specific language in mind, I tend to carelessly call it &lt;code&gt;typep&lt;/code&gt;.

&lt;p&gt;Why? I suspect it's because the most obvious name, &lt;code&gt;type&lt;/code&gt;, is too bare &amp;mdash; it sounds like it might collide with something else, although it doesn't in either Maclisp or Common Lisp &amp;mdash; so I look for an affix to distinguish it. The &lt;code&gt;-of&lt;/code&gt; in &lt;code&gt;type-of&lt;/code&gt; works, but it's meaningless and irregular, and sounds wrong &amp;mdash; more like function application than part of a name. &lt;code&gt;-p&lt;/code&gt; is semantically inappropriate, but it's so common and familiar that it sounds right anyway. So I latch onto it and don't think about the meaning.

&lt;p&gt;I can't be the only one with this problem. I've heard other people call it "one-argument typep", and someone must have made the same mistake decades ago to give &lt;code&gt;typep&lt;/code&gt; its misleading name in the first place. (Was it derived from a predicate? Did its designers have a different interpretation in mind, like "return the type predicate that's true of this value"?) If you are also drawn to this misnomer, or if you know more of its history, I'd like to hear about it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-6156310101299053754?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/Yf55tdb8GNo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/6156310101299053754/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=6156310101299053754" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6156310101299053754?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/6156310101299053754?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/Yf55tdb8GNo/curious-attraction-of-one-argument.html" title="The curious attraction of one-argument typep" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/curious-attraction-of-one-argument.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUASH0yeyp7ImA9Wx9bF0o.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-7252018794850536361</id><published>2011-02-27T03:32:00.003Z</published><updated>2011-02-27T03:44:09.393Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-27T03:44:09.393Z</app:edited><title>Formal comments and stylistic lag</title><content type="html">&lt;p&gt;If you've spent much time programming in industry, you've probably seen comments like this:

&lt;pre&gt;&lt;code&gt;/***************************************
 * Function: Frobnicate
 * Parameters:
 *    frob - a pointer to a Frob
 *    options - a pointer to a FrobnicationOptions
 * Returns:
 *    a boolean: true if frobnication succeeded, false otherwise
 * Description:
 *    Frobnicate the given frob.
 * Logic:
 *    1. Check for valid frob
 *    2. Check for valid options
 *    3. Frobnicate the frob
 *    4. Clean up
 ******************************************/
bool Frobnicate(Frob *frob, FrobnicationOptions *options) {
  &lt;i&gt;...200 lines bearing no resemblance to the "Logic" section above...&lt;/i&gt;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Such formal comments could in principle contain useful information, but in practice they hardly ever do. Usually the name and parameters simply repeat information from the signature, the return value and description are easily guessable, and the Logic section is useless if not completely wrong. I don't think I've ever seen one that includes the sort of information the maintainer is most likely to want. (Does &lt;code&gt;Frobnicate&lt;/code&gt; write to &lt;code&gt;options-&amp;gt;frobnication_output&lt;/code&gt;? What does it return if the &lt;code&gt;options&lt;/code&gt; say to skip this frob? Does it lock &lt;code&gt;frob-&amp;gt;mutex&lt;/code&gt;, or does the caller have to do that?) Most simply waste space and prevent the reader from seeing other code.

&lt;p&gt;Why are useless formal comments so common? I suppose they're often written by people who want to comment their code but don't understand what information is useful, and who, by following the form, can crank out lots of comments they don't realize are useless. But why do some people not only write them but even advocate them, and include them in style guides?

&lt;p&gt;There is a context where these comments make sense: assembly code. When there are no parameter lists or type declarations or even variable names, the information they convey will have to be included somewhere else, because it's vital to maintenance. When the body of a function consists of many pages of inscrutably low-level instructions, an introductory explanation of the logic can be a big help (although I still prefer having it sprinkled among the code, where it helps with navigation and is more likely to be kept up to date.) So prescriptions to include these things in comments are not completely out of the blue. They're based on what made sense, decades ago, for languages that couldn't express this information in any other way. Naturally, they've become entrenched in some programmers' concepts of good style, and are applied even in languages where they make no sense.

&lt;p&gt;I wonder how many of our widely accepted stylistic rules are similarly out of date or misapplied. The &lt;a href='http://www.joelonsoftware.com/articles/Wrong.html'&gt;widespread misuse of Hungarian notation&lt;/a&gt; qualifies, but that's no longer popular. There are a lot of prescriptions for object-oriented style that make no sense in functional languages, but they're seldom applied there. There are some language-specific archaisms, like writing &lt;code&gt;typedef struct Foo_ { ... } Foo;&lt;/code&gt; in C++, but I don't think that's actively promoted except for code that has to also be valid as C.

&lt;p&gt;What stylistic prescriptions are still widely accepted today, even where they don't make sense?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-7252018794850536361?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/bjDZ-5PvJWM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/7252018794850536361/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=7252018794850536361" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7252018794850536361?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7252018794850536361?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/bjDZ-5PvJWM/formal-comments-and-stylistic-lag.html" title="Formal comments and stylistic lag" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/formal-comments-and-stylistic-lag.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcCQnk6cSp7ImA9Wx9UGU8.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-1224395087040428206</id><published>2011-02-17T07:03:00.003Z</published><updated>2011-02-17T07:34:23.719Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-17T07:34:23.719Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="history" /><title>Japanese Lisp, Forth, and historical contingency</title><content type="html">&lt;p&gt;Yusuke Shinyama speculates: &lt;a href='http://lispnyc.org/blog/euske/what-if-lisp-was-invented-by-the-japanese'&gt;what would Lisp look like&lt;/a&gt; if it had been invented by speakers of a consistently postfix language like Japanese? Might it be written postfix instead of prefix?

&lt;p&gt;Maybe so. But this is superficial. The &lt;code&gt;car&lt;/code&gt; of a Lisp form is special because it's the &lt;em&gt;head&lt;/em&gt;, not because it's &lt;em&gt;first&lt;/em&gt;; as long as there are &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt; operators, it makes no difference whether the head is stored first or last or even in the middle. So while a postfix Lisp &lt;em&gt;looks&lt;/em&gt; different, this is only a superficial matter of syntax; Lisp would work the same way if it had been invented in Japan.

&lt;p&gt;Forth, though, might be dramatically affected &amp;mdash; not in nature but in timing. Despite its simplicity, Forth appeared rather late: it was developed &lt;a href='http://www.colorforth.com/HOPL.html'&gt;in the 1960s&lt;/a&gt; and not publicized until 1970, which was too late to become part of the cultural foundation of computing. I suspect this was an anomaly; Forth is so simple that it could easily have been discovered earlier, had anyone bothered to explore postfix notation. Speakers of a postfix natural language have an obvious example to encourage them. (Postfix mathematical notation would be an even stronger encouragement. IIUC &lt;a href='http://en.wiktionary.org/wiki/%E6%8E%9B%E3%81%91%E3%82%8B'&gt;Japanese arithmetic words&lt;/a&gt; are infix, so a Japanese-inspired notation would also be infix; postfix arithmetic could arise more naturally in a natlang where arithmetic operators are postpositions, and postpositional phrases follow their head noun, but this is not a common combination.)

&lt;p&gt;If Forth had been known by the mid-1950s, it could have outcompeted Fortran to become the canonical high-level language. This would have exerted significant pressure on hardware: machines would be designed to run Forth, much as they're designed to run C today, so there would be a lot of stack machines. Since Forth makes such a good assembly language for such machines, there would be less pressure to develop other high-level languages. Programmers accustomed to its simplicity and flexibility and convenience would see all proposed alternatives as unusable and crippled and insanely complex, so other language families could go unexplored. Forth and its descendants might rule computing unchallenged for decades, until some long-delayed development made tree languages competitive.

&lt;p&gt;History could be different. Lisp, Fortran, Algol &amp;mdash; all the great old language families &amp;mdash; might not exist, if the pioneers of computing had spoken a head-last natural language and found Forth first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-1224395087040428206?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/QUKwgMVCUMw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/1224395087040428206/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=1224395087040428206" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1224395087040428206?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1224395087040428206?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/QUKwgMVCUMw/japanese-lisp-forth-and-historical.html" title="Japanese Lisp, Forth, and historical contingency" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>4</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/japanese-lisp-forth-and-historical.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIFRXwzeCp7ImA9WhZSEU0.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-5332894990306449440</id><published>2011-02-13T06:19:00.004Z</published><updated>2011-03-26T00:48:34.280Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-26T00:48:34.280Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="syntax" /><title>Infixifiers</title><content type="html">&lt;p&gt;Haskell allows using any function as an infix operator, without declaring it &lt;code&gt;infix&lt;/code&gt; or giving it a nonalphanumeric name: &lt;code&gt;x `mod` 3&lt;/code&gt; is the same as &lt;code&gt;mod x 3&lt;/code&gt;, for any &lt;code&gt;mod&lt;/code&gt;. I used to think this was a silly extravagance of syntax, but I've come to like it, and to use it frequently in pseudocode. Like the &lt;a href='http://arcanesentiment.blogspot.com/2010/09/pipe-for-functions.html'&gt;pipe operator&lt;/a&gt;, it lets me write operations in a more natural order, and this is important enough to be worth a little syntactic complexity. With a suitably low precedence, it can also save a few parentheses, which is convenient, especially when writing code on paper, where balancing parentheses is hard.

&lt;p&gt;The backquotes still seem odd to me, probably because I confuse them with the output-of-a-command operator in the Bourne shell and Perl. I currently prefer a colon suffix: &lt;code&gt;x mod: 3&lt;/code&gt;, like Smalltalk. (However, I also sometimes use that for keyword arguments, as I prefer &lt;code&gt;sort xs key: cost&lt;/code&gt; to &lt;code&gt;sort xs :key cost&lt;/code&gt;.)

&lt;p&gt;Scala almost does this without requiring an explicit infixifier at all, as it uses mere juxtaposition to mean method call: &lt;code&gt;x mod 3&lt;/code&gt; is &lt;code&gt;x.mod(3)&lt;/code&gt; (which happens not to work, since there is no &lt;code&gt;Integer.mod&lt;/code&gt;). However, this doesn't work for functions in general, as Scala distinguishes them from methods. And of course it conflicts with using juxtaposition as ordinary prefix function call, which is a far more important and more general (because it allows arbitrary numbers of arguments) construct than infix.

&lt;p class=edit&gt;Update 25 March: &lt;a href='http://cran.r-project.org/doc/manuals/R-lang.html#Special-operators'&gt;R also has an infixifier&lt;/a&gt;: &lt;code&gt;a %f% b&lt;/code&gt; is &lt;code&gt;f(a, b)&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-5332894990306449440?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/0U2Sf0HqcLc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/5332894990306449440/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=5332894990306449440" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/5332894990306449440?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/5332894990306449440?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/0U2Sf0HqcLc/infixifiers.html" title="Infixifiers" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/infixifiers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QNSX4zfSp7ImA9Wx9VGE0.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-922565454606207843</id><published>2011-02-04T06:13:00.003Z</published><updated>2011-02-04T06:36:38.085Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-04T06:36:38.085Z</app:edited><title>Alternating cond</title><content type="html">&lt;p&gt;The traditional &lt;code&gt;cond&lt;/code&gt; used in most Lisps, including Scheme and CL, has &lt;code&gt;(test . body)&lt;/code&gt; pairs:

&lt;pre&gt;&lt;code&gt;(define (signum x)
  (cond ((&lt; x 0) -1)
        ((&gt; x 0) 1)
        (else 0)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That has Lots of Irritating Superfluous Parentheses, of a sort that are particularly annoying because they aren't forms. Arc and Clojure avoid this by alternating tests and bodies:

&lt;pre&gt;&lt;code&gt;(defn signum [x]
  (cond (&lt; x 0) -1
        (&gt; x 0) 1
        :else 0))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is nice. But: when test and body no longer fit on one line, it becomes hard to indent, because the list structure doesn't match the semantic structure. Indenting normally, according to list structure, makes the body look like another test:

&lt;pre&gt;&lt;code&gt;(defn fibonacci [n]
  (cond (not (and (integer? n) (&gt;= n 0)))
        (throw (java.lang.IllegalArgumentException.
                (str "fibonacci's argument must be a nonnegative integer: "
                     (pr-str n))))
        (&gt; n 1) (+ (fibonacci (- n 2)) (fibonacci (dec n)))
        :else n))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I tend to read &lt;code&gt;cond&lt;/code&gt;s by vertically scanning the conditions, which doesn't work with this indentation. Indenting according to sense solves this, but makes the body look like a subform of the test:

&lt;pre&gt;&lt;code&gt;(defn fibonacci [n]
  (cond (not (and (integer? n) (&gt;= n 0)))
          (throw (java.lang.IllegalArgumentException.
                  (str "fibonacci's argument must be a nonnegative integer: "
                       (pr-str n))))
        (&gt; n 1) (+ (fibonacci (- n 2)) (fibonacci (dec n)))
        :else n))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...and your editor will probably "fix" it anyway the next time you autoindent.

&lt;p&gt;I'm tempted to rewrite with nested &lt;code&gt;if&lt;/code&gt;s just to avoid the misleading indentation. Which is madness, because &lt;code&gt;cond&lt;/code&gt; is common, and tests and bodies often outgrow one line, and I shouldn't change code structure for formatting reasons. But I don't like being unable to &lt;em&gt;parse&lt;/em&gt; my code. The main value of S-expressions is that structure is obvious, and the structure of alternating &lt;code&gt;cond&lt;/code&gt; isn't.

&lt;p&gt;The same problem can occur in any expression with alternating subforms, such as Clojure's &lt;code&gt;let&lt;/code&gt;, or dictionaries, but in neither case is it as bad as in &lt;code&gt;cond&lt;/code&gt;. Variable names are distinctive, and anyway tend to be short, so &lt;code&gt;let&lt;/code&gt; is rarely formatted with initforms on their own lines. Dictionaries don't usually have large subforms, and often have distinctive &lt;code&gt;:keywords&lt;/code&gt; as their keys, so it's harder to get the keys and values confused. &lt;code&gt;cond&lt;/code&gt; is particularly vulnerable (probably along with friends like &lt;code&gt;typecase&lt;/code&gt;), because it often has large subforms that look alike but don't work alike.

&lt;p&gt;I think I prefer the old &lt;code&gt;cond&lt;/code&gt;, despite the parentheses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-922565454606207843?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/oD7P4Wb8inc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/922565454606207843/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=922565454606207843" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/922565454606207843?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/922565454606207843?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/oD7P4Wb8inc/alternating-cond.html" title="Alternating cond" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>3</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/alternating-cond.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MBQH88fip7ImA9Wx9UFUo.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-1653816550886382085</id><published>2011-02-02T07:58:00.004Z</published><updated>2011-02-13T06:44:11.176Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-13T06:44:11.176Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="clojure" /><title>min-key and max-key should take lists</title><content type="html">&lt;p&gt;Clojure's &lt;code&gt;min-key&lt;/code&gt; and &lt;code&gt;max-key&lt;/code&gt; operators are variants of &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; that minimize or maximize some function of their arguments:

&lt;pre&gt;user=&amp;gt; &lt;code&gt;(max-key count "Find" "the" "longest" "word")&lt;/code&gt;
"longest"&lt;/pre&gt;

&lt;p&gt;I used &lt;code&gt;min-key&lt;/code&gt; a few times recently, and found it awkward every time, because the input arrived in a list, not in several separate expressions. Converting from one to the other is a simple matter of &lt;code&gt;apply&lt;/code&gt;, but the resulting expression is not as clear as it ought to be:

&lt;pre&gt;user=&amp;gt; &lt;code&gt;(apply min-key count
         (clojure.string/split "Find the shortest word" #" "))&lt;/code&gt;
"the"&lt;/pre&gt;

&lt;p&gt;It seems to me that while &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; are almost always used on separate arguments, &lt;code&gt;min-key&lt;/code&gt; and &lt;code&gt;max-key&lt;/code&gt; are much more likely to be used on lists.  (In general, I think high-order functions are much more likely to be used on lists than their first-order relatives.) Googling &lt;a href='http://www.google.com/search?hl=en&amp;q=clojure%20min-key'&gt;clojure min-key&lt;/a&gt; supports this: almost all uses are &lt;code&gt;(apply min-key ...)&lt;/code&gt;, not &lt;code&gt;(min-key ...)&lt;/code&gt; &amp;mdash; and all of the latter seem to be either artificial examples or mistakes. Even the &lt;a href='http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Norvig_Spelling_Corrector'&gt;spelling corrector&lt;/a&gt; which was &lt;a href='http://groups.google.com/group/clojure/browse_thread/thread/60341d980b146855?fwc=1'&gt;the original motivation for adding &lt;code&gt;max-key&lt;/code&gt;&lt;/a&gt; uses it with &lt;code&gt;apply&lt;/code&gt;. So these functions should really be provided in list form (like Arc's &lt;code&gt;most&lt;/code&gt;) rather than separate-argument form.

&lt;p&gt;This is a general problem, though. Any operator that takes an arbitrary number of arguments will probably be used sometimes on lists and sometimes on a few explicit arguments. &lt;code&gt;apply&lt;/code&gt; or &lt;code&gt;reduce&lt;/code&gt; are the obvious ways to transform one into the other, but they're rather disappointing when you're expecting a clear, convenient list function.

&lt;p&gt;(Functions that aren't useful with only one argument (like &lt;code&gt;min-key&lt;/code&gt;) can be overloaded to provide both: &lt;code&gt;(min-key f xs)&lt;/code&gt; could operate on the elements of &lt;code&gt;xs&lt;/code&gt;, while &lt;code&gt;(min-key f a b)&lt;/code&gt; operates on &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;. &lt;span class=edit&gt;This is what Python does.&lt;/span&gt; This is a potentially susprising irregularity, though (&lt;code&gt;(min-key f a)&lt;/code&gt; no longer does what you expect), and it doesn't work for functions that can usefully take one argument. So I don't think it's a good idea.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-1653816550886382085?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/fzLQLqY7i9w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/1653816550886382085/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=1653816550886382085" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1653816550886382085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1653816550886382085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/fzLQLqY7i9w/min-key-and-max-key-should-take-lists.html" title="min-key and max-key should take lists" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/min-key-and-max-key-should-take-lists.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUGQXkzeCp7ImA9Wx9VFUk.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-1313553541093025147</id><published>2011-02-01T08:14:00.001Z</published><updated>2011-02-01T08:17:00.780Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-01T08:17:00.780Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Single-user Unix</title><content type="html">&lt;p&gt;There are a few basic security rules that every Unix newbie is taught, and one of them is: &lt;em&gt;don't log in as root&lt;/em&gt;. So when I went to demonstrate something to a new coworker a while ago, and began by logging in as root, it was an awkward moment.

&lt;p&gt;Was I being reckless? No, I was using Unix as a single-user OS. This was a shared machine, used for testing and little else, and there was no reason to distinguish multiple users; everyone needed root access anyway. Having multiple accounts would have been useless complexity; all we needed was a single-user system. Unix can be one, if you log in as root.

&lt;p&gt;It's not a very &lt;i&gt;good&lt;/i&gt; single-user OS, because most of its safety checks are user-based. When everything runs as root, a minor accident can destroy everything on the machine. But this machine had no valuable data on it &amp;mdash; at worst, we'd be forced to reinstall everything, so we didn't even bother to use a shared non-root account. Safety just wasn't much of an issue. Security wasn't an issue at all; everyone who used that machine needed to know the root password anyway.

&lt;p&gt;This isn't an unusual situation. Most personal computers have only a single user, and many others are shared among several users with no personal data. The user-based security model was developed for timeshared machines, which are now quite rare. Yet our orthodoxy still says user-based security is necessary, and systems without it are not to be taken seriously. Even after decades in which the most important computers have been &lt;em&gt;personal&lt;/em&gt; ones, and even now that single-user smartphones have become the most fashionable platforms, we still judge operating systems by their ability to protect multiple users from each other, not their ability to protect a single user from malicious code. Security, we think, means inter-user security, whether or not that's a good model of the threats we face.

&lt;p&gt;So I feel guilty every time I log in as root. I've been indoctrinated too thoroughly; even though I know it's not really a problem, I feel compelled to make excuses, and to point out that it wasn't me who set up that machine, and I wouldn't have done it that way. But I shouldn't. A single-user system is not necessarily a bad thing, even if it's Unix.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-1313553541093025147?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/RDlum6U2ekU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/1313553541093025147/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=1313553541093025147" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1313553541093025147?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/1313553541093025147?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/RDlum6U2ekU/single-user-unix.html" title="Single-user Unix" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/02/single-user-unix.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBRX4_fip7ImA9Wx9XFU8.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-7974547362945277409</id><published>2011-01-08T20:43:00.003Z</published><updated>2011-01-08T20:55:54.046Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-08T20:55:54.046Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="clojure" /><title>Clojure's unconventional symbols</title><content type="html">&lt;p&gt;If you asked me what a symbol is, I'd probably say something like "a canonicalized string". I might explain why this is useful, or mention that some languages (e.g. Common Lisp) include top-level bindings and plists and packages as part of their symbols, even though those are really a different concept. But I'd take for granted that canonical identity is the central idea. You can't have symbols without &lt;code&gt;intern&lt;/code&gt;, can you?

&lt;p&gt;Clojure does. It creates a new symbol for each occurrence it reads, with no attempt to canonicalize them. Despite its name, &lt;code&gt;&lt;a href='https://github.com/clojure/clojure/blob/9506ca6e7589599c17e165d6583a9c97aa1ca0c0/src/jvm/clojure/lang/Symbol.java'&gt;clojure.lang.Symbol&lt;/a&gt;/intern&lt;/code&gt; always makes a new symbol. It does intern the strings that are their &lt;em&gt;names&lt;/em&gt;, to make comparisons faster, but not the symbols themselves. (There's also &lt;code&gt;clojure.core/intern&lt;/code&gt;, but that creates &lt;code&gt;Var&lt;/code&gt;s — top-level definitions — not &lt;code&gt;Symbol&lt;/code&gt;s.) Observe:

&lt;pre&gt;user=&amp;gt; &lt;code&gt;(identical? 'a 'a)&lt;/code&gt;
false
user=&amp;gt; &lt;code&gt;(= 'a 'a)&lt;/code&gt;
true
user=&amp;gt; &lt;code&gt;(identical? (clojure.lang.Symbol/intern "a") (clojure.lang.Symbol/intern "a"))&lt;/code&gt;
false&lt;/pre&gt;

&lt;p&gt;(&lt;code&gt;identical?&lt;/code&gt; is Java &lt;code&gt;==&lt;/code&gt;, and &lt;code&gt;=&lt;/code&gt; is Java &lt;code&gt;.equals&lt;/code&gt;. The lengths of their names hint at their relative frequency in Clojure.)

&lt;p&gt;Because symbols aren't interned, any code doing symbolic processing must compare them by name rather than identity. This looks at first glance like sloppiness, or a missing feature. Indeed, it does have one harmful effect: &lt;code&gt;gensym&lt;/code&gt; can't quite guarantee that the symbols it creates won't collide with anything (although this risk is largely theoretical, and could be essentially eliminated by putting gensyms in their own namespace). But for the most part, it's harmless. Interning symbols sounds like a basic semantic feature, but it's not. It's only an optimization.

&lt;h3&gt;Digression: namespaces, and references vs. names&lt;/h3&gt;

&lt;p&gt;Symbol comparisons are actually more complicated than &lt;code&gt;=&lt;/code&gt;, because Clojure symbols also &lt;em&gt;optionally&lt;/em&gt; include a namespace. &lt;code&gt;user/a&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; are thus two different symbols &amp;mdash; one with a namespace, one without &amp;mdash; but they name the same variable:

&lt;pre&gt;user=&amp;gt; &lt;code&gt;(= 'user/a 'a)&lt;/code&gt;
false
user=&amp;gt; &lt;code&gt;(def a 1)&lt;/code&gt;
#'user/a
user=&amp;gt; &lt;code&gt;user/a&lt;/code&gt;
1
user=&amp;gt; &lt;code&gt;(def user/a 2)&lt;/code&gt;  ;redefinition!
#'user/a
user=&amp;gt; &lt;code&gt;a&lt;/code&gt;
2&lt;/pre&gt;

&lt;p&gt;This appears to make symbol comparison impossible, since determining what definition a name refers to requires looking at the environment, not just at the symbol. But this is true in any language with lexical scope; including a namespace in the symbol doesn't make it harder. It's only a potential problem for plain old symbol processing, and you probably wouldn't use qualified symbols for that anyway.

&lt;p&gt;What's really going on here is that symbols in Clojure have two roles. In addition to being &lt;dfn&gt;names&lt;/dfn&gt;, they're also used as &lt;dfn&gt;references&lt;/dfn&gt; to names, relative to the current namespace. Clojure uses the same class for both concepts: references may or may not specify a namespace, but names always(?) do. References are resolved to names (by &lt;code&gt;&lt;a href='https://github.com/clojure/clojure/blob/9506ca6e7589599c17e165d6583a9c97aa1ca0c0/src/jvm/clojure/lang/Compiler.java'&gt;clojure.lang.Compiler&lt;/a&gt;/resolveSymbol&lt;/code&gt;), so the first &lt;code&gt;def&lt;/code&gt; above defines a variable called &lt;code&gt;user/a&lt;/code&gt;, not &lt;code&gt;a&lt;/code&gt;. This means names can be compared by &lt;code&gt;=&lt;/code&gt; without worrying further about namespaces or collisions between them (although local bindings can still collide). In a language which resolved references directly to their definitions rather than via names, it would not be necessary to include the namespace in names, and &lt;code&gt;SymbolRef&lt;/code&gt; could be distinct from &lt;code&gt;Symbol&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-7974547362945277409?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/4XINjlNLGN4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/7974547362945277409/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=7974547362945277409" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7974547362945277409?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/7974547362945277409?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/4XINjlNLGN4/clojures-unconventional-symbols.html" title="Clojure's unconventional symbols" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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><feedburner:origLink>http://arcanesentiment.blogspot.com/2011/01/clojures-unconventional-symbols.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUGSXw_fSp7ImA9Wx9QE0Q.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-4091550452700740203</id><published>2010-12-24T03:26:00.003Z</published><updated>2010-12-26T20:43:48.245Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-26T20:43:48.245Z</app:edited><title>Denotational semantics is hard</title><content type="html">&lt;p&gt;&lt;a href='http://conal.net/blog/'&gt;Conal Elliott's blog&lt;/a&gt; makes me feel stupid. This isn't a difficult feat; any math I don't understand will generally do the trick. But usually the feeling is misguided, because the problem is ignorance, not stupidity &amp;mdash; when I don't understand something, it's probably because I don't know the concepts, not because I can't follow the reasoning.

&lt;p&gt;Conal's blog is different. He builds everything out of simple concepts I already know, and explains his reasoning in painstaking, executable detail, and often I still don't get it. After reading a few such posts, I start to think I'm just too stupid to understand. Or, at least, that denotational semantics with partially defined values is hard enough that I can't wing it by knowing the basic concepts and figuring out the rest as I read. (When I put it that way, I don't feel so bad.)

&lt;p&gt;I think part of the problem, beyond simple unfamiliarity, is that Conal's reasoning is mostly algebraic, and I'm not used to relying on that. Whenever I'm uncertain, I fall back on operational reasoning: I work through the computation and check that the results are what I expect. But this only works when I know what to expect. A typical Conal post is a tower of abstraction so high that when I try to check something, I'm not sure what the results ought to be. I have nothing to anchor my operational rope to, so when I lose my grip on the tower, I fall.

&lt;p&gt;Fortunately, Edward Yang has come to the rescue with some helpful background posts on the very tools Conal uses. He walks the reader through &lt;a href='http://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/'&gt;explicit bottoms&lt;/a&gt; and &lt;a href='http://blog.ezyang.com/2010/12/gin-and-monotonic/'&gt;the definedness partial ordering&lt;/a&gt; and &lt;a href='http://blog.ezyang.com/2010/12/getting-a-fix-on-fixpoints/'&gt;fixpoints&lt;/a&gt; and &lt;a href='http://blog.ezyang.com/2010/12/omega-i-m-lubbin-it/'&gt;lubs&lt;/a&gt; in great detail, with plenty of illustrated examples. (I like the hand-drawn diagrams. They look silly at first, but the absence of typesetting constraints probably allows them to be clearer than machine-drawn pictures would be.)  It's all textbook material, and so detailed that it almost seems an insult to the reader's intelligence, but it's a textbook I haven't read, and apparently I deserve the insult. The detail provides valuable practice both at thinking in terms of these concepts and at algebraic reasoning about them, which is just what I needed. Some of Conal's posts are looking a little less mysterious now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-4091550452700740203?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/nt80PENoBBM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/4091550452700740203/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=4091550452700740203" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4091550452700740203?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4091550452700740203?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/nt80PENoBBM/denotational-semantics-is-hard.html" title="Denotational semantics is hard" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>3</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2010/12/denotational-semantics-is-hard.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUDSXY7eyp7ImA9Wx9QEEU.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-4295344906839639596</id><published>2010-12-23T06:31:00.003Z</published><updated>2010-12-23T06:54:38.803Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-23T06:54:38.803Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="function of the day" /><title>Macro of the day: build-list</title><content type="html">&lt;p&gt;Some operations are rare in "real" programs but common in throwaways and toys. One of these is creating lists of random data. Toy programs frequently use random input, simply because it's easier than getting real data. Usually this takes the form of evaluating some &lt;code&gt;(random-thing)&lt;/code&gt; expression over and over and returning a list of the results:

&lt;pre&gt;&lt;code&gt;(map (λ (x) (random-thing)) (range n))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The unused &lt;code&gt;x&lt;/code&gt; here offends me. The randomly generated things usually don't depend on where they end up in the list, so why should the function that generates them receive the index as an argument?

&lt;p&gt;I only find the unused argument annoying if it's in an explicit &lt;code&gt;λ&lt;/code&gt;. Doing the same thing with Clojure's &lt;code&gt;for&lt;/code&gt; doesn't feel nearly as sinful, since it doesn't explicitly say the index is being passed to a function:

&lt;pre&gt;&lt;code&gt;(for [x (range n)] (random-thing))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's acceptably simple. But what I really want to write is something like this:

&lt;pre&gt;&lt;code&gt;(build-list n (random-thing))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...which evaluates &lt;code&gt;(random-thing)&lt;/code&gt; &lt;code&gt;n&lt;/code&gt; times and returns the results as a list. This is a straightforward macro:

&lt;pre&gt;&lt;code&gt;(defmacro &lt;b&gt;build-list&lt;/b&gt;
  "Return a seq of the results of evaluating EXPR N times."
  [n expr]
  `(for [i# (range ~n)] ~expr))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or, in CL (which, even using &lt;code&gt;loop&lt;/code&gt;, doesn't look good in comparison):

&lt;pre&gt;&lt;code&gt;(defmacro &lt;b&gt;build-list&lt;/b&gt; (n body)
  (with-gensyms (i)
    `(loop for ,i from 1 to ,n collect ,body)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href='http://clojuredocs.org/v/2069'&gt;Clojure's built-in &lt;code&gt;repeatedly&lt;/code&gt;&lt;/a&gt; is the functional equivalent of &lt;code&gt;build-list&lt;/code&gt;: it's &lt;code&gt;map&lt;/code&gt; over &lt;code&gt;range&lt;/code&gt;, but without passing the argument. With &lt;code&gt;#&lt;/code&gt; as a one-character λ, this approaches the ideal:

&lt;pre&gt;&lt;code&gt;(repeatedly n #(random-thing))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These tools are simple and frequently useful, especially in the throwaway programs that most benefit from library support, but few standard libraries offer them. Some come close, but can't resist including the index as an argument. Racket, for instance, &lt;a href='http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket/private/base..rkt%29._build-list%29%29' title='Racket's build-list'&gt;has&lt;/a&gt; a &lt;code&gt;build-list&lt;/code&gt; function which is equivalent to &lt;code&gt;map&lt;/code&gt; over a range, but it's barely an improvement for this use:

&lt;pre&gt;&lt;code&gt;(build-list n (λ (x) (random-thing)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I suspect this is because of cultural dissonance. Calling something repeatedly without passing it an argument is obviously useful only if it's not purely functional, and functional programmers tend to be suspicious of that. We (well, except for the Haskellers) accept impurities like randomness, but not so enthusiastically that we're comfortable including additional library functions to help with them. We expect our libraries to do the Right Thing, and some of our trusted heuristics tell us that making lists of random data is not the Right Thing. So, useful or not, we don't really try to make it easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-4295344906839639596?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/uS3ovH98aPo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/4295344906839639596/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=4295344906839639596" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4295344906839639596?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4295344906839639596?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/uS3ovH98aPo/macro-of-day-build-list.html" title="Macro of the day: build-list" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>6</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2010/12/macro-of-day-build-list.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIEQXw-eip7ImA9Wx9UGU8.&quot;"><id>tag:blogger.com,1999:blog-6454006.post-4190873814613344541</id><published>2010-12-15T03:53:00.000Z</published><updated>2011-02-17T07:25:00.252Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-17T07:25:00.252Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="history" /><title>What's so cool about APL?</title><content type="html">&lt;p&gt;Why does APL have such a devoted following, despite its strange appearance? What have its users, since the 1960s, seen in it that made them embrace such an unpopular language?

&lt;p&gt;I'm not one of those fanatical APLers, but I think I understand why. Imagine the year is 1965. All computing is on mainframes, and the only high-level languages you've ever seen are Fortran and Algol-60. And then one day you meet APL, and discover:

&lt;ul&gt;
&lt;li&gt;It has a &lt;b&gt;read-eval-print loop&lt;/b&gt;: you can type expressions in and see the results immediately, without running a compiler. It's a remarkably powerful calculator, in the days before calculators were common. (This may account for its popularity in finance.)
&lt;li&gt;It's mostly &lt;b&gt;functional&lt;/b&gt;: most operations return a result rather than requiring you to specify a destination to modify, so you can easily combine many operations in one expression.
&lt;li&gt;It has built-in &lt;b&gt;collections&lt;/b&gt; &amp;mdash; specifically multidimensional arrays, but any decent collection support would do as well. We take collections for granted nowadays, at least in languages higher-level than C, but this wasn't always so. There's a reason many early languages (not just APL and Lisp) were built around a collection type.
&lt;li&gt;It has &lt;b&gt;high-order&lt;/b&gt; operations: &lt;code&gt;map&lt;/code&gt; is (often) implicit, and &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;scan&lt;/code&gt;, and Cartesian product are single characters.
&lt;li&gt;It's &lt;b&gt;terse&lt;/b&gt;, and not just because of its one-character names. You really can say in a line of APL what would take a page of Fortran.
&lt;/ul&gt;

&lt;p&gt;Under these circumstances, wouldn't you be amazed by the powerful new language? Wouldn't you become a faithful user, and for decades wonder why all other languages were so uselessly primitive?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6454006-4190873814613344541?l=arcanesentiment.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ArcaneSentiment/~4/6-FB2kj3zsE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://arcanesentiment.blogspot.com/feeds/4190873814613344541/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6454006&amp;postID=4190873814613344541" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4190873814613344541?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6454006/posts/default/4190873814613344541?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ArcaneSentiment/~3/6-FB2kj3zsE/whats-so-cool-about-apl.html" title="What's so cool about APL?" /><author><name>Arcane Sentiment</name><uri>http://www.blogger.com/profile/04144052171693893368</uri><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>5</thr:total><feedburner:origLink>http://arcanesentiment.blogspot.com/2010/12/whats-so-cool-about-apl.html</feedburner:origLink></entry></feed>

