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: Tue, 09 Dec 2014 19:24:52 -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>
On 12/09/2014 01:16 PM, Jamison Hope wrote:
On Dec 9, 2014, at 12:48 AM, Per Bothner <per@bothner.com> wrote:
The syntax (? NAME::TYPE VALUE) can be used in conditional forms:
if, and, cond, etc. First VALUE is evaluated. Then if the result
is an compatible with TYPE, then NAME is bound to the result
(possibly after conversion). The result is #t, but with the "side effect"
that NAME is lexically bound in "following forms". If VALUE doesn't
match TYPE then the ?-form is false.
Is the result actually #t, or some unspecified true value?
Well, (? NAME::TYPE VALUE) isn't actually an expression - it's more a
pseudo-expression or a "sub-clause" of and/if/etc.
Is something like this supposed to work?
#|kawa:1|# (define (f x) (cond ((? r ::real x) => (lambda (y) y)) (else #f)))
/dev/stdin:1:22: '?' is only allowed in a conditional e.g. 'if' or 'and'
No, I don't think that makes sense. However, the following does:
(define (f x) (cond ((? r ::real x) r) (else #f)))
Types backed by Java primitives seem to be troublesome. I get VerifyErrors
("Bad type on operand stack") with the following:
(define (f x) (if (? b ::boolean x) b #f))
(define (f x) (if (? c ::character x) c #\?))
Ouch. I fixed those. I also fixed char and character-or-eof.
(The char type doesn't match for characters above #\xFFFF, but character does.)
What types of implicit conversions are to be expected? I find the
difference between these to be slightly unintuitive.
#|kawa:5|# (map (lambda (x) (if (? i ::int x) i -1)) '(3 "hello" 3.5 #\?))
(3 -1 3 -1)
#|kawa:6|# (map (lambda (x) (if (? i ::integer x) i -1)) '(3 "hello" 3.5 #\?))
(3 -1 -1 -1)
Note that 3.5 becomes int 3, but not integer 3.
I think both of those should be false.
Likewise for 'short' should *not* match if the values is not in the 'short' range.
#|kawa:7|# (map (lambda (x) (if (? s ::string x) s "N/A")) '(3 "hello" 3.5 #\?))
(N/A hello N/A N/A)
but
#|kawa:8|# (map (lambda (x) (if (? s ::String x) s "N/A")) '(3 "hello" 3.5 #\?))
Exception in thread "main" java.lang.NoClassDefFoundError: String
"String" is a special kind of type - which always matches. I checked in a fix for this.
Btw I checked in some tests loosely based on your tests.
--
--Per Bothner
per@bothner.com http://per.bothner.com/