Re: [Scheme-reports] ANN: first draft of R7RS small language available Aaron W. Hsu (05 May 2011 18:32 UTC)

Re: [Scheme-reports] ANN: first draft of R7RS small language available Aaron W. Hsu 05 May 2011 18:32 UTC

On Thu, 05 May 2011 10:05:47 -0400, Andrzej <ndrwrdck@googlemail.com>
wrote:

> To me it looks like we have two problems:
> 1) How to clean up the existing mess in 'cond' and 'case' forms (Are
> other forms affected? How about 'quasiquote').

Mess is probably a bit of a strong word, and R6RS did provide a solution
to it.

> 2) Provide a framework for hygienic user defined keywords.

Again, I think that this has already been firmly established in many
Scheme implementations.

> (2) can probably be fixed with quoted symbols but I don't have a proof
> for it other than I couldn't come up with an example exposing any
> problem with macro hygiene or with the module system.

Quoted symbols simply don't work any more in the presence of module
systems if you want to do real hygienic keyword matching. If syntax-rules
matches its keywords by symbol instead of identifiers, you've immediately
introduced a referential transparency bug in your code. Consider the
following R6RS library:

(library (foo)
   (export bar)
   (import (rnrs))

(define-syntax bar
   (syntax-rules (false)
     [(_ false) #f]
     [(_ e) e]))

)

(library (use-foo)
   (export blah)
   (import (rnrs) (foo))

(define-syntax blah
   (syntax-rules ()
     [(_ id e) (let ([id e]) (bar id))]))

)

Now, let's say that I import (use-foo). I don't know anything about (foo).
I shouldn't have to know anything about (foo), because it's (use-foo) that
uses foo, and it's use and behavior should be transparent to me. In this
case, (blah id expr) in any case should give me back the result of
evaluating expr, I should be able to always rely on this. However, if a
macro system compares keywords symbolically, it has no introduced a
glaring abstraction leakage. There's no way that the "false" can be hidden
away, so no matter how many layers deep I have the (foo) library, if I
suddenly say (bar false) in any capacity, regardless of whether the false
that I passed in was actually the false identifier that was
free-identifier=? to the false in (foo), and regardless of the fact that I
bound false to something else, I simply cannot use the variable name false
with the foo macro or *any other macro that uses bar* where the false name
might end up as the element in the bar form.

This is a very bad, very broken thing, because it destroys the safety of
macro systems. Indeed, I believe R5RS, R6RS, and this draft all agree on
this behavior, as the language states that a literal is matched if and
only if they are the same lexical binding.

> a) Declare 'else', '=>' and other affected keywords as reserved words
> and make it illegal to bind values to them. Errors could be signaled
> early, at binding stage, instead of resulting in some obscure
> behavior. That's a perfectly valid and effective solution (maintains
> described semantics of 'cond' and hygiene of macros). Sure it is not
> very elegant but we are only dealing with consequences of previous
> mistakes.

I don't believe that any previous mistakes were made regarding this.
Things may have been underspecified, but now we have the opportunity to
correctly specify these in such a way that ensures hygiene is preserved by
them. I take large issue with using any reserved keywords, as Scheme has
no reserved keywords, anywhere.

> b) Change the semantics of 'cond', 'case' and any other affected form
> so that they use regular identifiers. This implies rewriting affected
> sections of the specification. Because we are dealing with explicit
> identifiers they should be specified as well. Andre has pointed out
> that R7RS has already got a note endorsing this approach but I don't
> think this is enough (R7RS first specifies undesired semantics and
> then, in a loosely related section, it informs implementors and users
> that the specified semantics is wrong. Why?)

We actually have two approaches if we choose to use hygienic keyword
matching for COND and CASE, which, IMO, is the only sane approach given
the various issues with symbol keyword matching everywhere else. Either we
can leave the auxiliary keywords unbound and unexported, in which case we
have no control over them, and it effectly makes them reserved words, or
we can export them explicitly, in which case we have control over them and
they can be renamed and re-used without making it impossible to get them
back.

The latter solution does have some problems, which people have mentioned,
including things like import conflicts. On the other hand, I would argue
that these problems at least have effective work arounds, and they are
minor in comparison with the problems of the other solutions, where you
simply cannot solve them or work around them.

	Aaron W. Hsu

--
Programming is just another word for the lost art of thinking.

_______________________________________________
Scheme-reports mailing list
Scheme-reports@scheme-reports.org
http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports