From: Jean Abou Samra <jean@abou-samra.fr>
To: Maxime Devos <maximedevos@telenet.be>,
yarl baudig <yarl-baudig@mailoo.org>,
guile-devel@gnu.org
Subject: Re: define-module, #:export and export
Date: Thu, 5 Jan 2023 03:07:10 +0100 [thread overview]
Message-ID: <b5718ab1-57b0-ef9c-093c-73f50248b4ba@abou-samra.fr> (raw)
In-Reply-To: <7848ba66-4ab6-ba9f-c930-bb99ae2542e7@telenet.be>
[-- Attachment #1.1: Type: text/plain, Size: 3103 bytes --]
Le 04/01/2023 à 18:28, Maxime Devos a écrit :
> On 04-01-2023 16:11, yarl baudig wrote:
>> Hello guile.
>>
>> I don't know if that's a bug. Anyway, I am confused about this so I
>> ask. I came across this problem playing with guix source code. I will
>> share different "tests" each test is a directory with nothing but the
>> files I share.
>> each time the command to try the test (inside it's directory) is
>> `guile --no-auto-compile -L . main.scm`
>> [...]
> My (untested) hypothesis (*: things I'm unsure about)
>
> If there is no #:export (...), then when
> (define-operation (valid-path?)) is expanded, the identifier
> 'valid-path?' is free (*).
>
> Hence, the following ...
>
> > (syntax-rules (name ...)
> > ((_ name) id) ...)))))
>
> refers to the free identifier 'valid-path?'.
>
> Conversely, if there is #:export, then the (syntax-rules (name ...)
> ...) looks for the bound identifier 'valid-path?' (*).
>
> Important: bound identifiers != free-identifier, even if they have the
> same symbol! For (simple-format #t "~S\n" (operation-id valid-path?))
> to work, the 'valid-path?' of that expression must be bound if the
> syntax-rules looks for a bound identifier, and free if it looks for a
> free identifier.
That is also my understanding, confirmed by
$ cat lib.scm
(define-module (lib)
#:export (test))
(define-syntax test
(lambda (sintax)
(syntax-case sintax ()
((test id)
(datum->syntax sintax (free-identifier=? #'id #'thing))))))
$ cat test.scm
(define-module (main)
#:use-module (lib)
#:export (thing)
)
(display (test thing))
(newline)
(define thing 5)
$ guile3.0 -L . test.scm
#f
If you comment out #:export (thing), the result changes to #t.
To put it perhaps more simply, the use of #:export causes Guile to
understand early that there will be a variable 'thing' in this module,
and makes the identifier 'thing' refer to this variable that is not yet
defined. However, hygiene implies that you want to be able to use
keywords as if they were not keywords if they are rebound, e.g. the
'else' here doesn't cause the cond clause to be taken:
(let ((else #f)) (cond (#f 'bla) (else 'foo) (#t 'bar)))
$1 = bar
The way this is done is by comparing with the original identifier given
to syntax-rules. Technically, they are compared with free-identifier=? .
This means that a use of the identifier matches the keyword iff both are
unbound, or both are bound to the same lexical binding. However, this
isn't the case here, as the keyword in the macro was unbound, but at the
point of use, it has been bound by #:export.
Honestly, I think it is better to choose a different way of writing
these macros that avoids this confusing issue. Try defining the
operations at the same time as the enum so that the macro giving an enum
member refers to the bindings of the operators. If you give more context
on what you're trying to do, we could help more.
Best,
Jean
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
next prev parent reply other threads:[~2023-01-05 2:07 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-04 15:11 define-module, #:export and export yarl baudig
2023-01-04 17:28 ` Maxime Devos
2023-01-05 2:07 ` Jean Abou Samra [this message]
2023-01-06 13:31 ` yarl baudig
2023-01-06 13:55 ` Maxime Devos
2023-01-07 16:24 ` Jean Abou Samra
2023-01-08 9:46 ` yarl baudig
2023-01-08 13:19 ` Jean Abou Samra
2023-01-08 15:18 ` yarl baudig
2023-01-08 15:23 ` Jean Abou Samra
2023-01-13 7:58 ` yarl baudig
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=b5718ab1-57b0-ef9c-093c-73f50248b4ba@abou-samra.fr \
--to=jean@abou-samra.fr \
--cc=guile-devel@gnu.org \
--cc=maximedevos@telenet.be \
--cc=yarl-baudig@mailoo.org \
/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).