Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread rocketnia
Thanks Philip and Ryan,

I do need to get more familiar with the macro stepper. :) I tried it out 
for maybe the first time just now, but I think Philip's screenshot already 
helped me understand what's going on.

I recall that when Racket invokes a macro, it puts a scope on the inputs 
first (the macro-introduction scope), and then it flips that scope 
afterward so that it occurs only on the rest of the macro's output. This 
keeps variable occurrences that are introduced in the output from binding 
variables that were already in the input, and vice versa.

What's going on here seems to be that `let-third` uses `x`, but doesn't 
take `x` as its own input, so this scope-flipping treats it like it's an 
identifier the `let-third` macro introduces. If I think about the example 
in terms of currying, then `x` *is* an input -- it just isn't an input to 
this particular stage of the macro. But this isn't something Racket's 
hygiene is prepared to treat as an input.

And you know what? I guess I'm convinced. When I write out this far simpler 
example...

(let ([x "first"])
  (let-syntax ([let-second
 (syntax-parser
   [(_ body)
#'(let ([x "second"])
body)])])
(let-second
  x)))

...I take one look at it, and I don't expect the `(let ([x "second"]) ...)` 
to have anything to do with the other two occurrences of `x`. My original 
macro expands into a macro like this, so it doesn't work either.

I guess my intent clouded my judgment. I must have gone in assuming I could 
write a macro that created a `let` that shadowed the variable I wanted it 
to shadow, but that doesn't even work when the variable is hardcoded like 
this.

Philip's technique with the scope introduction with 
`syntax-local-introduce` looks good. I even tried `syntax-local-introduce` 
almost exactly like that myself before posting here, and I think I ran into 
the exact issue that Philip fixed by moving the `(let ([var "second"]) 
...)` around. So there is a workaround to this, which is nice.

I didn't actually have a macro to write; I just wanted a test case to 
ensure my custom variables obeyed the kind of hygiene Racket's existing 
variables did. Now that I understand this better, I know that what I'm 
seeing isn't a broken behavior.

Thanks again,
Nia


On Wednesday, September 30, 2020 at 7:51:09 AM UTC-7 rmculp...@gmail.com 
wrote:

