[iterate-devel] Between-each, FORMAT's ~^ and code-walking

Hoehle, Joerg-Cyril Joerg-Cyril.Hoehle at t-systems.com
Fri Dec 9 13:56:08 UTC 2005


Mészáros Levente wrote:
>> Would you like to show more elaborate loop examples?
>Let's say one has a list and one wants to transform it into a 
>string by transforming each element to a string and putting a 
>comma between them.
>(concatenate-as-string
>	(iter (for e in l)
>		(except-first-time (collect ", "))
>		(collect (as-string e))))

I recently came across that article about Lispy FORMAT replacements and started wondering how to nicely implement FORMAT's "~^" idiom.

http://www.cs.yale.edu/homes/dvm/format-stinks.html

BTW, I haven't seen the code for McDermott's out macro, but I expect it to be subject to code-walking problems similar to Iterate, series and other packages that depend on traversing code.

Why? consider one example from the above article:
   (out "#<Foo " (Foo-label f1) 
        (:q ((eq (Foo-status f1) ':abnormal)
             "?"))
        (:e (dolist (x (Foo-contents f1))
               (:o " " x)))
        ">")
Do you see the :o keyword inside the dolist? I think keywords are constants and cannot be locally bound (using MACROLET). Therefore, I believe the OUT macro needs to code-walk its body to track down all uses of :o and insert the replacememt code.

Had a non-constant symbol been used therein, then MACROLET could have been used and the implementation of the macro out would (presumably) be clean.

In any case, ~^ is quite different from *-first-time. It's more like an early test of loop termination.  The macro out does not propose an idiom for that. The examples just repeat the termination test, as in
(defun print-xapping ...)
  ... (do ((d ... (cdr d)))
  ... (:q ((not (null (cdr d))) " ")))))
Repeating the test makes it unable to use the much more readable DOLIST instead of DO, and therefore must also use (CAR d) to access the elements.

Reading the full paper (ytools) instead of the short FORMAT critique, it appears to me that OUT is no silver bullet either. It has its own set of controls: :a, :e, :t, :i>, :i<, :f, :v, :pp-block etc., so it's still complex to grok.
I found the difference more appealing between e.g. the sexp-based regular expression notation (IIRC there's a Scheme SRFI about it) that the error-prone flat string syntax. 

BTW, McDermott's diver&snorkeler macro design pattern is interesting.

Regards,
	Jörg Höhle



More information about the iterate-devel mailing list