hyln9 / ikarus

Optimizing incremental native-code compiler for R6RS scheme. This is a forked repository.
https://launchpad.net/ikarus
Other
5 stars 0 forks source link

expansion of splicing let-syntax needs revision #189

Open hyln9 opened 10 years ago

hyln9 commented 10 years ago

Currently, splicing let-syntax is kind of equivalent to define-syntax in that the following is valid:

(let () (let-syntax ([foo (identifier-syntax 12)]) (define-syntax x (identifier-syntax foo))) x) => 12

That is, foo expands correctly even though it's referenced out of its context (which is incorrect).

Launchpad Details: #LP309223 Abdulaziz Ghuloum - 2008-12-17 22:11:11 -0500

hyln9 commented 10 years ago

Scary! I dont think I have ever come across it, but then again, I am not too comfortable with let-syntax and friends either still. :)

Launchpad Details: #LPC leppie - 2008-12-18 11:16:12 -0500

hyln9 commented 10 years ago

On Thu, 2008-12-18 at 16:16 +0000, leppie wrote:

Scary! I dont think I have ever come across it, but then again, I am not too comfortable with let-syntax and friends either still. :)

I used to think they are exotic and more complicated than they are. They just bind identifiers to macro transformers, just like define-syntax, but with the region of the bindings limited, and their body is just like begin so it can have defines that get spliced. Take a look at xitomatl/{alists,define,fuego}.sls for the simple way I've used let-syntax so far.

Launchpad Details: #LPC Derick Eddington - 2008-12-18 19:42:23 -0500

hyln9 commented 10 years ago

Just to be clear, would the following still be legal?

