This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: conditional bindings
- From: Per Bothner <per at bothner dot com>
- To: kawa at sourceware dot org
- Date: Thu, 11 Dec 2014 10:36:49 -0800
- Subject: Re: conditional bindings
- Authentication-results: sourceware.org; auth=none
- References: <54868D3A dot 10605 at bothner dot com> <8FDA27DC-2AC0-442E-879B-390760EAC000 at theptrgroup dot com> <5487BD04 dot 4080709 at bothner dot com> <1A9D21C9-3897-47BD-AB86-60D249A9CB8D at theptrgroup dot com> <54891FCF dot 2000608 at bothner dot com> <0890BFFE-8180-4F6D-9F1A-9E93F0E9C9BA at theptrgroup dot com>
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/