From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.devel Subject: Re: summary: lilypond, lambda, and local-eval Date: Fri, 16 Dec 2011 05:33:09 -0500 Message-ID: <871us4kdqy.fsf@netris.org> References: <87r506uodd.fsf@pobox.com> <87pqfpj7e3.fsf@netris.org> <87liqcamrf.fsf@pobox.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1324031708 8319 80.91.229.12 (16 Dec 2011 10:35:08 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 16 Dec 2011 10:35:08 +0000 (UTC) Cc: guile-devel To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Fri Dec 16 11:35:04 2011 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RbV81-0004Pc-Ap for guile-devel@m.gmane.org; Fri, 16 Dec 2011 11:35:01 +0100 Original-Received: from localhost ([::1]:59431 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RbV7z-0001dO-NF for guile-devel@m.gmane.org; Fri, 16 Dec 2011 05:34:59 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:46051) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RbV7s-0001dJ-NM for guile-devel@gnu.org; Fri, 16 Dec 2011 05:34:58 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RbV7r-0005b8-7l for guile-devel@gnu.org; Fri, 16 Dec 2011 05:34:52 -0500 Original-Received: from world.peace.net ([96.39.62.75]:40096) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RbV7q-0005aW-Qt for guile-devel@gnu.org; Fri, 16 Dec 2011 05:34:51 -0500 Original-Received: from 209-6-91-212.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.91.212] helo=yeeloong) by world.peace.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1RbV7h-00082y-My; Fri, 16 Dec 2011 05:34:42 -0500 In-Reply-To: <87liqcamrf.fsf@pobox.com> (Andy Wingo's message of "Fri, 16 Dec 2011 10:28:36 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 96.39.62.75 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:13134 Archived-At: 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