Re: [racket-users] syntax/parse is not hygienic

2018-03-04 Thread Alexis King
Actually, what I wrote was wrong. The key piece of information I
overlooked was the following rule:

> A binding for an identifier can only capture a reference to another
> if both were present in the source or introduced during a single
> evaluation of a syntax or quasisyntax form, with the understanding
> that the evaluation of any nested, unquoted syntax or quasisyntax
> forms counts as part of the evaluation of an enclosing quasisyntax.

The key phrase is “single evaluation”, so quote-syntax becomes
generative: multiple evaluations of the same quote-syntax form use
distinct scopes.

This is interesting to me. It’s stricter than Racket’s model for
hygiene, since Racket makes it legal to do things like this:

(with-syntax ([def #'(define x 42)])
  #'(begin def x))

...which produces a piece of syntax that will evaluate to 42, unlike in
van Tonder’s model, in which it would produce an unbound identifier
error. Of course, this problem is not difficult to solve; it just
requires lifting #'x into a separate binding:

(with-syntax* ([id #'x]
   [def #'(define id 42)])
  #'(begin def id))

This model... makes sense to me. I like it. It seems, on the surface,
more intuitive than Racket’s model of introducing fresh scopes in the
expander itself. That said, it’s still quite different from Racket’s
model, so some of what I said in my last message still applies, I think.
I also wouldn’t be surprised if there were some infelicities in the
alternative approach I’m not immediately seeing (corner cases,
perhaps?).

While it’s a bit of a tangent, I’d be quite interested to finding more
information on this alternate model of hygiene from anyone familiar with
the tradeoffs (the SRFI that describes it does not include much in the
way of comparisons). Are there strong reasons to prefer Racket’s model
aside from backwards compatibility and mild convenience when
procedurally assembling pieces of syntax?

> On Mar 4, 2018, at 19:28, Alexis King  wrote:
> 
> Sam suggested I take a look at van Tonder’s work as well on Slack, and
> it’s interesting, though it isn’t what I originally had in mind. I
> think it would solve the first example of mine, but it would not solve
> the second. In the second example, all uses of tmp come from the same
> quote-syntax form, merely multiplied via ellipsis. My first mental
> model was to treat syntax classes under ellipses like distinct macro
> invocations, which would require a dynamic, not lexical, treatment of
> scope to be consistent with Racket’s model of hygiene.
> 
> If I’m understanding correctly, attaching fresh scopes at quotation
> rather than expansion treats the source text of the program as the
> ground truth for all scoping information — if two identifiers come
> from the same location in the user’s source code, they can bind each
> other.  This seems like a good model for most things, but it seems
> radically different from Racket’s model when internal definitions are
> involved, since such an interpretation would imply that this program
> should produce a duplicate definition error:
> 
>(define-syntax-rule (def-x)
>  (define x 42))
> 
>(def-x)
>(def-x)
> 
> That seems to me like an enormous break from Racket’s model of
> hygiene, but it doesn’t seem wrong, just different. I could picture a
> different programming language with a different macroexpander using
> such a model successfully. Still, unless I’m misunderstanding the
> implications here, it seems like attaching the scopes at expansion
> (even if “expansion” is really “parsing with syntax classes”) rather
> than quoting would be more consistent with the rest of Racket?

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] syntax/parse is not hygienic

2018-03-04 Thread Alexis King
> On Mar 4, 2018, at 15:11, Matthew Flatt  wrote:
> 
> I think scope-flipping would work, but FWIW, I thought you were going
> a different direction here. The scope-flipping approach is a way to
> infer an intended scope dynamically. It sounds to me like you want
> something more static --- a way of applying a fresh scope to a textual
> region of syntax literals.
> 
> An extreme end of that approach would be applying a fresh scope on the
> evaluation of each `quote-syntax` form (essentially as van Tonder
> explored), but it's possible that larger regions would work better.

Sam suggested I take a look at van Tonder’s work as well on Slack, and
it’s interesting, though it isn’t what I originally had in mind. I think
it would solve the first example of mine, but it would not solve the
second. In the second example, all uses of tmp come from the same
quote-syntax form, merely multiplied via ellipsis. My first mental model
was to treat syntax classes under ellipses like distinct macro
invocations, which would require a dynamic, not lexical, treatment of
scope to be consistent with Racket’s model of hygiene.

If I’m understanding correctly, attaching fresh scopes at quotation
rather than expansion treats the source text of the program as the
ground truth for all scoping information — if two identifiers come from
the same location in the user’s source code, they can bind each other.
This seems like a good model for most things, but it seems radically
different from Racket’s model when internal definitions are involved,
since such an interpretation would imply that this program should
produce a duplicate definition error:

(define-syntax-rule (def-x)
  (define x 42))

(def-x)
(def-x)

That seems to me like an enormous break from Racket’s model of hygiene,
but it doesn’t seem wrong, just different. I could picture a different
programming language with a different macroexpander using such a model
successfully. Still, unless I’m misunderstanding the implications here,
it seems like attaching the scopes at expansion (even if “expansion” is
really “parsing with syntax classes”) rather than quoting would be more
consistent with the rest of Racket?

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] pkgd.racket-lang.org sign-in link down

2018-03-04 Thread Jay McCarthy
Thanks, I just kicked it.

On Sun, Mar 4, 2018 at 9:04 PM, 'John Clements' via users-redirect
 wrote:
> The “sign in” link on pkgs.racket-lang.org appears to time out. It looks to 
> me like that’s because it’s a link to pkgd.racket-lang.org (not pkgs….). I 
> believe these are … supposed to be synonyms? When I go to 
> pkgd.racket-lang.org I get a directory listing… looks like a misconfigured 
> web server.
>
> John
>
>
>
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.



-- 
-=[ Jay McCarthy   http://jeapostrophe.github.io]=-
-=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
-=[ Moses 1:33: And worlds without number have I created; ]=-

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[racket-users] pkgd.racket-lang.org sign-in link down

2018-03-04 Thread 'John Clements' via users-redirect
The “sign in” link on pkgs.racket-lang.org appears to time out. It looks to me 
like that’s because it’s a link to pkgd.racket-lang.org (not pkgs….). I believe 
these are … supposed to be synonyms? When I go to pkgd.racket-lang.org I get a 
directory listing… looks like a misconfigured web server.

John



-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] syntax/parse is not hygienic

2018-03-04 Thread Matthew Flatt
At Sun, 4 Mar 2018 12:40:43 -0800, Alexis King wrote:
>   2. Are there some fundamental, theoretical obstacles to making a
>  syntax class-like thing hygienic that I have not foreseen? Or would
>  it really be as simple as performing the usual scope-flipping that
>  macroexpansion already performs?

I think scope-flipping would work, but FWIW, I thought you were going a
different direction here. The scope-flipping approach is a way to infer
an intended scope dynamically. It sounds to me like you want something
more static --- a way of applying a fresh scope to a textual region of
syntax literals.

An extreme end of that approach would be applying a fresh scope on the
evaluation of each `quote-syntax` form (essentially as van Tonder
explored), but it's possible that larger regions would work better.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] syntax/parse is not hygienic

2018-03-04 Thread Matthias Felleisen


> On Mar 4, 2018, at 3:40 PM, Alexis King  wrote:
> 
> Apologies in advance for both the inflammatory subject and yet another
> overly long email to this list.


I wouldn’t call this inflammatory. It might be considered a bug report. 
Thanks for the thorough analysis. 

Would you be in a position to add syntax classes to Michael Adam’s 
model of hygiene (I know that it doesn’t support define, but I think one 
can think of define-syntax-class as (let-for-syntax ((a (syntax-class …)). 
One could also add it to Matthew’s model and see what is doable there. 
If the two agree that syntax-generating attributes can be made hygienic, 
good. If not, one might wish to consider telling people (forcing?) to produce 
values that are then fed into auxiliary macros. 

I am looking forward to Ryan’s response — Matthias



> 
> I think anyone who knows me knows that I love syntax/parse — I think
> it’s far and away one of Racket’s most wonderful features — but I’ve
> long suspected it does not respect hygiene. Consider:
> 
>#lang racket
>(require syntax/parse/define)
> 
>(define x #f)
> 
>(begin-for-syntax
>  (define-syntax-class a
>[pattern _ #:attr def #'(define x #t)])
>  (define-syntax-class b
>[pattern _ #:attr use #'x]))
> 
>(define-simple-macro (m a:a b:b)
>  (begin a.def b.use))
> 
>(m 0 0) ; => #t
> 
> This program produces #t from the reference to x on line 10. Considering
> the natural lexical scope of the program, as it appears to a human
> reader, there is no local definition of x in scope where #'x is written
> on line 10, so it logically ought to refer to the top-level definition
> of x on line 4, which would make the program produce #f. However, it
> does not. Instead, it produces #t because it actually refers to the
> definition of x written on line 8, which is assembled alongside the use
> on line 13.
> 
> While this behavior makes sense from the perspective of someone familiar
> with the semantics of procedural macros, if taken from the point of view
> of pattern-based systems, it seems to violate one of the essential
> properties of a hygienic macro system. Namely, the macro system should
> respect program scope. The above program does not.
> 
> For those unfamiliar with the details, this behavior occurs because
> syntax class uses are not treated like macro transformations. When a
> macro is expanded, a fresh scope is attached to its expansion, but when
> a syntax class is used, its syntax objects have no additional
> introduction scope. One could argue this behavior is useful — sometimes
> it is helpful to be able to assemble larger pieces of syntax from the
> outputs of different syntax classes without needing to pass shared
> identifiers as input to the classes — but it also causes problems. I
> think I first ran into it when I was using a syntax class to generate a
> series of definitions:
> 
>#lang racket
>(require syntax/parse/define)
> 
>(begin-for-syntax
>  (define-syntax-class def-and-use
>[pattern val:expr
> #:attr x #'(begin
>  (define tmp (+ val 1))
>  (displayln tmp))]))
> 
>(define-simple-macro (m a:def-and-use ...)
>  (begin a.x ...))
> 
>(m 1 2 3)
> 
> I would expect this program to print "2\n3\n4\n", but instead, it fails
> to compile with an error:
> 
>module: identifier already defined
>  in: tmp
> 
> The multiple definitions of tmp are assembled alongside each other, and
> since they all have the same scopes, they collide. A solution is to use
> generate-temporary, but that is a little ugly. A solution that uses a
> helper macro in place of the syntax class has no such problem:
> 
>#lang racket
>(require syntax/parse/define)
> 
>(define-simple-macro (def-and-use val:expr)
>  (begin (define tmp (+ val 1))
> (displayln tmp)))
> 
>(define-simple-macro (m a:expr ...)
>  (begin (def-and-use a) ...))
> 
>(m 1 2 3)
> 
> There are arguments to be made that the existing behavior is not
> unreasonable. Syntax classes behave like phase 1 functions, not macros.
> If one desires macro-like behavior, it’s often possible to use a helper
> macro instead of a syntax class. This is not always true, however;
> sometimes syntax classes are used to generate syntax that will be
> inserted into places where the macroexpander will not run (such as
> binding positions), but one still needs to use generate-temporaries to
> avoid duplicate bindings.
> 
> There are some minor questions as to what the semantics of “hygienic”
> syntax classes would be, since they accept arbitrary values as inputs
> (in the case of parameterized syntax classes), not exclusively syntax
> objects. They also have multiple outputs, some of which may not be
> syntax-valued, so it’s not immediately obvious to me if performing the
> same scope flipping that works for macros would produce the appropriate
> result for syntax classes

[racket-users] syntax/parse is not hygienic

2018-03-04 Thread Alexis King
Apologies in advance for both the inflammatory subject and yet another
overly long email to this list.

I think anyone who knows me knows that I love syntax/parse — I think
it’s far and away one of Racket’s most wonderful features — but I’ve
long suspected it does not respect hygiene. Consider:

#lang racket
(require syntax/parse/define)

(define x #f)

(begin-for-syntax
  (define-syntax-class a
[pattern _ #:attr def #'(define x #t)])
  (define-syntax-class b
[pattern _ #:attr use #'x]))

(define-simple-macro (m a:a b:b)
  (begin a.def b.use))

(m 0 0) ; => #t

This program produces #t from the reference to x on line 10. Considering
the natural lexical scope of the program, as it appears to a human
reader, there is no local definition of x in scope where #'x is written
on line 10, so it logically ought to refer to the top-level definition
of x on line 4, which would make the program produce #f. However, it
does not. Instead, it produces #t because it actually refers to the
definition of x written on line 8, which is assembled alongside the use
on line 13.

While this behavior makes sense from the perspective of someone familiar
with the semantics of procedural macros, if taken from the point of view
of pattern-based systems, it seems to violate one of the essential
properties of a hygienic macro system. Namely, the macro system should
respect program scope. The above program does not.

For those unfamiliar with the details, this behavior occurs because
syntax class uses are not treated like macro transformations. When a
macro is expanded, a fresh scope is attached to its expansion, but when
a syntax class is used, its syntax objects have no additional
introduction scope. One could argue this behavior is useful — sometimes
it is helpful to be able to assemble larger pieces of syntax from the
outputs of different syntax classes without needing to pass shared
identifiers as input to the classes — but it also causes problems. I
think I first ran into it when I was using a syntax class to generate a
series of definitions:

#lang racket
(require syntax/parse/define)

(begin-for-syntax
  (define-syntax-class def-and-use
[pattern val:expr
 #:attr x #'(begin
  (define tmp (+ val 1))
  (displayln tmp))]))

(define-simple-macro (m a:def-and-use ...)
  (begin a.x ...))

(m 1 2 3)

I would expect this program to print "2\n3\n4\n", but instead, it fails
to compile with an error:

module: identifier already defined
  in: tmp

The multiple definitions of tmp are assembled alongside each other, and
since they all have the same scopes, they collide. A solution is to use
generate-temporary, but that is a little ugly. A solution that uses a
helper macro in place of the syntax class has no such problem:

#lang racket
(require syntax/parse/define)

(define-simple-macro (def-and-use val:expr)
  (begin (define tmp (+ val 1))
 (displayln tmp)))

(define-simple-macro (m a:expr ...)
  (begin (def-and-use a) ...))

(m 1 2 3)

There are arguments to be made that the existing behavior is not
unreasonable. Syntax classes behave like phase 1 functions, not macros.
If one desires macro-like behavior, it’s often possible to use a helper
macro instead of a syntax class. This is not always true, however;
sometimes syntax classes are used to generate syntax that will be
inserted into places where the macroexpander will not run (such as
binding positions), but one still needs to use generate-temporaries to
avoid duplicate bindings.

There are some minor questions as to what the semantics of “hygienic”
syntax classes would be, since they accept arbitrary values as inputs
(in the case of parameterized syntax classes), not exclusively syntax
objects. They also have multiple outputs, some of which may not be
syntax-valued, so it’s not immediately obvious to me if performing the
same scope flipping that works for macros would produce the appropriate
result for syntax classes.

Still, with all this context out of the way, my questions are
comparatively short:

  1. Is this lack of hygiene well-known? I did not find anything in
 Ryan’s dissertation that explicitly dealt with the question, but I
 did not look very hard, and even if it isn’t explicitly mentioned
 there, I imagine people have thought about it before.

  2. Are there some fundamental, theoretical obstacles to making a
 syntax class-like thing hygienic that I have not foreseen? Or would
 it really be as simple as performing the usual scope-flipping that
 macroexpansion already performs?

  3. If it is possible, is the unhygienic nature of syntax classes
 desirable frequently enough that it outweighs the benefits of
 respecting hygiene? That seems unlikely to me, but maybe I have not
 fully considered the problem. The semantics of syntax classes

[racket-users] Re: Getting young children started with Racket

2018-03-04 Thread Prabhakar Ragde
On Saturday, March 3, 2018 at 8:41:16 AM UTC-5, Paulo Matos wrote:
>
> Hello, 
>
> I have a 7yo daughter currently in 1st grade (Germany) and she was given 
> a password for the school computer. Having never touched a computer 
> before she is now being introduced to typing and the mouse. 
>
> I wonder if anyone has any experience with the following: 
>
> 1. Is it useful for a child this age to get introduced to programming if 
> they are not actively looking to learn? 
> 2. Is racket a good way to introduce it? 
> 3. Is 7yo / 1st grade a good time or too early and I should wait?
>

I used Racket with both my children at age 9. Here is a short writeup about 
it originally posted to this mailing list.

https://web.archive.org/web/20080612194829/http://home.adelphi.edu/sbloch/class/hs/testimonials/prabhakar.shtml

In answer to your questions, I would say (1) Demo it and see what they 
think, but let it be their decision; (2) Yes, the best one I know of!; (3) 
They need the potential to grasp the abstractions that an identifier may 
refer to a specific value or may range over all values, and the ability to 
distinguish those two situations. Seven might be a bit young, but you know 
your child best. Bootstrap did not exist when my children were the right 
age, and I would definitely think about that now.

Neil is right that some light instruction combined with suggested but not 
required exercises and encouragement to explore is best. Of course that has 
to be tailored to the situation. Exploration can be frustrating if things 
are obscure or counterintuitive. And my younger child wanted to learn how 
to use Terminal in OS X by typing things into it. I had to explain why that 
was dangerous! --PR


-- 
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.
For more options, visit https://groups.google.com/d/optout.