Tuesday, March 18, 2008

Gif

Yesterday I got a friendly email suggesting that I should stop learning those esoteric languages and switch to Arc(*), presto. After the usual propaganda, that Arc is the latest, greatest and streight from the roots of original McCarthy's lisp blah blah blah, I was finally shown an example of such ingenuity with its if operator. Spice that with comments like what the hell was common lisp comittee thinking when they buried cond under sea of parenthesis and you'll know why the blackhat character from xkcd has zero tolerance for newbishness. So why the hell Arcs' if is not such a big deal?Anybody who spent more than 15 minutes reading On Lisp will find writing such macro nobrainer. Here's mine code as you go:

(defun pair-them (x)
(cond ((null x) nil)
((endp (cdr x))
(cons (list t (car x))
(pair-them (cddr x))))
(t
(cons (list (car x) (cadr x))
(pair-them (cddr x))))))
;;; Grahams' if
(defmacro gif (&rest args)
`(cond ,@(pair-them args)))

Few tests:

(pprint
(macroexpand-1
'(gif (= a 1) (setq a 2)
(= a 2) (setq a 3)
(= a a) (floor a 3))))

(COND ((= A 1) (SETQ A 2))
((= A 2) (SETQ A 3))
((= A A) (FLOOR A 3)))


(pprint
(macroexpand-1
'(gif (= a 1) (setq a 2)
(= a 2) (setq a 3)
(floor a 3))))

(COND ((= A 1) (SETQ A 2))
((= A 2) (SETQ A 3))
(T (FLOOR A 3)))

Looks fine. I could probably make something nicer but this is Ok for demonstrational purposes. Note that if you feed it with odd number of arguments it assumes that last clause is the default one. I don't know exactly how Arcs' if is working, but I assume it's something like that.
But what will happen if you have a cond clause with multiple computations like below?

(cond ((evenp x)
(do-something)
(do-something-else))
((oddp ...

Than you'll have to insert some progns and the beauty is gone.

(if (evenp x)
(progn
(do-something)
(do-something-else)) .
(oddp ...

So you pay for those omitted parens with additional progns. Whichever solutions is better depends from the situation, so use whatever you want. If someone could think of graceful solution that could simoultaneously omit extra parens and progns that could make me learn Arc. Or rather implement the same thing in common lisp.

(*) I didn't even looked at Arc,beside it's cover.

2 comments:

  1. In Arc, (progn ...) is (do ...), which is a bit easier to type. Might make typing multi-statement cases in ifs more bearable too.

    Also, your last code sample turns into (when predicate ...), like in Common Lisp.

    ReplyDelete
  2. Few characters doesn't count much, since you must introduce extra parenthesis and a new token.

    It was intended as part of a multistatement cond, I'll make it more clear thanks for pointing it.

    ReplyDelete

Note: Only a member of this blog may post a comment.