From 419532e133f79c256893e6a57e883ad9de7b034e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 26 Feb 2014 22:12:26 -0800 Subject: * eval.c (gun_s): New global variable. (me_gun): New static function. (eval_init): New gun symbol interened, me_gun registered as intrinsic macro. * txr.1: Documented gun. --- txr.1 | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'txr.1') diff --git a/txr.1 b/txr.1 index 309a5cd9..f94af99d 100644 --- a/txr.1 +++ b/txr.1 @@ -7973,12 +7973,13 @@ Description: The repeat function produces an infinite lazy list formed by the repeatedly cycled catenation of the argument lists. -.SS Macro gen +.SS Macros gen and gun .TP Syntax: (gen ) + (gun ) .TP Description: @@ -8000,6 +8001,34 @@ producing the lazy list. If the expression yields nil, then the operator returns the empty list nil. Otherwise, it instantiates the lazy list and invokes the to force the first item. +The gun macro similarly creates a lazy list according to the following +rules. Each successive item of the lazy list is obtained as a result of +evaluating . However, when +yields nil, then the list terminates (without adding that nil as an item). + +Note 1: the form gun can be implemented as a macro-expanding to +an instance of the gen operator, like this: + + (defmacro gun (expr) + (let ((var (gensym))) + '(let (,var) + (gen (set ,var ,expr) + ,var)))) + +This exploits the fact that the set operator returns the value that is +assigned, so the set expression is tested as a condition by gen, +while havin the side effect of storing the next item temporarily +in a hidden variable. + +In turn, gen can be implemented as a macro expanding to some lambda +functions which are passed to the generate function: + + (defmacro gen (while-expr produce-expr) + '(generate (lambda () ,while-expr) (lambda () ,produce-expr))) + +Note 2: GEN can be considered as an acronym for Generate, testing Expression +before Next item, whereas GUN stands for Generate Until Null. + .TP Example: -- cgit v1.2.3