This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: conditional bindings




On 12/11/2014 08:43 AM, Jamison Hope wrote:
On Dec 10, 2014, at 11:38 PM, Per Bothner <per@bothner.com> wrote:

Looks correct to me ... If you redefine ? then it is just a regular identifier.
I.e.
  (let ((? 0+0i)) (if (? r ::real ?) r +nan.0))
is the same as:
  (let ((x 0+0i)) (if (x r ::real x) r +nan.0))

Remember - Scheme has no reserved identifiers.

Yeah I guess so, it just seems so.. unhygienic? dynamic?, for a macro to
work or not work depending upon the lexical scope of the call site.

Quite the opposite.  A lexical binding overrides a non-lexical binding.
That is how Scheme lexical scoping and hygiene works.  Note it's the same for 'else':

(let ((else #f)) (cond (#f (display "a\n")) (else (display "b\n"))))

FWIW, I tested this on Guile as well as Kawa - neither prints anything.

Plus, function keywords are immune to these shenanigans, so it seems like
macro literals should be, too.

(define (f #!key (x 0) (y 0)) (cons x y))
(let ((y: 7) (x: 1)) (f y: 2 x: 3))
=> (3 . 2)

That's a bug, complicated by the attempt to provide compatibility with
Schemes not supporting keywords.

Kawa should either:
(a) complain about using a keywords as an identifier being bound in a let; or
(b) allow it, and then treat it as an identifier in the body.  I.e.
  (let ((y: 7) (x: 1)) (f y: 2 x: 3))
should either be illegal or the same as:
  (f 7 2 1 3)

(It should definitely do the latter if you specify --r7rs.)

But since that's not the case, I wonder if a macro literal renamer -- akin
to how (import (rename ...)) works for libraries -- could be useful.

It's already possible to wrap a macro to effectively remap its keywords:

(let-syntax ((if (lambda (x) (syntax-case x (q ::)
                                ((_ (q pattern :: type init) then else)
                                 #'(if (? pattern :: type init) then else))))))
   (let ((? 3))
     (if (q r :: real ?) r 0)))

=> 3

but that's awfully verbose.

Why would you want to do this?

Do the original syntax-rules/syntax-case literal list and patterns
survive to runtime to facilitate the kind of introspection such a
thing would need?

Sort-of, mixed in with other literal values.
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]