Discussion
Loading...

Discussion

  • About
  • Code of conduct
  • Privacy
  • About Bonfire
Ludovic Courtès
@civodul@toot.aquilenet.fr  ·  activity timestamp last week

Problem: if you write a macro that uses ‘define-foo’, then the identifier ‘foo’ is made unique (rewritten to ‘foo-123456’ or so).

(define-syntax-rule (define-foo* value)
(define-foo value))

(define-foo* 42) ;does not define ‘foo’

👎

  • Copy link
  • Flag this post
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

It’s possible to break hygiene with ‘datum->syntax’; below, the macro introduces the top-level identifier ‘foo’, as-is:

(define-syntax define-foo
(lambda (s)
(syntax-case s ()
((_ value)
(with-syntax ((foo (datum->syntax s 'foo)))
#'(define foo value))))))

(define-foo 42)

👍

  • Copy link
  • Flag this comment
  • Block
Daphne Preston-Kendal
@dpk@chaos.social replied  ·  activity timestamp last week

@civodul This code is not compliant – the first argument to datum->syntax must be an identifier because the context on an identifier is (1) guaranteed to be present (any other type of syntax object might be unwrapped) and (2) unambigous (a compound syntax object of any kind might carry multiple contexts)

  • Copy link
  • Flag this comment
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

@dpk Uh, silly me. 🤦

And it fixes the ‘define-foo’ example.

I have more involved code where macro-introduced top-level identifiers are still being rewritten though. I wonder what I’m missing.

  • Copy link
  • Flag this comment
  • Block
Daphne Preston-Kendal
@dpk@chaos.social replied  ·  activity timestamp last week

@civodul Usually it’s sufficient to capture the macro use keyword’s context:

(define-syntax define-foo
(lambda (s)
(syntax-case s ()
((k value)
(with-syntax ((foo (datum->syntax #'k 'foo)))
#'(define foo value))))))

but there are exceptions, usually when identifiers are generated by adding bits to other identifiers (like implicit naming in define-record-type)

  • Copy link
  • Flag this comment
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

Problem: if you write a macro that uses ‘define-foo’, then the identifier ‘foo’ is made unique (rewritten to ‘foo-123456’ or so).

(define-syntax-rule (define-foo* value)
(define-foo value))

(define-foo* 42) ;does not define ‘foo’

👎

  • Copy link
  • Flag this comment
  • Block
Daphne Preston-Kendal
@dpk@chaos.social replied  ·  activity timestamp last week

@civodul This is correct behaviour for reasons explained in the R7RS large draft: https://r7rs.org/large/fascicles/macro/1/macros-and-hygiene.html#hygiene-definition:~:text=Within%20the%20context%20of%20hygienic%20macro%20expansion

There’s no real watertight technical solution, unfortunately; if you use the keyword-capturing trick mentioned in the previous toot, you also have to make sure the underlying macro is in scope with the expected name.

The design pattern solution is that every unhygienic macro should just be syntactic sugar for some other, hygienic macro (as, again, in implicit naming define-record-type)

  • Copy link
  • Flag this comment
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

@dpk My use case here is introducing top-level identifiers from a macro that parses https://codeberg.org/swagger.v1.json and generates bindings.

It’s a situation that requires hygiene to be turned off, but I’m reaching the conclusion that it won’t be possible—that I’ll have to generate a Scheme file rather than do it all at macro-expansion time.

What’s your take?

  • Copy link
  • Flag this comment
  • Block
Daphne Preston-Kendal
@dpk@chaos.social replied  ·  activity timestamp last week

@civodul Do you have time to jump onto Jitsi/similar and share what you’re working on?

  • Copy link
  • Flag this comment
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

@dpk Thanks for unblocking the situation on IRC earlier today!

Turns out the solution, as you found it, was to pass ‘datum->syntax’ the right context—i.e., a syntax object corresponding to the top level.

Making progress!

  • Copy link
  • Flag this comment
  • Block
Ludovic Courtès
@civodul@toot.aquilenet.fr replied  ·  activity timestamp last week

This is pretty annoying and I don’t see a good way to work around that.

Thoughts, #Scheme folks?

  • Copy link
  • Flag this comment
  • Block
Log in

A small Bonfire corner on the internet

This is a small personal instance of Bonfire in the Fediverse.

A small Bonfire corner on the internet: About · Code of conduct · Privacy ·
Bonfire social · 1.0.0 no JS en
Automatic federation enabled
  • Explore
  • About
  • Code of Conduct
Home
Login