From: Borislav I. <bor...@ko...> - 2004-04-07 18:35:15
|
Hi Tim, Thanks very much for the explanation. However, I must admit that the workings of those macros are a bit confusing to me. I can stupidly remember to unquote the macro arguments in a returned s-expression, but I don't quite understand why and how it works. Ok, define-macro returns an s-expression which will _then_ be evaluated. So when a macro is applied, the s-expression is first constructed from the macro definition and then it is passed to the evaluator. So with the following macro: (define-macro (my-delay form) `(delay ,form)) If I write: (define promise (my-delay (display "Hi there!"))) what is happening is that first an s-expression is constructed: `(delay ,(display "Hi there!")) which is then evaluated to yield the promise. So the 'promise' define above should be equivalent to: (define promise (eval `(delay ,(display "Hi there!")))) But evaluating the above expression prints the string "Hi there!" as one would expect because (display ...) is unquoted inside the quasiquotation. Evaluating (my-delay (display "Hi there!")) doesn't display anything which is the intent, but I don't understand why? Given the implied model of macro expansion (i.e. build an s-expression, then evaluate it). Thanks, Boris | -----Original Message----- | From: Timothy John Hickey [mailto:tim...@ma...] | Sent: Wednesday, April 07, 2004 9:38 AM | To: Borislav Iordanov | Cc: jsc...@li... | Subject: Re: [Jscheme-user] a little problem with define-macro | | | | On Apr 7, 2004, at 12:27 AM, Borislav Iordanov wrote: | | > Hi, | > | > I tried using define-macro (i.e. the built in macros) to simplify | > working with streams thus: | > | >> (define-macro (make-stream h t) (cons h (delay t))) | > (macro make-stream (h t)...) | | The define-macro should return an s-expression which will | then be evaluated: | | (define-macro (make-stream h t) `(cons ,h (delay ,t))) | | This works fine with enum. The quasiquoted expression | could also be written with standard quote as | | (define-macro (make-stream h t) (list 'cons h (list 'delay t))) | | which would work as well, but is harder to read... | | ---Tim--- | | | > | > But then: | > | >> (define (enum start end) | > (if (> start end) '() (make-stream start (enum (+ start | 1) end)))) | > | > SchemeException: expected object of type list (i.e. pair or empty), | > but | > got: , " | > (lambda delay~3 ()...)" | > at jsint.E.error(E.java:14) | > at jsint.E.typeError(E.java:24) | > at jsint.U.toList(U.java:180) | > at jsint.U.listToVector(U.java:772) | > at jsint.Scheme.analyze(Scheme.java:487) | > at jsint.Scheme.analyze(Scheme.java:475) | > at jsint.Scheme.analyze(Scheme.java:490) | > at jsint.Scheme.analyze(Scheme.java:473) | > at jsint.Scheme.analyze(Scheme.java:459) | > at jsint.Scheme.analyze(Scheme.java:490) | > at jsint.Scheme.analyze(Scheme.java:490) | > at jsint.Scheme.analyze(Scheme.java:475) | > at jsint.Scheme.eval(Scheme.java:434) | > at jsint.Scheme.eval(Scheme.java:424) | > at jsint.Scheme.readEvalWriteLoop(Scheme.java:208) | > at jsint.Scheme.runJscheme(Scheme.java:186) | > at jsint.Scheme.defaultMain(Scheme.java:149) | > at jsint.Scheme.main(Scheme.java:124) | > at jscheme.REPL.main(REPL.java:138) | > | > | > If expand "manually" the macro: | > | > (define (enum start end) | > (if (> start end) '() (cons start (delay (enum (+ start | 1) end))))) | > | > there is no problem. | > | > BTW, it also works with define-syntax macros.. | > | > Best, | > Boris | > | > | > | > ------------------------------------------------------- | > This SF.Net email is sponsored by: IBM Linux Tutorials | > Free Linux tutorial presented by Daniel Robbins, President | and CEO of | > GenToo technologies. Learn everything from fundamentals to system | > | administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click | > _______________________________________________ | > Jscheme-user mailing list | > Jsc...@li... | > https://lists.sourceforge.net/lists/listinfo/jscheme-user | | |