<?xml version="1.0"?>
<rss version="2.0.">
  <channel>
    <title>Advogato blog for nikodemus</title>
    <link>http://www.advogato.org/person/nikodemus/</link>
    <description>Advogato blog for nikodemus</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Sat, 17 May 2008 09:31:36 GMT</pubDate>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Quick Notes</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=11</link>
      <guid>http://random-state.net/log/3411205049.html</guid>
      <description>
&lt;p&gt;The only valid measurement of code quality: &lt;a
href="http://www.osnews.com/images/comics/wtfm.jpg"&gt;WTFM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Getting Git&lt;/i&gt; series will continue later this week, but in the
meanwhile I would like to bring to your attention an oft-forgotten
output operator in Common Lisp: &lt;tt&gt;&lt;a
href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_pr.htm#write"&gt;WRITE&lt;/a&gt;&lt;/tt&gt;.
It is perfect for both REPL and code in many cases, since you don't
need to bind printer control variables around it -- just pass the ones
you care about as keywords. Similarly, you don't have to worry about
it munging variables your callers may care about.&lt;/p&gt;

&lt;p&gt;Presenting &lt;b&gt;&lt;a
href="http://random-state.net/files/esrap.lisp"&gt;ESRAP 0.1&lt;/a&gt;&lt;/b&gt;.  It
is a simple packrat parser for Common Lisp. It's been almost a year
since I wrote it, and it seems unlikely that I'll work more on it in
near future. In its current state it is neither particularly optimized
or polished, nor does it have a great deal of fancy features, but it
did what I needed it to do at the time, and I figured someone else
might find it a more useful starting point for their own needs then
CL-PEG. The feature list reads:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;dynamic redefinition of nonterminals&lt;/li&gt;
 &lt;li&gt;inline grammars&lt;/li&gt;
 &lt;li&gt;semantic predicates&lt;/li&gt;
 &lt;li&gt;simple introspective facilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;pre&gt;(parse '(or "foo" "bar") "foo") &amp;rArr; "foo", NIL

(add-rule 'foo+ (make-instance 'rule 
                 :expression '(+ "foo"))) 
  &amp;rArr; FOO+

(parse 'foo+ "foofoofoo") 
  &amp;rArr; ("foo" "foo" "foo"), NIL

(add-rule 'decimal
           (make-instance 'rule
            :expression '(+ (or "0" "1" "2" "3" 
                                "4" "5" "6" "7" 
                                "8" "9"))
            :transform 
            (lambda (list) 
              (parse-integer (format nil "~{~A~}" 
                                     list)))))
  &amp;rArr; DECIMAL

(parse '(oddp decimal) "123") &amp;rArr; 123, NIL

(handler-case
    (parse '(oddp decimal) "124")
  (error (e)
    (format t "~&amp;oops: ~A~%" e))) &amp;rArr; NIL
; output
oops: Expression (ODDP DECIMAL) failed at 0.

(parse 'foo+ "foofoofoobar" :junk-allowed t) 
  &amp;rArr; ("foo" "foo" "foo"), 9

(parse '(evenp decimal) "123" :junk-allowed t) 
  &amp;rArr; NIL, 0

(add-rule 'foos-or-decimal
          (make-instance 'rule
           :expression '(or foo+ decimal)))
  &amp;rArr; FOOS-OR-DECIMAL

(describe-grammar 'foos-or-decimal) &amp;rArr; NIL
; output
Grammar FOOS-OR-DECIMAL:
   FOOS-OR-DECIMAL &lt;- (OR FOO+ DECIMAL)
   FOO+    &lt;- (+ "foo")
   DECIMAL &lt;- (+ (OR "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))&lt;/pre&gt;

&lt;p&gt;Existence of bugs is guaranteed. Licence is zero-clause MIT.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Getting Git, part 3</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=10</link>
      <guid>http://random-state.net/log/3411001100.html</guid>
      <description>
&lt;p&gt;&lt;i&gt;Note: updated to correct a logical error. When development
converges, a child will have multiple parents -- not vice-versa.
Kudos to Johannes Gr&amp;oslash;dem for sharp eyes and a heads-up.&lt;/i&gt;&lt;/p&gt;

&lt;p&lt;b&gt;Intermission&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I've learned that some people are reading this and wondering if
   they really need to know all this to use Git?.&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;If all you're using Git for is "edit-diff-commit, edit-diff-commit"
 cycle, you don't. This seems to be 99% of what many people use a VCS
 for, and there is nothing wrong with that. You can even go quite a
 bit beyond that, and still you don't need to know anything about
 what's really going on -- just follow the a simple recipe, and you're
 good to go.&lt;/p&gt;

&lt;p&gt;It's when you move beyond the recipe level that you need to
 understand the model the VCS uses, just like you need to with CVS,
 Subversion, Darcs, or any other VCS. If you don't think that's true,
 you've either internalized the model without noticing, or you're just
 hammering out recipes.&lt;/p&gt;

&lt;p&gt;Specifically, this series is written to teach enough of the Git
 model to be able to look at a bunch of disparate branches you need to
 merge somehow, figure out the kind of history you want to build, and
 then do that. No recipe in the world is going to to this for the
 general case: you need to know what is going on before you can decide
 what you want.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;What's In A Commit&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;So, where were we? Ah, storing history. If you haven't read it yet,
&lt;a href="http://random-state.net/log/3410155710.html" &gt;here's&lt;/a&gt; where
you can read the story so far.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Commits&lt;/b&gt; are the third kind of object stored in the object
database. You could call commit "a moment in history", but let's
see exactly what it contains:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;&lt;b&gt;Tree&lt;/b&gt;: the entire contents of the directory tree
        associated with the commit.&lt;/p&gt;

 &lt;li&gt;&lt;p&gt;&lt;b&gt;Parent(s)&lt;/b&gt;: a commit has one or more parent commits. A
        parent commit is the "previous" commit: the changes introduced
        by a commit can be seen by comparing the trees of the commit
        and its parent(s).&lt;/p&gt;
     &lt;p&gt;The common case is a single parent: this represents normal
        linear development.&lt;/p&gt;
     &lt;p&gt;Multiple parents represent converging lines of development.
        A commit with multiple parents is called a &lt;i&gt;merge commit&lt;/i&gt;.
        Two parents is the norm, but multiple branches can be merged
        with a single commit.&lt;/p&gt;&lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;b&gt;Comment&lt;/b&gt;: some text describing the commit.&lt;/p&gt;&lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;b&gt;Committer&lt;/b&gt;: the person who actually created the commit,
   and the date this was done.&lt;/p&gt;&lt;/li&gt;

 &lt;li&gt;&lt;p&gt;&lt;b&gt;Author&lt;/b&gt;: the person responsible for the change
   represented by the commit, and the date. Often the author and the
   committer are the same, but when eg. submitting patches by email
   Git automatically preserves information about the original
   author.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Commits form a DAG via parents. When development diverges, multiple
   children will share that same parent. When development converges, a
   single child will have multiple parents. If this is not clear, get
   a piece of paper, and draw a few dags -- it's more effective then
   any fancy graphic I might cook up.&lt;/p

&lt;p&gt;So, if you have hold of a commit object, you have hold of the
   entire history up to that point -- but you don't know anything
   about the future. In other words: &lt;b&gt;History is the DAG rooted at
   any given commit.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;s&gt;Back to our regularly scheduled Erlang envy.&lt;/s&gt; Review: What is
   a commit object? Can multiple commits refer to a single tree; if
   so, what does it mean; if not, why not? Can multiple commits share
   parents; if so, what does it mean; if not, why not? If the tip of a
   branch is a commit, can you guess what the history of the branch
   is?&lt;/p&gt;

&lt;p&gt;Next time: tagsoup.&lt;/p&gt;

&lt;p&gt;Also, here's some moral support for me: &lt;a
href="http://www.advogato.org/person/apenwarr/diary/371.html"&gt;Git is
the next Unix&lt;/a&gt; says &lt;a
href="http://www.advogato.org/person/apenwarr/"&gt;apenwarr&lt;/a&gt;. I may
not agree with the metaphor, but it's a nice read:&lt;/p&gt;

&lt;blockquote&gt;Git was originally not a version control system; it was
designed to be the infrastructure so that someone else could build one
on top. And they did; nowadays there are more than 100 git-* commands
installed along with git. It's scary and confusing and weird, but what
that means is git is a platform. It's a new set of nouns and verbs
that we never had before. Having new nouns and verbs means we can
invent entirely new things that we previously couldn't do.
&lt;/blockquote&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Getting Git, part 2</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=9</link>
      <guid>http://random-state.net/log/3410431842.html</guid>
      <description>
&lt;p&gt;&lt;i&gt;Read &lt;a href="http://random-state.net/log/3410155710.html" &gt;part
1&lt;/a&gt; first.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;At the core of Git is the object database. It is not an
implementation detail, but a fundamental part of the whole. Don't
ignore it, and don't be scared of it. You don't have to use it
directly, but knowing the basics makes life a lot easier.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;p&gt;The object database lives somewhere under .git/ in each and every
repository clone -- nevermind where exactly.&lt;/p&gt;

&lt;p&gt;The object database is garbage collected: the only way to delete an
object is to remove all roots that point to it, and let the GC reclaim
it. Roots also live under .git/, but are distinct from the database.&lt;/p&gt;

&lt;p&gt;Since &lt;i&gt;content is immutable&lt;/i&gt;, there is no way to mutate
anything in the database -- you can only add new objects.&lt;/p&gt;

&lt;p&gt;Now, there are four kinds of objects in the database. Today we will
cover just two of them -- the lower level, if you will. This is
content at its most content-seeming:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Blobs&lt;/b&gt; are binary content. They don't contain any pointers.
  Blobs are used to store file contents. Not file names, etc -- just
  contents. If you have files x/foo.txt and y/bar.txt, which both
  contain just the string "foobar", then in the object database there
  will be a blob that stores the string "foobar" -- representing the
  content of both files. Remember: content is identity.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Trees&lt;/b&gt; are lists of entries. The entries represent other
  objects in the database: for each entry the tree stores the object
  type, the pointer/SHA1 for the object, the object name, and the mode
  (the executable bit, really.) A single tree object represents a
  single directory with its files and subdirectories; in normal
  circumstances a tree willl only contain blob and tree entries.
  Again, &lt;i&gt;content is identity&lt;/i&gt;: if you have to two directories
  containing identically named files with identical contents and
  executable bits, both will be represented by the same tree
  object.&lt;/p&gt;

&lt;p&gt;Consider directories and the file here: x/y/z.txt&lt;/p&gt;

&lt;p&gt;We have:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Blob-object &lt;i&gt;B&lt;sub&gt;z&lt;/sub&gt;&lt;/i&gt; for the contents of z.txt.&lt;/li&gt;

 &lt;li&gt;Tree-object &lt;i&gt;T&lt;sub&gt;y&lt;/sub&gt;&lt;/i&gt; for y/, containing the name
   z.txt, and a pointer to &lt;i&gt;B&lt;sub&gt;z&lt;/sub&gt;&lt;/i&gt;.&lt;/li&gt;

 &lt;li&gt;Tree-object &lt;i&gt;T&lt;sub&gt;x&lt;/sub&gt;&lt;/i&gt; for x/, containing the name y, and a pointer to
   &lt;i&gt;T&lt;sub&gt;y&lt;/sub&gt;&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if we change the contents of z.txt, and commit the new content to
the object database -- what happens to the object graph as a whole?&lt;/p&gt;

&lt;blockquote&gt;
  Remember: Content is identity, and not just for blobs, but all
  objects. If you change the contents of a file, you need a new tree
  object containing a pointer to the new blob, etc. This is a really
  important bit, so make sure you understand this: any pointer into
  the object database is a unique identifier for the whole object
  graph reachable from that point.
&lt;/blockquote&gt;

&lt;p&gt;So, you will have:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Blob-object &lt;i&gt;B&lt;sub&gt;z2&lt;/sub&gt;&lt;/i&gt; for the new contents of z.txt.&lt;/li&gt;

 &lt;li&gt;Tree-object &lt;i&gt;T&lt;sub&gt;y2&lt;/sub&gt;&lt;/i&gt; for y/, containing the name z.txt, and a pointer
    to &lt;i&gt;B&lt;sub&gt;z2&lt;/sub&gt;&lt;/i&gt;.&lt;/li&gt;

  &lt;li&gt;Tree-object &lt;i&gt;T&lt;sub&gt;x2&lt;/sub&gt;&lt;/i&gt; for x/, containing the name y, and a pointer to
    &lt;i&gt;T&lt;sub&gt;y2&lt;/sub&gt;&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The old versions are still there: content is immutable -- as long as
GC hasn't reclaimed them, we can get at them.&lt;/p&gt;

&lt;p&gt;Now, as long as you remember that a tree object represents the
&lt;i&gt;whole state of the whole directory structure under it&lt;/i&gt;,
including file contents, you can forget about blobs. Just think of
trees, and you will be fine.&lt;/p&gt;

&lt;p&gt;Review: &lt;s&gt;Why did the hacker cross the road?&lt;/s&gt; Where does Git store
content? How are files and directories stored? Can you mutate stored
content; if so, how; if not, why not? Can you deleted stored content;
if so, how; if not, why not? What does a tree object represent?&lt;/p&gt;

&lt;p&gt;Next time: how history is content, and how it is stored.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Getting Git, part 1</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=8</link>
      <guid>http://random-state.net/log/3410155710.html</guid>
      <description>
&lt;p&gt;Many people -- me included -- find Git &lt;i&gt;really nice&lt;/i&gt;, but equally
many seem somewhat confused by it. I think this is due to Git being
conceptually different compared to other VCS we're used to: unless you
have an at least mostly correct &lt;i&gt;theory of Git&lt;/i&gt; your expectations
based on experiences with other systems will lead you astray.&lt;/p&gt;

&lt;p&gt;This is the first part in a series of posts that tries to address
this issue, by providing the aforementioned theory. In this part I
talk about general concepts: the terms I use are not Git terms; I'm
trying to start you thinking in a Git-compatible way as opposed to
whatever CVS and others have taught you over the years. Details and
real terms will start in the next episode.&lt;/p&gt;

&lt;p&gt;Ready? Buckle up!&lt;/p&gt;

&lt;p&gt;Git stores &lt;b&gt;content, not metadata&lt;/b&gt;. Some of the data stored
   by Git may very well describe some other data also stored by Git,
   but it is all content to Git.&lt;/p&gt;

&lt;p&gt;Git stores &lt;b&gt;content, not changes&lt;/b&gt;. It can &lt;i&gt;reason&lt;/i&gt; about
   changes in content, but only content is stored.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Content is identity.&lt;/b&gt; If two "things" have identical content,
   they are the same thing for Git.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Content is immutable.&lt;/b&gt; If you think you are mutating
   something stored by Git, think again: what you're doing is making
   an altered copy and possibly throwing away the original. Since
   content is identity, you &lt;i&gt;cannot&lt;/i&gt; mutate an object and have it
   retain its identity.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;I hope this was simple enough, but if you've had trouble
understanding Git before, please review the points above a time or two
to make sure you understand what I'm saying. You don't yet need to
understand how the points above relate to Git -- just try to
grok &lt;i&gt;das Ding an sich&lt;/i&gt;. When you think you have it, ask yourself:&lt;/p&gt;

&lt;p&gt;&lt;s&gt;Conan! What is best in life?&lt;/s&gt; What does Git store? How would
you describe this stuff that Git stores?&lt;/p&gt;

&lt;p&gt;Next time we'll pop open the hood and see what's inside.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>This makes me sad</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=7</link>
      <guid>http://random-state.net/log/3410004557.html</guid>
      <description>
&lt;p&gt;A short while ago, I wrote &lt;a
href="http://random-state.net/log/3409830445.html"&gt;a piece&lt;/a&gt;
parodying a few common memes oft seen in programming blogs:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Primarily, valuing terseness over readability and long-term
     maintainability. Terseness and conciseness do not imply
     expressiveness. While it is reasonable to expect for the reader
     to be familiar with the language used and various common idioms,
     it is not reasonable to make abstractions that are larger then
     the problems they solve.&lt;/li&gt;

 &lt;li&gt;Secondarily, the tendency to use trivial operations over small
     sets to demonstrate benefits of a given approach for non-trivial
     operations over large sets. Granted, blogs are too small a margin
     for many things, but we should all pay more attention to this.&lt;/li&gt;

 &lt;li&gt;Finally: "the utter clarity that functional programming
     delivers". Just like code that depends on intricate side-effects
     is hard to understand, code that depends on intricate flow of
     values can be hard to understand. Saying "It's Functional!" is
     not an excuse for impenetrable code: sometimes your personal
     aesthetics and clarity of expression are at odds, and you must
     find a balance that does not unduly stress future generations
     that must live with the code we write today.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, the arrow macros I presented were intentionally
horrible. If you thought they were neat, think again.&lt;/p&gt;

&lt;p&gt;I hope the fact that my parody elicited more responses then
anything I've ever written before -- some liking, others disliking,
but all taking it seriously -- is more indicative of my meager skills
as a humorist, then it is of the state of the programming blogs.&lt;/p&gt;

&lt;p&gt;*sigh* -- I thought disclaimers are for wussies.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Experiments in Fun[ctional] Programming</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=6</link>
      <guid>http://random-state.net/log/3409830445.html</guid>
      <description>
&lt;p&gt;&lt;b&gt;WARNING:&lt;/b&gt; &lt;a
href="http://random-state.net/log/3410004557.html"&gt;May Contain Trace
Elements of Parody&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I mentioned the possibility to use &amp;lt;- instead of #L a while ago.
Then I got to talking
with &lt;a href="http://www.google.com/search?q=troels+henriksen" &gt;Troels
Henriksen&lt;/a&gt; of the Climacs (which is Emacs of tomorrow -- like Arc
is to Common Lisp, except that it actually exists!) and McCLIM fame
about &lt;a href="http://ircbrowse.com/channel/lisp/200801" &gt;related
matters&lt;/a&gt;. Like so
many &lt;a href="http://lambda-the-ultimate.org/" &gt;others&lt;/a&gt;, I've always
been intrigued by the utter clarity functional programming delivers --
on thing led to another, and now I'd like to introduce you to my three
new best friends: &amp;lt;-, &amp;lt;---, and ---&amp;gt;.&lt;/p&gt;

&lt;p&gt;The core idea is to be able to express lazy and partial evaluation
succintly -- because, as we all know, terseness is a virtue: code that
is never written is the best code. Naysayers will claim that overly terse
code can be hard to understand, but as long as there is less of it, that
really doesn't count, does it?&lt;/p&gt;

&lt;p&gt;Firstly, we have the idea of "streams" or "pipes": functions called
repeatedly to produce different values: such a function can easily
express eg. any infinite series. Of course, for this to to be of any
utility, we need a utility to do this calling in a
terse-yet-expressive manner. This is what ---&amp;gt; does:&lt;/p&gt;

&lt;pre&gt;(defmacro ---&amp;gt; (size composition &amp;rest arguments)
  (let ((express (gensym "EXPRESS"))
        (unexpressed (gensym "UNEXPRESSED"))
        (expressed (gensym "EXPRESSED"))
        (expression-arguments (gensym "EXPRESSION-ARGUMENTS")))
    `(let ((,expression-arguments (list ,@arguments)))
       (labels ((,express (,expressed ,unexpressed)
                  (if (zerop ,unexpressed)
                      ,expressed
                      (,express (append ,expressed (list (apply ,composition ,expression-arguments))) 
                                (- ,unexpressed 1)))))
         (,express nil ,size)))))&lt;/pre&gt;

&lt;p&gt;This macro expands into an elegant recursion that constructs a list
by repeatedly calling a function with &lt;i&gt;the results of evaluating
arguments&lt;/i&gt;. The last bit is the key to its power:&lt;/p&gt;

&lt;pre&gt;;;; no need for this
(let ((stream (make-stream))) (---&amp;gt; *n* (composition) stream))

;;; just this is enough
(---&amp;gt; *n* (composition) (make-stream))&lt;/pre&gt;

&lt;p&gt;Next, we need tools for writing streams. What we would like to be able
to do is:&lt;/p&gt;

&lt;pre&gt;(defun natural-number-stream () (&amp;lt;--- 0 1+))&lt;/pre&gt;

&lt;p&gt;Happily, &amp;lt;--- is simple enough:&lt;/p&gt;

&lt;pre&gt;(defmacro &amp;lt;--- (start step)
  (let ((value (gensym "VALUE")))
    `(let ((,value ,start))
       (lambda () (prog1 ,value (setf ,value (,step ,value)))))))&lt;/pre&gt;

&lt;p&gt;Finally, we want to be able to express our composition nicely.
Say, we would like to put &lt;tt&gt;(lambda (x) (- (funcall x))&lt;/tt&gt; in a 
better way.&lt;/p&gt;

&lt;pre&gt;;;; This would be nice: no extra parens!
(&amp;lt;- -)&lt;/pre&gt;

&lt;p&gt;Again, easy enough. This is a slight extension to my earlier &amp;lt;-,
which deals with the _ implicitly, and automatically handles functions
as arguments, so that it can be used with streams like above.&lt;/p&gt;

&lt;pre&gt;(defmacro &amp;lt;- (operation &amp;rest arguments)
  (let ((processed-arguments (if (member '_ arguments) arguments (append arguments '(_)))))
    `(lambda (_) 
       (setf _ (if (functionp _) (funcall _) _))
       (,operation ,@processed-arguments))))&lt;/pre&gt;

&lt;p&gt;That's all there is to it! Now we can express mappings over natural
numbers in a clear and concise manner:&lt;/p&gt;

&lt;pre&gt;(---&amp;gt; 3 (&amp;lt;- -) (&amp;lt;--- 0 1+)) ; =&gt; (0 -1 -2)&lt;/pre&gt;

&lt;p&gt;Where are &amp;lt;-- and --&amp;gt; you might ask, naturally enough. I'm
reserving them for implementing general purpose lazy evaluation...&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>This Calls for Dispute</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=5</link>
      <guid>http://random-state.net/log/3406913451.html</guid>
      <description>
&lt;p&gt;Eric Normand &lt;a href="http://www.lispcast.com/index.php/2007/12/toolchest-shortcuts-for-higher-order-functions/" &gt;writes about expressing higher-order functions&lt;/a&gt;. His case study is basically:&lt;/p&gt;

&lt;pre&gt;(mapcar (lambda (x) (* x 2)) list)&lt;/pre&gt;

&lt;p&gt;One of the expressions this can be given is:&lt;/p&gt;

&lt;pre&gt;(mapcar (curry #'* 2) list)&lt;/pre&gt;

&lt;p&gt;and another is&lt;/p&gt;

&lt;pre&gt;(mapcar #L(* 2 _) list)&lt;/pre&gt;

&lt;p&gt;I realize that some people are really fond of #L. Fine, it's fine -- use it.
Let's just be fair about the comparison...&lt;/p&gt;

&lt;p&gt;Problems of #L according to Eric:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;It's not widely used, so it might be hard for someone to understand at first glance.&lt;/li&gt;
 &lt;li&gt;Can only be used for functions of one argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same for &lt;tt&gt;CURRY&lt;/tt&gt;:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Not very common, so it's not readable by all.&lt;/li&gt;
 &lt;li&gt;#' syntax gets in the way.&lt;/li&gt;
 &lt;li&gt;I would not use it since the form is a bit clunky.&lt;/lu&gt;
&lt;/ul&gt;

&lt;p&gt;Huh? #' gets in the way and #L does not? How is the &lt;tt&gt;CURRY&lt;/tt&gt; klunky?
I just &lt;i&gt;so&lt;/i&gt; do not get this. That said, I generally prefer the explicit
lambda -- though there are exceptions.&lt;/p&gt;

&lt;p&gt;Finally, I really don't understand why to use a reader-macro for this
when regular macros work for similar purposes more then fine. Use macros
when fuctions won't do, and use reader-macros when macro's won't do is
a good rule of the thumb in my books.&lt;/p&gt;

&lt;pre&gt;(defmacro &amp;lt;- (&amp;amp;body body) `(lambda (_) ,@body))&lt;/pre&gt;

&lt;p&gt;...with the added benefit that the user can macroexpand the form
for instant comprehansion.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>SBCL 12.5 months after 1.0</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=4</link>
      <guid>http://random-state.net/log/3406910062.html</guid>
      <description>
&lt;p&gt;It is now a bit over a year since SBCL 1.0 was released.&lt;/p&gt;

&lt;pre&gt;Author: William Harold Newman
Date:   Thu Nov 30 02:36:43 2006 +0000

    1.0:
        release, will be tagged as sbcl_1_0&lt;/pre&gt;

&lt;p&gt;What's changed since then? I'll list my own favorites here (in
reverse order of appearance).&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Hash-tables with synchronization support over multiple
 accesses.&lt;/li&gt;

 &lt;li&gt;Compare and swap support on several kinds of places.&lt;/li&gt;

 &lt;li&gt;Support for user-defined subclasses of SPECIALIZER.&lt;/li&gt;

 &lt;li&gt;Code coverage support.&lt;/li&gt;

 &lt;li&gt;XREF support.&lt;/li&gt;

 &lt;li&gt;Support for user-defined subclasses of SEQUENCE.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not counting optimizations or bugfixes here at all. If I was, I'd
make a big deal about how SBCL threads are finally starting to mature.
Or list Big-Oh / order of magnitude optimizations. Or rant about the
old chestnut, interrupt-safety...&lt;/p&gt;

&lt;p&gt;Maybe it's time to start thinking about 1.1...&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>In Merry Old England</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=3</link>
      <guid>http://random-state.net/log/3399276118.html</guid>
      <description>
&lt;p&gt;Last Sunday I moved to Leiceister, UK -- though only for
till the end of the year: my partner has an honorary research
fellowship for the fall term here, in the De Montfort University.&lt;/p&gt;

&lt;p&gt;Last week has been chaotic and rather stressful: it turns out that
almost no-one in the UK is happy with taking tenants for less then 6
months; the hotel internet is a bad joke; we both have sore throats
and have been feeling a bit feverish. ...but things are settling down.
We did find a place to live, and can move in next tuesday, and I have
found &lt;a href="http://www.icemango.co.uk/" &gt;a decent internet cafe&lt;/a&gt;
to work from -- essential as our place will not be connected until
some time in October.&lt;/p&gt;

&lt;p&gt;So, if there is anyone in the area who feels like saying
hello, feel free to drop me a line.&lt;/p&gt;
  </description>
    </item>
    <item>
      <pubDate>Mon, 5 May 2008 16:17:57 GMT</pubDate>
      <title>Learning Common Lisp</title>
      <link>http://www.advogato.org/person/nikodemus/diary.html?start=2</link>
      <guid>http://random-state.net/log/3399269964.html</guid>
      <description>
&lt;p&gt;Spurred by &lt;a href="http://www.gigamonkeys.com/blog/2007/09/19/bomb-me.html" &gt;Peter Seibel&lt;/a&gt;, here's my recommendation for learning lisp:&lt;/p&gt;

&lt;p&gt;If you already know how to program, and are looking for a book or a
tutorial that gives you a solid grounding in Common Lisp, go read
&lt;i&gt;Practical Common Lisp&lt;/i&gt; at &lt;a
href="http://www.gigamonkeys.com/book/"&gt;http://www.gigamonkeys.com/book/&lt;/a&gt;.
In my opinion it's the best one out there.&lt;/p&gt;

&lt;p&gt;If PCL rubs you the wrong way for some reason, if you find it too
hard, or are new to programming in general, &lt;i&gt;A Gentle Introduction
to Symbolic Computation&lt;/i&gt; at &lt;a
href="http://www.cs.cmu.edu/~dst/LispBook/index.html"&gt;http://www.cs.cmu.edu/~dst/LispBook/index.html&lt;/a&gt;
is possibly a better match.&lt;/p&gt;

&lt;p&gt;If you ask me, don't bother with the others before you've read
either one of these. (Though for learning programming in general I
would suggest
&lt;i&gt;Structure and Interpretation of Computer Programs&lt;/i&gt;, even though it
doesn't teach you Common Lisp.)&lt;/p&gt;
  </description>
    </item>
  </channel>
</rss>
