From: Timothy J. H. <tim...@ma...> - 2004-04-07 20:14:07
|
On Apr 7, 2004, at 2:35 PM, Borislav Iordanov wrote: > 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!")) Not quite.... (my-delay (display "Hi there!") ---> (delay (display "Hi there!")) The quasiquote and unquote are interepreted in the define-macro environment where form is bound to the term (display "Hi there!") So in more detail, with environments you would have Env | (my-delay form) --> (Env,{form=(display "Hi there!")} | (E `(delay ,form))) --> (Env,{form=(display "Hi there!")} | (E (list 'delay '(display "Hi there!")))) --> (Env,{form=(display "Hi there!")} | (E `(delay (display "Hi there!")))) --> (Env} | (delay (display "Hi there!"))) where E is an operator that evaluates the term in the current environment I don't know if this is helpful. Its halfway between an informal explanation and a formal semantics..... > > which is then evaluated to yield the promise. So the 'promise' define > above should be equivalent to: > > (define promise (eval `(delay ,(display "Hi there!")))) The explanation above was to show why this line is incorrect.... Your unquote is taking place in the wrong environment.... Does this help? ---Tim--- > > 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 > | > | > |