From: Mikael Djurfeldt <mikael@djurfeldt.com>
To: Daphne Preston-Kendal <dpk@nonceword.org>
Cc: guile-devel@gnu.org, Mikael Djurfeldt <mikael@djurfeldt.com>
Subject: Re: Proposal: Identifier properties for Guile
Date: Tue, 17 Sep 2024 10:40:50 +0200 [thread overview]
Message-ID: <CAA2XvwKs7_0MPxXGRtn3RNH9wz5RRezVSSmG8xZaa3WsGnZmWQ@mail.gmail.com> (raw)
In-Reply-To: <05A7E253-3DFB-4CA8-A257-353BD5FB650F@nonceword.org>
Dear Daphne,
What you propose sounds exciting! I also think that you have the right
background to pull this off in a nice way.
Obviously, Andy Wingo should give his view on this, but I thought that
your message should have some response. :-)
Best regards,
Mikael Djurfeldt
On Tue, Sep 10, 2024 at 11:08 PM Daphne Preston-Kendal
<dpk@nonceword.org> wrote:
>
> Hi!
>
> I want to implement identifier properties a la SRFI 213 in Guile’s
> psyntax.
> <https://srfi.schemers.org/srfi-213/srfi-213.html>
> These will be in R7RS Large (in the fascicle on macros coming out Real
> Soon Now), and are in fact the only major macro feature Guile is
> missing from R7 Large.
>
> I want to gather feedback on my proposed strategy to implement these
> into Guile before starting work. Along the way, I’ll explain some
> nuances of the semantics which the SRFI explains very badly (the
> fascicle on macros completely redid the text).
>
> First of all, why would you want identifier properties? As an
> admittedly pretty advanced macrologist, I’m convinced these are the
> best things since sliced bread. I’ve gathered some example use cases
> here:
> <https://codeberg.org/scheme/r7rs/wiki/Identifier-property-use-cases>
> and in fact the second use case is no longer a hypothetical as it was
> when I wrote that page, because I have actually implemented it:
> <https://codeberg.org/dpk/extensible-match>
> Getting that library working in Guile and Hoot is my main personal
> motivation for wanting this feature – apart from wanting to see an
> implementation support the R7-large spec which I wrote ;-)
>
> Identifier properties are fundamentally very similar to transformer
> bindings, and pose some of the same challenges. The main difference is
> that identifier properties are attached in addition to a binding,
> rather than changing the regular Scheme semantics of the binding.
> But like transformer bindings, it makes sense to divide them into
> top-level (module-level, in Guile) property definitions and local
> definitions.
>
> The latter are easier to deal with because they don’t need to touch
> the module system. The expander gets rid of them in the same way it
> gets rid of let-syntax; expanded code doesn’t need to care about them
> any more.
>
> Implementing this means changing the expander’s idea of a wrap so that
> it contains property bindings, much as has been done in Chez’s version
> of psyntax:
> <https://github.com/cisco/ChezScheme/blob/658e0b152abe3bc4ba889883d4dc218fef093aef/s/syntax.ss#L892>
> This is a non-obtrusive change entirely localized to the expander as
> it exists in a live Guile system. I don’t see any major issues here or
> have any questions.
>
> When we get to module-level property bindings, things get trickier.
> I’d like a bit of guidance here. First, to clarify the SRFI:
> identifier properties, as the name suggests, are attached to
> identifiers in the sense of define/import/export. If you import an
> identifier from module A which the unrelated module B has attached a
> property to, you won’t see that property – unless you *also* re-import
> the same identifier from module B. Identifiers are organized, though,
> by keys, which themselves look like identifiers but those identifiers
> are actually used only for their bindings in the sanse of
> ‘free-identifier=?’. (Keys have to be defined – the fallback to
> symbolic comparison doesn’t apply here.)
>
> To support this I will have to extend the definition of a module in
> boot-9.scm to add, effectively, a second obarray – this one mapping
> variables to mappings of bindings to property values, rather than
> variables to values directly. However, it looks to me like there is
> some duplicate definition between C and Scheme here, and I would also
> need to update libguile/modules.c to at least be aware of the new
> structure, and probably write the property mapping code in C there as
> well to make it work as I describe below. Is this a correct
> assumption?
>
> Looking at how syntax transformers work in the current code, the
> ‘define-property’ form will probably have to be considered primitive
> down to a fairly low level. As I understand it from looking at
> expansion and disassembly, (define-syntax x y) first expands into
> (define x (make-syntax-transformer something something y)), then on
> the way from Tree-IL to bytecode it becomes an intrinsic call which is
> effectively (define! (current-module) 'x) followed by a (set! 'x
> (make-syntax-transformer something something y)). It looks like there
> might be double definition here too: once in a direct route from
> Tree-IL to bytecode, another with the same source and target but via
> CPS.
>
> In any case, based on this, I will add a <toplevel-define-property>
> Tree-IL node which compiles to a new define-property! intrinsic the
> same way <toplevel-define> compiles to a define!. That primitive will
> add the var -> binding -> value mapping to the module. Since there is
> no set! operation on properties, I think everything can be done in one
> intrinsic. One minor question I will have to solve is how to represent
> the binding used for the key down at this level. I am sure there is a
> simple answer to this – possibly just a pair:
> (<original-module> . <var-name>)
>
> There is an alternative approach which looks easier, which would be to
> have define-property at the top level expand directly into a call to a
> new ‘module-define-property!’ procedure. But I assume there is a
> reason macro transformers and other definitions were done the way they
> are done …
>
> Also, because this reaches so far down into the internals of Guile, I
> assume it will be necessary to adapt some of this specially for Hoot
> as well. I haven’t looked at the Hoot sources yet – it might be an
> idea to wait until Andy Wingo has finished porting psyntax to Hoot
> before trying anything there.
>
> In any case, there is then one last step, which is to add code
> adding/merging properties when modules are imported into other
> modules. This should be a fairly simple hash table/alist/whatever
> union operation, but I haven’t looked into it yet.
>
> Since this does touch nearly every level of Guile’s compiler, I would
> appreciate some feedback and ideally the opportunity to consult
> occasionally while I’m working with someone who is more familiar with
> all of this code than I am.
>
> Many thanks in advance,
>
> --
> dpk (Daphne Preston-Kendal) ·· 12103 Berlin, Germany ·· http://dpk.io/
> One Thing to name them all, One Thing to define them,
> One Thing to place them in environments and bind them,
> In the Lambda Order they are all first class. — R2RS
>
>
prev parent reply other threads:[~2024-09-17 8:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-10 20:09 Proposal: Identifier properties for Guile Daphne Preston-Kendal
2024-09-17 8:40 ` Mikael Djurfeldt [this message]
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=CAA2XvwKs7_0MPxXGRtn3RNH9wz5RRezVSSmG8xZaa3WsGnZmWQ@mail.gmail.com \
--to=mikael@djurfeldt.com \
--cc=dpk@nonceword.org \
--cc=guile-devel@gnu.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).