do iterator

Started by Jeff, March 11, 2008, 07:40:12 AM

Previous topic - Next topic

Jeff

For your enjoyment, here is a do macro like in common lisp (note, it is actually more like do*, since it uses letn, rather than let in its expansion):


(define-macro (do)
  (letex ((iter-forms (args 0))
 (break (args 1 0))
 (result (args 1 1))
 (body (cons begin (rest (rest (args))))))
(letex ((init-forms (map (fn (form) (0 2 form)) 'iter-forms))
(update-symbols (reverse (map first 'iter-forms)))
(update-values (reverse (map last 'iter-forms))))
 (letn init-forms
(do-until break body
 (map set 'update-symbols
  (map eval 'update-values)))
result))))


This is something that I feel is really missing from newLISP.  Except in specialized cases like dolist, iteration is more likely to be over multiple variables.  The format of this is similar to for (without the step value), with multiple init/update expressions, then a list of the break-condition expression and the result expression.



Here is an example of factorial (from Ansi Common Lisp) using this do.  It doesn't even have a body, because the update forms do all the work.  I've included a comment where the body would be.


(define (factorial n)
  (do ((j n (- j 1))
  (f 1 (* j f)))
 ((= j 0) f)
    ; (println j ", " f)
  ))

(println (factorial 10))
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

cormullion

#1
Cool. From a quick look, I'm guessing that the syntax in newLISP-reference-manual style is this:



(do ((sym1 num-from1 num-to1) (sym2 num-from2 num-to2) ... ) (exp-break result) body)



I agree that this would be useful! I'll try it out later...

Jeff

#2
(do ((sym1 init-form1 update-form1) [(sym2 init-form2 update-form2) ...]) (exp-break sym-result) (expr-body*))
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

cormullion

#3
Perfect!

newdep

#4
Tight coding Jeff! ..and it itters through nested lists as far as I can check...
-- (define? (Cornflakes))

Jeff

#5
It just does the same thing as for, but over multiple variables, with a stop condition, and control over the return value.  I hope it's useful.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code