[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Scheme-reports] ANN: first draft of R7RS small language available

On Thu, 05 May 2011 10:05:47 -0400, Andrzej <ndrwrdck@x>  

> 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  

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