Could (define-syntax (name stx) ...) be brought back?

Asked by Derick Eddington on 2007-11-19

I use this convenient form a lot. Could it be enabled with (import (ikarus))?

Question information

Language:
English Edit question
Status:
Solved
For:
Ikarus Scheme Edit question
Assignee:
No assignee Edit question
Solved by:
Abdulaziz Ghuloum
Solved:
2007-11-20
Last query:
2007-11-20
Last reply:
2007-11-19
Best Abdulaziz Ghuloum (aghuloum) said : #1

Good question, but I'm afraid the answer is no.

Here's the problem.

If (ikarus) exports a version of define-syntax that's different from
the define-syntax exported from (rnrs base) and (rnrs), then every
time you import both, you'd get a conflict. So, (import (rnrs)
(ikarus)) fails and you'd have to do either:
    (import (except (rnrs) define-syntax) (ikarus))
or
    (import (rnrs) (except (ikarus) define-syntax))

I would rather live with no (define-syntax (name stx) ---) than make
the (ikarus) library incompatible with the (rnrs *) libraries.

Now of course you can define your own version of define-syntax that
does exactly what you want, put it in its own library, and make a
composite library that imports and re-exports everything you need.
It's a pain to do with the huge list of default exports, but once
it's done, you don't have to change it at all.

I'm open to any suggestions that you may have to make the situation
better.

Thanks Abdulaziz Ghuloum, that solved my question.

I think the below works to make it so the same define-syntax disallows or allows the procedure-making define-syntax with formals -style depending on whether (ikarus) is in the environment. In psyntax.expander.ss, change parse-define-syntax to be:

  (define parse-define-syntax
    (lambda (x)
      (syntax-match x ()
        ((_ id val) (id? id) (values id val))
        ((_ (id . args) e e* ...)
         (or (and (member '(ikarus) (map library-name ((imp-collector))))
                  (id? id))
             (stx-error x "define-syntax with formals is invalid syntax in R6RS"))
         (values id (cons* (bless 'lambda) args e e*))))))

This seems to work:

$ cat ./ds-r6.ss
#! /home/d/bin/ikarus --r6rs-script
(import #;(ikarus) (rnrs))
(define-syntax (s stx)
  (syntax-case stx ()
    [(_ x) #'(begin (display x) (newline))]))
(s 'foo)

$ ikarus --r6rs-script ./ds-r6.ss
Unhandled exception:
 Condition components:
   1. &error
   2. &who: expander
   3. &message: "define-syntax with formals is invalid syntax in R6RS"
   4. &irritants: ((define-syntax (s stx) (syntax-case stx () ((_ x) #'(begin (display x) (newline))))))

# uncomment the import of (ikarus) and it's valid:

$ cat ./ds-r6.ss
(import (ikarus) (rnrs))
(define-syntax (s stx)
  (syntax-case stx ()
    [(_ x) #'(begin (display x) (newline))]))
(s 'foo)

$ ikarus --r6rs-script ./ds-r6.ss
foo

Similarly:

Ikarus Scheme version 0.0.1
Copyright (c) 2006-2007 Abdulaziz Ghuloum

> (expand '(let () (define-syntax (fail stx) #f) (fail))
                 (environment '(rnrs)))
Unhandled exception
 Condition components:
   1. &error
   2. &who: expander
   3. &message: "define-syntax with formals is invalid syntax in R6RS"
   4. &irritants: ((define-syntax (fail stx) #f))
>
> (expand '(let () (define-syntax (fail stx) #f) (fail))
                 (environment '(rnrs) '(ikarus)))
((case-lambda (() '#f)))
()

Actually make that:

  (define parse-define-syntax
    (lambda (x)
      (syntax-match x ()
        ((_ id val) (id? id) (values id val))
        ((_ (id . args) e e* ...)
         (and (or (member '(ikarus) (map library-name ((imp-collector))))
                  (stx-error x "define-syntax with formals is invalid syntax in R6RS"))
              (id? id))
         (values id (cons* (bless 'lambda) args e e*))))))

Abdulaziz Ghuloum (aghuloum) said : #5

Unfortunately, this does not work in general. There are many cases where it breaks but I'll just mention 2.

Case 1:

#!/usr/bin/env scheme-script
(import (rnrs) (except (ikarus) define-syntax))
(define-syntax (foo x) 12) ;;; shouldn't this signal an error?
(foo)

Case 2:

(library (A)
  (export define-syntax)
  (import (ikarus)))

#!/usr/bin/env scheme-script
(import (A))
(define-syntax (foo x) 12) ;;; shouldn't this succeed?
(foo)

The problem here is that you want one identifier to denote two different things. If you have a single identifier (define-syntax), then you have no way of deciding which behavior to perform when you find that identifier. If you have two different identifiers and both are called define-syntax, then you get a conflict if you import both.

Duh, right. Oh well.

Jens Axel Søgaard (soegaard) said : #7

If, say, Dybvig, Clinger, and Flatt all agreed to support (define-syntax (name arg) ...)
would you then reconsider?

/Jens Axel,
(define-syntax (name stx) ...) is in my fingers,
not to mention all my code

Abdulaziz Ghuloum (aghuloum) said : #8

On Dec 28, 2007, at 6:22 PM, Jens Axel Søgaard wrote:

> If, say, Dybvig, Clinger, and Flatt all agreed to support (define-
> syntax (name arg) ...)
> would you then reconsider?

Of course. Are you collecting signatures?

Jens Axel Søgaard (soegaard) said : #9

Abdulaziz Ghuloum skrev:
> Question #18207 on Ikarus Scheme changed:
> https://answers.launchpad.net/ikarus/+question/18207
>
> Abdulaziz Ghuloum posted a new comment:
>
> On Dec 28, 2007, at 6:22 PM, Jens Axel Søgaard wrote:
>
>> If, say, Dybvig, Clinger, and Flatt all agreed to support (define-
>> syntax (name arg) ...)
>> would you then reconsider?
>
> Of course. Are you collecting signatures?

I will now :-)

/Jens Axel