> Yes, the behavior you're seeing is a consequence of hygiene, and you 
> should see the same behavior in other Scheme implementations.
>
> When the expander gets to the `let-third` call, there is a `var` 
> identifier in the macro's template that is used as a binder, and there is a 
> `var` identifier in the macro's argument that is used as a reference. 
> Hygiene says that a macro-introduced binder does not capture a 
> macro-argument reference.
>
> The fact that they both originate from the *same* identifier given to 
> `let-second-and-create-let-third` is irrelevant. The hygiene condition for 
> `let-third` requires that they be treated differently. After all, in 
> "ordinary" hygienic macros, the identifiers are the same also, but the fact 
> that one is in the macro template and one is passed to the macro 
> distinguishes them.
>
> If you want to do higher-order macro programming, the lesson is that 
> hygienic macros are not *pure* abstractions for syntax in the same way that 
> Racket's closures are pure abstractions for computation. That becomes a 
> problem when you want to generate macro definitions that contain 
> identifiers that they use as binders.
>
> Philip provided one solution (and thanks for the macro stepper plug!). The 
> other solution is to pass `var` as an argument to `let-third`.
>
> Ryan
>
>
> On Wed, Sep 30, 2020 at 8:46 AM rocketnia  wrote:
>
>>
>> Hi all,
>>
>> I've been experimenting with a custom system of managed local variables, 
>> and I came up with a hygiene test case that was failing. So then I tried 
>> the same test case with plain Racket variables, and it failed that way 
>> too. Here's a minimalistic example.
>>
>> Basically, this is a curried macro: The user supplies a variable and gets 
>> a macro out, and then the user calls that macro. Can the second macro 
>> bind the variable the user supplied to the first one? I thought it would 
>> be able to, but this doesn't currently seem to be case on Racket v7.8 
>> [cs].
>>
>> Could anyone explain what's going on with this? Is there a workaround if 
>> I want to write this kind of macro? Should I file a bug in Racket? This 
>> looks pretty close to R5RS Scheme, so I wonder what the situation in the 
>> broader Scheme world is like, too.
>>
>>
>> #lang racket
>>
>> (require rackunit)
>>
>> (define-syntax-rule
>>   (let-second-and-create-let-third var let-third body-of-let-second)
>>   (let-syntax ([let-third
>>  (syntax-rules ()
>>[(let-third body-of-let-third)
>> (let ([var "third"])
>>

[racket-users] Call for Contributions: BOB 2021 [Feb 26, Deadline Nov 13]

2020-09-30 Thread Michael Sperber


Racket contributions are very welcome at BOB!

 BOB Conference 2021
 "What happens when we use what's best for a change?"
  http://bobkonf.de/2021/cfc.html
 Berlin, February 26
Call for Contributions
 Deadline: November 13, 2020

You are actively engaged in advanced software engineering methods,
implement ambitious architectures and are open to cutting-edge
innovation? Attend this conference, meet people that share your goals,
and get to know the best software tools and technologies available
today. We strive to offer a day full of new experiences and
impressions that you can use to immediately improve your daily life as
a software developer.

If you share our vision and want to contribute, submit a proposal for
a talk or tutorial!

NOTE: The conference fee will be waived for presenters. Travel
expenses will not be covered (for exceptions see "Speaker Grants").
Online or Onsite

We do know yet whether BOB will happen onsite in Berlin or as an
online event. Should BOB happen online, we will likely ask for
pre-recorded talks to make room for questions and social interactions
during the actual conference day. (Of course, we'll provide assistance
making those recordings.) Tutorials will likely happen as a
live-session.

Speaker Grants
--

BOB has Speaker Grants available to support speakers from groups
under-represented in technology. We specifically seek women speakers
and speakers who are not be able to attend the conference for
financial reasons.

Shepherding
---

The program committee offers shepherding to all speakers. Shepherding
provides speakers assistance with preparing their
sessions. Specifically:

- advice on structure and presentation
- review of talk slides
- assistance with recording
- review of recording, if applicable

Topics
--

We are looking for talks about best-of-breed software technology,
e.g.:

- functional programming
- persistent data structures and databases
- event-based modelling and architecture
- types
- formal methods for correctness and robustness
- abstractions for concurrency and parallelism
- metaprogramming
- probabilistic programming
- math and programming
- controlled side effects
- beyond REST and SOAP
- effective abstractions for data analytics
- … everything really that isn’t mainstream, but you think should be.

Presenters should provide the audience with information that is
practically useful for software developers.

We're especially interested in experience reports.  Other topics are
also relevant, e.g.:

- introductory talks on technical background
- overviews of a given field
- demos and how-tos

Requirements


We accept proposals for presentations of 45 minutes (40 minutes talk +
5 minutes questions), as well as 90 minute tutorials for
beginners. The language of presentation should be either English or
German.

Your proposal should include (in your presentation language of choice):

- An abstract of max. 1500 characters.
- A short bio/cv
- Contact information (including at least email address)
- A list of 3-5 concrete ideas of how your work can be applied in a developer's 
daily life
- additional material (websites, blogs, slides, videos of past presentations, …)
- Don't be confused: The system calls a submission event.

Organisation


- Direct questions to contact at bobkonf dot de
- Proposal deadline: November 13, 2020
- Notification: November 27, 2020
- Program: December 6, 2020

Submit here:

https://bobcfc.active-group.de/en/bob2021/cfp

Program Committee
-

(more information here: https://bobkonf.de/2020/programmkomitee.html)

- Matthias Fischmann, Wire
- Matthias Neubauer, SICK AG
- Nicole Rauch, Softwareentwicklung und Entwicklungscoaching
- Michael Sperber, Active Group
- Stefan Wehr, Hochschule Offenburg

Scientific Advisory Board

- Annette Bieniusa, TU Kaiserslautern
- Torsten Grust, Uni Tübingen
- Peter Thiemann, Uni Freiburg

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/y9lblhn1ck3.fsf%40valmont.fritz.box.


Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread Ryan Culpepper
Yes, the behavior you're seeing is a consequence of hygiene, and you should
see the same behavior in other Scheme implementations.

When the expander gets to the `let-third` call, there is a `var` identifier
in the macro's template that is used as a binder, and there is a `var`
identifier in the macro's argument that is used as a reference. Hygiene
says that a macro-introduced binder does not capture a macro-argument
reference.

The fact that they both originate from the *same* identifier given to
`let-second-and-create-let-third` is irrelevant. The hygiene condition for
`let-third` requires that they be treated differently. After all, in
"ordinary" hygienic macros, the identifiers are the same also, but the fact
that one is in the macro template and one is passed to the macro
distinguishes them.

If you want to do higher-order macro programming, the lesson is that
hygienic macros are not *pure* abstractions for syntax in the same way that
Racket's closures are pure abstractions for computation. That becomes a
problem when you want to generate macro definitions that contain
identifiers that they use as binders.

Philip provided one solution (and thanks for the macro stepper plug!). The
other solution is to pass `var` as an argument to `let-third`.

Ryan


On Wed, Sep 30, 2020 at 8:46 AM rocketnia  wrote:

>
> Hi all,
>
> I've been experimenting with a custom system of managed local variables,
> and I came up with a hygiene test case that was failing. So then I tried
> the same test case with plain Racket variables, and it failed that way
> too. Here's a minimalistic example.
>
> Basically, this is a curried macro: The user supplies a variable and gets
> a macro out, and then the user calls that macro. Can the second macro
> bind the variable the user supplied to the first one? I thought it would
> be able to, but this doesn't currently seem to be case on Racket v7.8
> [cs].
>
> Could anyone explain what's going on with this? Is there a workaround if
> I want to write this kind of macro? Should I file a bug in Racket? This
> looks pretty close to R5RS Scheme, so I wonder what the situation in the
> broader Scheme world is like, too.
>
>
> #lang racket
>
> (require rackunit)
>
> (define-syntax-rule
>   (let-second-and-create-let-third var let-third body-of-let-second)
>   (let-syntax ([let-third
>  (syntax-rules ()
>[(let-third body-of-let-third)
> (let ([var "third"])
>   body-of-let-third)])])
> ; This binding shows that the first macro *does* manage to bind
> ; the given variable, even though the second macro doesn't.
> (let ([var "second"])
>   body-of-let-second)))
>
> (check-equal?
>   (let ([x "first"])
> (let-second-and-create-let-third x let-third
>   (let-third
> x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> ; FAILURE
> ; actual: "second"
> ; expected: "third"
>
>
> You can also find this code in Gist form here:
> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>
> Thanks in advance for any insight you have about what's going on here.
>
> - Nia
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CANy33qnRzmLYTLpZMEPFOabE9Hr-tk90hiaWbNcoKDZymw6kbw%40mail.gmail.com.


Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread Philip McGrath
I'll also put in a plug for DrRacket's Macro Stepper, which can show your
scopes in pretty colors! (And precise numbers.) In particular, in the
"Stepper > Foreground colors" menu, you can toggle between "By macro
scopes" and "By all scopes".

[image: Screen Shot 2020-09-30 at 3.47.40 AM.png]
-Philip


On Wed, Sep 30, 2020 at 3:40 AM Philip McGrath 
wrote:

> Hi Nia,
>
> Here's a variant that passes your test:
>
> #lang racket
>
> (require rackunit
>  syntax/parse/define)
>
> (define-syntax let-second-and-create-let-third
>   (syntax-parser
> [(_ var let-third body-of-let-second)
>  #'(let ([var "second"])
>  (let-syntax ([let-third
>(syntax-parser
>  [(_ body-of-let-third)
>   #:with var* (syntax-local-introduce #'var)
>   #'(let ([var* "third"])
>   body-of-let-third)])])
>body-of-let-second))]))
>
> (check-equal?
>   (let ([x "first"])
> (let-second-and-create-let-third x let-third
>   (let-third
> x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> You need `syntax-local-introduce` (or another mechanism, like
> `datum->syntax`) for `let-third` to be able to capture `x` in its body:
> otherwise, the expander will see that it is a macro-introduced binding. You
> also need to address the fact that each `let` in the expansion creates a
> new scope: if the binding to `"second"` isn't in scope for the
> right-hand-side of `let-third`, you can get an ambiguous binding (see:
> https://www.cs.utah.edu/plt/scope-sets/pattern-macros.html#(part._pattern-ambiguous)).
> In this case I just moved the `let-syntax` inside the `let`, but you could
> also use something like `letrec-syntaxes+values`.
>
> -Philip
>
> On Wed, Sep 30, 2020 at 2:46 AM rocketnia  wrote:
>
>>
>> Hi all,
>>
>> I've been experimenting with a custom system of managed local variables,
>> and I came up with a hygiene test case that was failing. So then I tried
>> the same test case with plain Racket variables, and it failed that way
>> too. Here's a minimalistic example.
>>
>> Basically, this is a curried macro: The user supplies a variable and gets
>> a macro out, and then the user calls that macro. Can the second macro
>> bind the variable the user supplied to the first one? I thought it would
>> be able to, but this doesn't currently seem to be case on Racket v7.8
>> [cs].
>>
>> Could anyone explain what's going on with this? Is there a workaround if
>> I want to write this kind of macro? Should I file a bug in Racket? This
>> looks pretty close to R5RS Scheme, so I wonder what the situation in the
>> broader Scheme world is like, too.
>>
>>
>> #lang racket
>>
>> (require rackunit)
>>
>> (define-syntax-rule
>>   (let-second-and-create-let-third var let-third body-of-let-second)
>>   (let-syntax ([let-third
>>  (syntax-rules ()
>>[(let-third body-of-let-third)
>> (let ([var "third"])
>>   body-of-let-third)])])
>> ; This binding shows that the first macro *does* manage to bind
>> ; the given variable, even though the second macro doesn't.
>> (let ([var "second"])
>>   body-of-let-second)))
>>
>> (check-equal?
>>   (let ([x "first"])
>> (let-second-and-create-let-third x let-third
>>   (let-third
>> x)))
>>   "third"
>>   "Test that a macro generated by a macro can bind a variable the user
>> supplied to the generator macro")
>>
>> ; FAILURE
>> ; actual: "second"
>> ; expected: "third"
>>
>>
>> You can also find this code in Gist form here:
>> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>>
>> Thanks in advance for any insight you have about what's going on here.
>>
>> - Nia
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com
>> 
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/01000174ddff1f9f-f60fe46f-efc2-40c6-bac5-f9f5a2926f8a-00%40email.amazonses.com.


Re: [racket-users] Hygiene for a curried macro

2020-09-30 Thread Philip McGrath
Hi Nia,

Here's a variant that passes your test:

#lang racket

(require rackunit
 syntax/parse/define)

(define-syntax let-second-and-create-let-third
  (syntax-parser
[(_ var let-third body-of-let-second)
 #'(let ([var "second"])
 (let-syntax ([let-third
   (syntax-parser
 [(_ body-of-let-third)
  #:with var* (syntax-local-introduce #'var)
  #'(let ([var* "third"])
  body-of-let-third)])])
   body-of-let-second))]))

(check-equal?
  (let ([x "first"])
(let-second-and-create-let-third x let-third
  (let-third
x)))
  "third"
  "Test that a macro generated by a macro can bind a variable the user
supplied to the generator macro")

You need `syntax-local-introduce` (or another mechanism, like
`datum->syntax`) for `let-third` to be able to capture `x` in its body:
otherwise, the expander will see that it is a macro-introduced binding. You
also need to address the fact that each `let` in the expansion creates a
new scope: if the binding to `"second"` isn't in scope for the
right-hand-side of `let-third`, you can get an ambiguous binding (see:
https://www.cs.utah.edu/plt/scope-sets/pattern-macros.html#(part._pattern-ambiguous)).
In this case I just moved the `let-syntax` inside the `let`, but you could
also use something like `letrec-syntaxes+values`.

-Philip

On Wed, Sep 30, 2020 at 2:46 AM rocketnia  wrote:

>
> Hi all,
>
> I've been experimenting with a custom system of managed local variables,
> and I came up with a hygiene test case that was failing. So then I tried
> the same test case with plain Racket variables, and it failed that way
> too. Here's a minimalistic example.
>
> Basically, this is a curried macro: The user supplies a variable and gets
> a macro out, and then the user calls that macro. Can the second macro
> bind the variable the user supplied to the first one? I thought it would
> be able to, but this doesn't currently seem to be case on Racket v7.8
> [cs].
>
> Could anyone explain what's going on with this? Is there a workaround if
> I want to write this kind of macro? Should I file a bug in Racket? This
> looks pretty close to R5RS Scheme, so I wonder what the situation in the
> broader Scheme world is like, too.
>
>
> #lang racket
>
> (require rackunit)
>
> (define-syntax-rule
>   (let-second-and-create-let-third var let-third body-of-let-second)
>   (let-syntax ([let-third
>  (syntax-rules ()
>[(let-third body-of-let-third)
> (let ([var "third"])
>   body-of-let-third)])])
> ; This binding shows that the first macro *does* manage to bind
> ; the given variable, even though the second macro doesn't.
> (let ([var "second"])
>   body-of-let-second)))
>
> (check-equal?
>   (let ([x "first"])
> (let-second-and-create-let-third x let-third
>   (let-third
> x)))
>   "third"
>   "Test that a macro generated by a macro can bind a variable the user
> supplied to the generator macro")
>
> ; FAILURE
> ; actual: "second"
> ; expected: "third"
>
>
> You can also find this code in Gist form here:
> https://gist.github.com/rocketnia/cb83da2cfcddbf614dfe1dfc5e08792c
>
> Thanks in advance for any insight you have about what's going on here.
>
> - Nia
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/71daa8da-25cf-426b-b709-ee9ed25b53f0n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/01000174ddf4d987-bb428eb4-b346-4bf9-a565-985b02610563-00%40email.amazonses.com.