|
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
> |
> |
>
|