From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Frank Terbeck Newsgroups: gmane.lisp.guile.devel Subject: Re: Recursive Macros generating Definitions Date: Mon, 03 Oct 2022 15:41:04 +0200 Message-ID: <87lepxkosv.fsf@ft.bewatermyfriend.org> References: <87zgedkuqc.fsf@ft.bewatermyfriend.org> <939c81ae-5b12-1910-5fbd-8ad99a697da6@telenet.be> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="19281"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: guile-devel@gnu.org To: Maxime Devos Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Mon Oct 03 15:42:03 2022 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ofLhr-0004u9-Ky for guile-devel@m.gmane-mx.org; Mon, 03 Oct 2022 15:42:03 +0200 Original-Received: from localhost ([::1]:35264 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ofLhq-0002c1-9q for guile-devel@m.gmane-mx.org; Mon, 03 Oct 2022 09:42:02 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:40244) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ofLhC-0002bY-O5 for guile-devel@gnu.org; Mon, 03 Oct 2022 09:41:22 -0400 Original-Received: from smtprelay03.ispgateway.de ([80.67.31.30]:27906) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ofLhA-00021w-TA for guile-devel@gnu.org; Mon, 03 Oct 2022 09:41:22 -0400 Original-Received: from [62.155.197.123] (helo=jim.voodoo.lan) by smtprelay03.ispgateway.de with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1ofLhW-0002LB-TS; Mon, 03 Oct 2022 15:41:42 +0200 Original-Received: by jim.voodoo.lan (Postfix, from userid 1000) id E460863583D; Mon, 3 Oct 2022 15:41:04 +0200 (CEST) In-Reply-To: <939c81ae-5b12-1910-5fbd-8ad99a697da6@telenet.be> (Maxime Devos's message of "Mon, 3 Oct 2022 14:48:39 +0200") X-Df-Sender: NDMwNDQ0 Received-SPF: none client-ip=80.67.31.30; envelope-from=ft@bewatermyfriend.org; helo=smtprelay03.ispgateway.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 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-mx.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.io gmane.lisp.guile.devel:21381 Archived-At: Hey Maxime! Maxime Devos wrote: > On 03-10-2022 13:32, Frank Terbeck wrote: >> When looking at this, I also saw the following, which might be related >> if =E2=80=98syntax-rules=E2=80=99 is implemented using =E2=80=98syntax-= case=E2=80=99 > > It is, IIRC. > >> (I didn't check if >> this is the case): >> (define-syntax-rule (foobar n) (define quux n)) >> ,exp (foobar 23) >> =E2=86=92 (define quux-ea7bdcf8675f4a4 23) > > This is correct (as in, functioning as intended and not a bug) to my > understanding -- in the match expression of 'foobar', 'quux' does not app= ear, > so the for hygiene, the 'quux' inside shouldn't be the quux outside. [=E2=80=A6] > It's sometimes a bit inconvenient -- sometimes you _want_ to define 'quux= ' (and > not just only available to the macro), but that's easily resolved by addi= ng an > additional 'quux' argument to 'foobar': > > (define-syntax-rule (foobar quux n) (define quux n)) > ,exp (foobar quux 23) I get the point, but I think it's sort of surprising, when everything in the macro-language is otherwise quite literal, to my understanding. It may be warranted to point this out in the documentation that this is a side effect of hygienic macros, I think. >> (define-syntax generate-shorthands [...] > > Your recursive macro is, well, recursive. This is fine, but IIUC a conse= quence > of this is that the recursive 'call' to generate-shorthands is a new lexi= cal > lexical environment (hence, hygience, so -?????? stuff). > > As such, I consider this not a bug in Guile, but a bug in your code. > > My proposal would be to change the 'x' in (datum->syntax x) -- instead of= using > #'x (which refers to the whole expression, which in a recursive call has = an > undesired lexical environment), use something of the 'end-user' of > generate-shorthands, say, #'s (i.e., SEMANTICS-SYMBOL) (for the right lex= ical > environment). > > If I make that change, I get some reasonable output (no -????? suffixes): > > $1 =3D (begin > (define (varint:sint32-decode bv) > (varint-decode bv 32 zig-zag)) > (define (varint:sint32-encode n) > (varint-encode n 32 zig-zag))) Thanks, this does work indeed! So, clearly I don't fully understand the first argument to =E2=80=98datum->syntax=E2=80=99, because I thought =E2=80=98x=E2=80=99 wo= uld be exactly right since I thought it captured the context of where the macro was called in the original code. But every time, I perform an indirection through recursion, the context captured by =E2=80=98x=E2=80=99 is bound to somethin= g new, that's in the context of the outer level of macro expansion. If I understand this correctly, using #'s here, refers to something that was created at the source level of where the initial expansion of the macro happened. If that is the case, is it correct, that it doesn't really matter whether I used #'s or #'w. And that seems to be the case. And if I wanted to do this: ((op s w) (let ((base (make-base-name #'s #'w))) (with-syntax ((enc (datum->syntax #'op (symbol-append base '-encode))) (dec (datum->syntax #'op (symbol-append base '-decode)))) #'(begin (define (dec bv) (varint-decode bv w s)) (define (enc n) (varint-encode n w s)))))) =E2=80=A6I'd still end up with the -HEX amended symbol names, because i= n the recursing cases, I am using a literal =E2=80=98generate-shorthands=E2=80= =99 symbol. But if I'd do this: ((op (sems ...) (widths ...)) #'(begin (op sems (widths ...)) ...)) ((op sem (widths ...)) #'(begin (op sem widths) ...)) It should work, because =E2=80=98op=E2=80=99 always refers to the syntacti= c object used at the source level, where the user used the macro, which means that in the base-case, the =E2=80=98op=E2=80=99 template variable still refers to= the original source position, so the scopes match up correctly, so that the intro- duced bindings don't have to be amended for hygiene. In hindsight, I should have sent this to -users after all. :) This behaviour is probably explained in one of the =E2=80=98syntax-case= =E2=80=99 and =E2=80=98datum->syntax=E2=80=99 examples in the manual, but it wasn't cl= ear to me at all. Not sure how, but I think there's room for improvement here. :) Thanks for clearing this up! And feel free to correct anything I got wrong in what I wrote in the above. Regards, Frank