From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Tom Lord Newsgroups: gmane.lisp.guile.devel Subject: Re: Internal defines Date: Mon, 10 Nov 2003 19:11:18 -0800 (PST) Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <200311110311.TAA22963@morrowfield.regexps.com> References: <3FAEC259.302@dirk-herrmanns-seiten.de> <87ekwf63xu.fsf@raven.i.defaultvalue.org> NNTP-Posting-Host: deer.gmane.org X-Trace: sea.gmane.org 1068519652 2759 80.91.224.253 (11 Nov 2003 03:00:52 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 11 Nov 2003 03:00:52 +0000 (UTC) Cc: guile-devel@gnu.org, mvo@zagadka.de Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Tue Nov 11 04:00:50 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AJOlt-0006id-00 for ; Tue, 11 Nov 2003 04:00:49 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AJPiO-0007fy-Ge for guile-devel@m.gmane.org; Mon, 10 Nov 2003 23:01:16 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1AJPiF-0007So-J3 for guile-devel@gnu.org; Mon, 10 Nov 2003 23:01:07 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1AJPey-0006CG-Gb for guile-devel@gnu.org; Mon, 10 Nov 2003 22:58:16 -0500 Original-Received: from [65.234.195.251] (helo=morrowfield.regexps.com) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AJPek-0005aG-QB for guile-devel@gnu.org; Mon, 10 Nov 2003 22:57:31 -0500 Original-Received: (from lord@localhost) by morrowfield.regexps.com (8.9.1/8.9.1) id TAA22963; Mon, 10 Nov 2003 19:11:18 -0800 (PST) (envelope-from lord@morrowfield.regexps.com) Original-To: rlb@defaultvalue.org In-reply-to: <87ekwf63xu.fsf@raven.i.defaultvalue.org> (message from Rob Browning on Mon, 10 Nov 2003 20:21:01 -0600) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.2 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 Xref: main.gmane.org gmane.lisp.guile.devel:2990 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:2990 Dirk wrote: According to R5RS, the body of a form like lambda, let, let* etc. looks like follows: --> * --> * --> --> (define ) | (define ( ) ) | (begin *) That is, it starts with zero or more definitions followed by one or more expressions. The definition forms must start with the literal symbol 'define' or 'begin', which may enclose further definitions or begin forms. In any case, there is no mentioning of macro expansion here. Dirk is wrong. (By striking coincidence, I recently spent about 6 hours figuring this out myself. In my personal experience, it is hella easy to be wrong on this topic :-) R5RS is not strikingly crystal clear on this matter, but it _does_ speak of macro expansion in this context and actually provides a coherent and reasonable semantic. The critical section is "5.3 Syntax definitions": Although macros may expand into definitions and syntax definitions in any context that permits them, it is an error for a definition or syntax definition to shadow a syntactic keyword whose meaning is needed to determine whether some form in the group of forms that contains the shadowing definition is in fact a definition, or, for internal definitions, is needed to determine the boundary between the group and the expressions that follow the group. For example, the following are errors: Key here is "macros may expand into definitions and syntax definitions in _any_ context that permits them" [emphasis added]. Thus, this is quite legal: (let-syntax ((foo (syntax-rules () ((foo (proc args ...) body ...) (define proc (lambda (args ...) body ...)))))) (let ((x 3)) (foo (plus x y) (+ x y)) (define bar x) (plus bar x))) => 6 (which contradicts Dirk's reading). On the other hand, as noted by the spec, this is "an error" (let-syntax ((foo (syntax-rules () ((foo (proc args ...) body ...) (define proc (lambda (args ...) body ...)))))) (let ((x 3)) (foo (plus x y) (+ x y)) (define foo x) (plus foo x))) because, looking at the contents of the LET, we can expand FOO and realize that that is apparently a definition, but the subsequent DEFINE of FOO undermines that interpretation since it's scope encompasses the apparent macro-use of FOO (c.f. the "determining boundaries" foo in the language from 5.3 quoted above). Guile currently does not detect that error and simply returns 6 for the second, error-laden, form. Thus, Guile's conformance is saved in this instance by the distinction between "is an error" and "an error is signaled". It is _slightly_ intimidating to think of what would be required of an implementation, especially an SCM-derived implementation, to actually detect that error. Overall, Guile suffers from the sin of SCM -- of not making expansion and evaluation separate phases. Whether or not the unambiguous (but obscure) english language of 5.3 is born out by the "authoritative" denotational semantics is a question I haven't investigated. But I think it is crystal clear (once the subtleties understodd) that if the denotational semantics do not support 5.3 then the denotational semantics have a bug. There _is_, denotational semantics notwithstanding, a quite clear operational interpretation here in which the successive forms in the "body" (not ) of the LET are expanded and then interpreted. However, to actually detect and report the "an error", the operational semantics has to include an observence of what head forms arise during the expansion of forms that might or might not be part of the s of the LET. -t _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel