unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
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 --]

  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).