Hacker News new | past | comments | ask | show | jobs | submit login
Why Lisp macros are cool, a Perl perspective (2005) (warhead.org.uk)
90 points by lobo_tuerto on July 15, 2012 | hide | past | favorite | 13 comments



How did this wind up here?

For the original, go to http://plover.com:8080/~alias/list.cgi?2:mss:234:200507:hokn... and see the discussion we had about it then.

It is also worth noting that MJD has the distinction of being the highest rated speaker at Oscon ever. If there is any possibility of interest, he is worth watching because he is incredibly informative.

See http://perl.plover.com/ for some of his older Perl writings.


How did this wind up here?

Because chimeracoder posted it here: http://news.ycombinator.com/item?id=4245898. Credit where due!


Which makes me wonder why chimeracoder had that link rather than the original. And makes me wonder whether I know chimeracoder.

Some background. I was the person who forwarded an interesting email from hop-discuss to a small mailing list of mostly technical friends. The link that was reposted was to the version that I forwarded, instead of the original that I would expect to be more widely known.


It may just be that Google knows you:

https://www.google.com/#q=mark+dominus+lisp+macros


It is more likely that it crawled those archives and found more on the IWE list than hop-discuss.


Lisp people might enjoy this short specification for Perl 6: http://perlcabal.org/syn/S06.html#Macros

"Real" macros in a non-lisp language [edit: I mean, a language without the parse tree explicitly in the syntax]? Well, it'd be wonderful if it works.

Edit: re Dominus, his Higher Order Perl is on the net. http://hop.perl.plover.com/


"Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in." - Larry Wall

C's macro system, for example, is so unreliable that you can't even define a simple macro like

        #define square(x)      x*x

How do you set the value associated with the "foo" property? Oh, you use "setf", which rewrites

        (setf (get x foo) 1)
to

        (LET* ((#:G847 X) (#:G848 FOO))
          (MULTIPLE-VALUE-BIND (#:G850) 1 (COMMON-LISP::%PUT #:G847
             #:G848 #:G850)))
but you don't have to know that. It just works.

I agree about C macros. But, show me the source for:

    (defmacro setf ...
and you may be quoting Larry Wall.


Since it's only 30 lines of code, here's the relevant section from SBCL (as found in src/code/early-setf.lisp):

    (defmacro-mundanely setf (&rest args &environment env)
      #!+sb-doc
      "Takes pairs of arguments like SETQ. The first is a place and the second
      is the value that is supposed to go into that place. Returns the last
      value. The place argument may be any of the access forms for which SETF
      knows a corresponding setting form."
      (let ((nargs (length args)))
        (cond
         ((= nargs 2)
          (let ((place (first args))
                (value-form (second args)))
            (if (atom place)
              `(setq ,place ,value-form)
              (multiple-value-bind (dummies vals newval setter getter)
                  (sb!xc:get-setf-expansion place env)
                (declare (ignore getter))
                (let ((inverse (info :setf :inverse (car place))))
                  (if (and inverse (eq inverse (car setter)))
                    `(,inverse ,@(cdr place) ,value-form)
                    `(let* (,@(mapcar #'list dummies vals))
                       (multiple-value-bind ,newval ,value-form
                         ,setter))))))))
         ((oddp nargs)
          (error "odd number of args to SETF"))
         (t
          (do ((a args (cddr a))
               (reversed-setfs nil))
              ((null a)
               `(progn ,@(nreverse reversed-setfs)))
            (push (list 'setf (car a) (cadr a)) reversed-setfs))))))
Okay, so it's not the simplest thing around, and it hinges upon a bunch of other things also defined in the source. Nonetheless it's not very "oatmeal and fingernail clippings" after all. It's pretty straightforward. "Here is my docstring, let `nargs` be the number of arguments, if this is 2, then we've either got the primitive case (setf a 1) which is actually a `setq`, or else we macro-expand the place which should be a list like `(car a)`, pull off that first symbol `(car place)`, get its function -- call that function `inverse`, then return an expression which will call `inverse` on the `(cdr place)` with the `value-form` we're trying to set to. If this inverse doesn't exist then there seems to be some transformation of the list (a comment would have been nice here, because I'm not sure what this describes). If the number of args is odd then that's an error; if it's an even number greater than two then we assume that the syntax was (setf a 1 b 2) and recurse on the child pairs."

As readability goes, it's not bad.


"Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in." - Larry Wall

Considering the general appearance of code for the language he created I'm not sure this quote of his can be taken all that seriously. At worst Perl looks like somebody glued the shift key down and repeatedly head-butted the top row of their keyboard.


(I shouldn't comment on karma 18 accounts, I'm probably being trolled, but a couple of links should be ok...)

See the Synopsises here:

http://search.cpan.org/~flora/MooseX-Declare-0.35/lib/MooseX...

http://search.cpan.org/~ether/MooseX-Method-Signatures-0.43/...

(I assume you'll insist that any link I give is ugly. :-) But note that the declarations and parameter specifications are at least as elegant as any other major scripting language I'm aware of.)

Edit: And for the record, I love Perl and Lisp. :-)


Not trolled, probably karma 18 because I've posted only a few times in the years since creating an account. I'm really not intrested in karma/scoring games on sites like HN.

Moose looks really nice and I've nothing against Perl - my language of choice is Scala. I just thought it was a daft thing for Larry to say considering the issues of readability that have been levelled at Perl.


If you consider this, what you've just said is "I think it's daft for Larry not to like the way lisp looks considering some people don't like the way perl looks."

I don't like the way python looks. Does that mean it would be daft for Guido to ever criticise another language's aesthetics? :)


I know you didn't actually mean it but here's an implementation of setf from GNU Emacs:

https://gist.github.com/3116185#L1950

It's actually not hard to understand if you know a bit of elisp. And of course the implementation of Macros is usually the hairiest bits of Lisp code. The thing about Macros is that you don't often want to write them, but when you do they allow you to do amazing things that simply wouldn't be possible without them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: