On Sat, May 30, 2015 at 03:42:41PM +0200, Michele La Monaca wrote: > On Sat, May 30, 2015 at 4:23 AM, John Cowan <co...@mercury.ccil.org> wrote: > > Jinsong Liang scripsit: > > > >> I want to learn some basic macro programming in Chicken. However, it seems > >> there are multiple macro definition APIs in Chicken: define-syntax, > >> syntax-rules, syntax-case, define-macro. Which one should I start with? > > > > Define-macro is completely obsolete and not supported in Chicken 4 or > > any modern Scheme. > > Gambit has it. Too bad Chicken 4 dropped it. > > I don’t think describing define-macro "obsolete” is 100% correct.
As has been pointed out time and again, it is fundamentally broken. See also below: > Let’s say someone had the (bad?) idea to masquerade/embed it in other > more baroque forms. For example in Chicken you have to write: > > (define-syntax apply-any > (er-macro-transformer > (lambda (form rename compare) > (let ((x (cadr form)) (lst (caddr form))) > (eval `(cons ',x ,lst)))))) > > instead of: > > (define-macro apply-any > (lambda (x lst) > (eval `(cons ‘,x ,lst)))) Looks like you are mixing up two things: on one hand, define-macro offers the syntactic convenience of not having to pick apart the input form. On the other hand, define-macro does not support hygienic renaming at all (except for gensym, which only works on identifiers created by the macro itself). If it's the syntactic convenience you're after, take a look at the "bindings" egg by Juergen Lorenz. It offers various improvements on the basic er-macro-transformer and ir-macro-transformer syntax. > Oh, and it is quite powerful. I’ve used Gambit to > practice. Only when you dominate it, I suggest to move on to > syntax-rules. The latter works at a higher layer (see below), enforces > hygiene and introduces you to pattern matching (which is not a macro > specific topic). > > (define-syntax apply-any > (syntax-rules () > ((_ x lst) (eval (cons 'x lst))))) > > (define l '(#f (+ 1 2) (print "hello"))) > > (apply-any or l) > > => 3 > > (apply-any + (list 1 2 3)) > > => 6 > > (let ((x 9)) (apply-any or '(#f (+ x 1) (print "hello")))) > > Error: unbound variable: x > > Oops. Eval does not have access to the lexical scope where it is invoked. Cheers, Peter
signature.asc
Description: Digital signature
_______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users