(let () (let-syntax ([foo (identifier-syntax 12)]) (define-syntax x (lambda (stx) #`(+ 3 #,foo)))) x) => 15

or would I still have to pull the define syntax to the outer layer like so?

(let () (define-syntax x (let-syntax ([foo (identifier-syntax 12)]) (lambda (stx) #`(+ 3 #,foo)))) x) => 15

Launchpad Details: #LPC Michael D. Adams - 2008-12-20 11:45:49 -0500

hyln9 commented 10 years ago

I think the required behaviour is almost like the 2nd example.

Here is how I think it should behave:

(let () (define-syntax x (let-syntax ([foo (identifier-syntax 12)]) (lambda (stx) #'foo))) x) => error "identifier out of context" 'foo

Launchpad Details: #LPC leppie - 2008-12-20 12:13:30 -0500

hyln9 commented 10 years ago

On Dec 20, 2008, at 11:45 AM, Michael D. Adams wrote:

Just to be clear, would the following still be legal?

(let () (let-syntax ([foo (identifier-syntax 12)]) (define-syntax x (lambda (stx) #`(+ 3 #,foo)))) x) => 15

Yes.

This is the same as:

(let () (let-syntax ([foo (identifier-syntax 12)]) (define-syntax x (lambda (stx) (list #'+ #'3 foo)))) x)

which is the same as:

(let () (define-syntax x (lambda (stx) (list #'+ #'3 #'12))) x)

which is the same as:

(let () (+ 3 12))

Aziz,,,

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-12-20 12:32:46 -0500

hyln9 commented 10 years ago

On Dec 20, 2008, at 12:13 PM, leppie wrote:

I think the required behaviour is almost like the 2nd example.

Here is how I think it should behave:

(let () (define-syntax x (let-syntax ([foo (identifier-syntax 12)]) (lambda (stx) #'foo))) x) => error "identifier out of context" 'foo

Your example is different from Michael's.

His is closer to:

(let () (define-syntax x (let-syntax ([foo (identifier-syntax 12)]) (lambda (stx) foo))) ;;; no #' x)

which is the same as:

(let () (define-syntax x (lambda (stx) 12)) x)

which is the same as:

(let () 12)

Aziz,,,

Launchpad Details: #LPC Abdulaziz Ghuloum - 2008-12-20 12:35:21 -0500

hyln9 commented 10 years ago

Here is a variation on the theme:

!r6rs

(import (rnrs))

(define lit 41)

(define-syntax foo (syntax-rules (lit) (( lit) (syntax-rules () (() lit)))))

(let ((lit2 42)) (let-syntax ((z (foo lit))) (display (z))))

This should not run.

Changing lit2 to lit raises what seems an incorrect error.

Cheers

leppie

Launchpad Details: #LPC leppie - 2009-06-25 14:19:57 -0400

hyln9 commented 10 years ago

On Jun 25, 2009, at 9:19 PM, leppie wrote:

!r6rs

(import (rnrs))

(define lit 41)

(define-syntax foo (syntax-rules (lit) (( lit) (syntax-rules () (() lit)))))

(let ((lit2 42)) (let-syntax ((z (foo lit))) (display (z))))

This should not run.

Why not?

Changing lit2 to lit raises what seems an incorrect error.

Huh? What do you mean incorrect error. (let ((lit 42)) (foo lit)) should not match the rule for foo since the two "lit"s are not free-identifier=?.

Aziz,,,

Launchpad Details: #LPC Abdulaziz Ghuloum - 2009-06-25 17:21:41 -0400

hyln9 commented 10 years ago

Why not?

'foo' is being used out of context (in both cases), all non-psyntax R6RS implementations agree on this, as well the expected behavior of non-R6RS (I asked on IRC, as I thought incorrectly that this was an implicit phasing issue).

Huh? What do you mean incorrect error. (let ((lit 42)) (foo lit)) should not match the rule for foo since the two "lit"s are not free-identifier=?.

The incorrect error should be 'foo' being used out of context, not a match failure.

Cheers

leppie

Launchpad Details: #LPC leppie - 2009-06-26 01:06:35 -0400

hyln9 commented 10 years ago

On Jun 26, 2009, at 8:06 AM, leppie wrote:

Why not?

'foo' is being used out of context (in both cases),

??

all non-psyntax R6RS implementations agree on this,

That's not a good reason to add a restriction to Ikarus. There is no reason why a compile-time entity (a macro) cannot be used at compile time.

as well the expected behavior of non-R6RS

Huh? What non-R6RS are you talking about?

Aziz,,,

Launchpad Details: #LPC Abdulaziz Ghuloum - 2009-06-26 02:19:11 -0400

hyln9 commented 10 years ago

On Fri, Jun 26, 2009 at 8:19 AM, Abdulaziz Ghuloum

Why not?

'foo' is being used out of context (in both cases),

??

all non-psyntax R6RS implementations agree on this,

That's not a good reason to add a restriction to Ikarus. There is no reason why a compile-time entity (a macro) cannot be used at compile time.

as well the expected behavior of non-R6RS

Huh? What non-R6RS are you talking about?

I'm no language lawyer, but according to Taylor R. Campbell for R5RS, the identifier should be out of context (I did not test this), just as I did see in all other R6RS's I tested (PLT, Larceny, Ypsilon).

I will investigate and gather some more information.

Cheers

leppie

Launchpad Details: #LPC leppie - 2009-06-26 04:55:00 -0400

hyln9 commented 10 years ago

On Jun 26, 2009, at 11:55 AM, leppie wrote:

I'm no language lawyer, but according to Taylor R. Campbell for R5RS, the identifier should be out of context (I did not test this), just as I did see in all other R6RS's I tested (PLT, Larceny, Ypsilon).

R5RS only specifies the behavior when the "syntax-rules" appears on the right-hand-side of {let,letrec,define}-syntax. It says nothing about what happens when something else (e.g., (foo)) appears there.

All implementations of psyntax (the current R6RS one, as well as the original one) allow macros to be used in both variable and syntax bindings. All implementations that use psyntax, even non-R6RS ones, follow the same semantics (try sisc, guile, chicken's psyntax egg, gambit, to name a few). Chez Scheme's R6RS libraries also allow it.

Even if R6RS disallows it (which I doubt it would, since the whole macro business is so loosy-goosy), that still does not make a good case. That would be just an arbitrary restriction since Ikarus's behavior is a demonstration for why such restriction need not be required.

I will investigate and gather some more information.

I don't see the point of that since it's very unlikely that anything will change w.r.t. this issue. I am not going to require writing auxiliary libraries for the sole purpose of making a macro available at syntax definitions. If the other implementations require it, and you want to run your code on these implementations, then by all means do split your libraries and don't forget to add the appropriate phase declarations.

Aziz,,,

Launchpad Details: #LPC Abdulaziz Ghuloum - 2009-06-26 05:29:51 -0400