loop

Mit dem Macro loop können mehrere Ausdrücke wiederholt ausgeführt werden.

(loop <statement> ...)

Alle Argumente des Macros gehen in den Rumpf der Schleife ein. Die Ausdrücke werden solange ausgeführt, bis

(return <expr>)

innerhalb des Rumpfs ausgewertet wird. Dann endet die Schleife und der Wert von <expr> wird als Wert des loop-Ausdrucks zurück gegeben.

Dieses Beispiel summiert die Ganzzahlen von 1 bis 100:

(let
  ((sum 0)
   (index 1))
  (loop
    (setq sum (+ sum index))
    (when (greater? index 99) (return sum))
    (setq index (+ 1 index))))
> 5050

Das Macro basiert im Wesentlichen auf let, letrec, catch, throw, lambda und progn:

(setq loop
  (mlambda args
    (let
      ((continue (gensym))
       (break (gensym)))
      (quasi-quote
        (catch (quote (unquote break))
          (letrec
            ((return
              (lambda (result) (throw (quote (unquote break)) result)))
             ((unquote continue)
              (lambda ()
                (progn
                  (unquote (cons (quote progn) args))
                  ((unquote continue))))))
            ((unquote continue))))))))