unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: Andy Wingo <wingo@pobox.com>
Cc: guile-devel <guile-devel@gnu.org>
Subject: Re: summary: lilypond, lambda, and local-eval
Date: Fri, 16 Dec 2011 05:33:09 -0500	[thread overview]
Message-ID: <871us4kdqy.fsf@netris.org> (raw)
In-Reply-To: <87liqcamrf.fsf@pobox.com> (Andy Wingo's message of "Fri, 16 Dec 2011 10:28:36 +0100")

Hi Andy, thanks for the quick feedback.  I'll respond to the rest of
your email later, but just a few quick notes for now:

> What are the meanings of these expressions:
>
>   ;; Toplevel
>   (local-eval '(define foo 42) (the-environment))
>
>   ;; Lexical, tail context
>   (local-eval '(define foo 42) (let ((x 100)) (the-environment)))
>
>   ;; Lexical, tail context -- but with a definition
>   (local-eval '(begin (define foo 42) foo) (let ((x 100)) (the-environment)))
>
>   ;; Lexical, tail context -- but with a definition, and nested reference
>   (local-eval '(begin (define foo 42) (bar))
>               (let ((x 100)) (define (bar) foo) (the-environment)))
>
>   ;; Lexical, not a definition context
>   (local-eval '(define foo 42) (let ((x 100)) not-a-definition (the-environment)))

All of these will raise errors, because my current implementation of
`local-eval' (I just posted a new version of the evaluator-only patch)
uses `expand' instead of `expand-top-sequence' to expand the local
expression, therefore definitions are not allowed.

> What about this one:
>
>   ;; Keeping in mind that `or' expands to (let ((t ...)) (if t t ...)),
>   ;; hygienically
>   (local-eval 't '(let ((t 42)) (or #f (the-environment))))

Yes, even my first patch handles this properly (though you must use
`primitive-eval', since the compiler currently barfs if it encounters
`the-environment'):

scheme@(guile-user)> (local-eval 't (primitive-eval '(let ((t 42)) (or #f (the-environment)))))
$1 = 42

> Can you pass syntax objects into `local-eval'?

I believe so, but I haven't verified that this works as it should.
I don't have much experience using syntax-case.

The expression passed to `local-eval' simply gets passed along to
`expand' within psyntax.scm, using the saved "expander environment":
i.e. the values of the `r', `w', and `mod' in psyntax, at the point
where (the-environment) was expanded.  This "expander environment" is
stored in the tree-il representation of (the-environment).

Here's what I currently see:

scheme@(guile-user)> (local-eval #'t (primitive-eval '(let ((t 42)) (or #f (the-environment)))))
ERROR: In procedure memoize-variable-access!:
ERROR: Unbound variable: t

This is the correct behavior, no?

> Are let-syntax / letrec-syntax / nested define-syntax forms present in a
> local environment?

Yes:

scheme@(guile-user)> (define env1 (primitive-eval '(let-syntax ((foo (syntax-rules () ((foo x) (quote x))))) (let ((x 1) (y 2)) (the-environment)))))
scheme@(guile-user)> (local-eval '(foo (1 2)) env1)
$3 = (1 2)
scheme@(guile-user)> (define env2 (local-eval '(let-syntax ((bar (syntax-rules () ((bar x) (foo x))))) (let ((x 1) (z 3)) (the-environment))) env1))
scheme@(guile-user)> (local-eval '(bar (1 2)) env2)
$5 = (1 2)
scheme@(guile-user)> (local-eval '(foo (1 2)) env2)
$6 = (1 2)

> Currently these things never leave the expander.  I suppose as long as
> they are understood to be opaque, it would be OK.

Agreed.  However, it should be noted that if we compile a form
containing (the-environment) into a .go file, the "expander environment"
will have to be stored within the .go file as an embedded constant.
This means that if the representations of r, w, or mod within psyntax
changes, any .go files containing uses of (the-environment) will have to
be recompiled, or else `local-eval' could fail ungracefully.

This is indeed an unpleasant complication.  Automatic recompilation
could be achieved using a versioning scheme, using a separate
expander-environment-version number.  With some care, we could perhaps
avoid needless recompilation of .go files that do not use
(the-environment) when the expander environment version changes, though
it might be a bit of a pain to do the necessary bookkeeping to determine
whether a .go file contains any expander environments.  I'll have to
think more about this.

     Mark



  parent reply	other threads:[~2011-12-16 10:33 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-15 10:21 summary: lilypond, lambda, and local-eval Andy Wingo
2011-12-15 14:46 ` David Kastrup
2011-12-15 16:52 ` Hans Aberg
2011-12-15 17:24   ` David Kastrup
2011-12-15 17:52     ` Hans Aberg
2011-12-16  7:35 ` Mark H Weaver
2011-12-16  8:08   ` Mark H Weaver
2011-12-16  8:49   ` Mark H Weaver
2011-12-16  9:16     ` David Kastrup
2011-12-18  7:11     ` Mark H Weaver
2011-12-18 11:27       ` Andy Wingo
2011-12-18 15:32         ` Noah Lavine
2011-12-18 16:19           ` David Kastrup
2011-12-18 21:24             ` Noah Lavine
2011-12-19  9:13         ` Mark H Weaver
2012-01-09 14:44           ` David Kastrup
2011-12-16  9:28   ` Andy Wingo
2011-12-16  9:59     ` David Kastrup
2011-12-16 10:33     ` Mark H Weaver [this message]
2011-12-16 12:13       ` Hans Aberg
2011-12-16 12:43         ` David Kastrup
2011-12-16 14:57           ` Hans Aberg
2011-12-21 10:32 ` Ian Hulin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871us4kdqy.fsf@netris.org \
    --to=mhw@netris.org \
    --cc=guile-devel@gnu.org \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).