Re: [bigloo] behavior of CASE with strings

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [bigloo] behavior of CASE with strings

Manuel.Serrano
Hi Damien,

Bigloo complies with the R5RS specification (see section 4.2) that says:

-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
case <key> <clause1> <clause2> ..., library syntax
Syntax: <Key> may be any expression. Each <clause> should have the form

((<datum1> ...,) <expression1> <expression2> ...,),

where each <datum> is an external representation of some object. All the <datum>s must be distinct. The last <clause> may be an ``else clause,'' which has the form

(else <expression1> <expression2> ...,).

Semantics: A case expression is evaluated as follows. <Key> is evaluated and its result is compared against each <datum>. If the result of evaluating <key> is equivalent (in the sense of eqv?; see section Equivalence predicates) to a <datum>, then the expressions in the corresponding <clause> are evaluated from left to right and the result(s) of the last expression in the <clause> is(are) returned as the result(s) of the case expression. If the result of evaluating <key> is different from every <datum>, then if there is an else clause its expressions are evaluated and the result(s) of the last is(are) the result(s) of the case expression; otherwise the result of the case expression is unspecified.

(case (* 2 3)
  ((2 3 5 7) 'prime)
  ((1 4 6 8 9) 'composite))            =>  composite
(case (car '(c d))
  ((a) 'a)
  ((b) 'b))                            =>  unspecified
(case (car '(c d))
  ((a e i o u) 'vowel)
  ((w y) 'semivowel)
  (else 'consonant))                   =>  consonant
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----

You can observe that with:

(pp (expand '(case x (("foo") 1) (("bar" ) 2))))
=>
(let ((case-value x))
  (if (eqv? case-value '"foo")
    1
    (if (eqv? case-value '"bar") 2 #unspecified)))

Cheers,

--
Manuel
Reply | Threaded
Open this post in threaded view
|

Re: [bigloo] behavior of CASE with strings

Damien Mattei-2
Hi bent,

i did not completely understood your example, now it's clear it solves
the problem,
with 'member' instead of 'memv' it's ok for the strings.

i will use this next week,

Thanks a lot,

Damien

On Tue, Jan 17, 2017 at 8:27 PM, Bent Phillipsen
<[hidden email]> wrote:

> Hi Damien,
>
> This question has already been answered. Should it be of interest, I would
> like to add the following:
>
> R5RS specifies that the case expression tests equivalence with eqv? (p.10),
> but also that equivalence test of strings with eqv? is 'unspecified' (p.18).
> This has the consequence that stings cannot be used as key and clause in
> case expressions in a well defined way (or at least portable way). You can
> however easily define a macro that *also* can use strings. You can write
> your own; but simply taking the case macro defined in R5RS (p.43) ensures
> that all corner cases are handled correctly. You then just need to replace
> 'memv' with 'member' (this has the effect of testing equivalence with equal?
> instead of eqv?). You probably want to change the name of the macro also,
> for instance to case-member, to avoid shadowing the original case
> expression. You will get something like the following, which should work and
> which I think is portable. (There is of cause a (mostly insignificant)
> performance penalty in testing with equal? instead of eqv?):
>
> --------------------------------------
>
> (module test-case-member
>         (main start))
>
> (define-syntax case-member
>         (syntax-rules (else)
>                 ((case-member (key ...)
>                         clauses ...)
>                  (let ((atom-key (key ...)))
>                         (case-member atom-key clauses ...)))
>                 ((case-member key
>                         (else result1 result2 ...))
>                  (begin result1 result2 ...))
>                 ((case-member key
>                         ((atoms ...) result1 result2 ...))
>                  (if (member key '(atoms ...))
>                         (begin result1 result2 ...)))
>                 ((case-member key
>                         ((atoms ...) result1 result2 ...) clause clauses
> ...)
>                  (if (member key '(atoms ...))
>                         (begin result1 result2 ...)
>                         (case-member key clause clauses ...)))))
>
> (define (start argv)
>
>         (define x (string-append "b" "a" "r"))
>         (define y "animal")
>         (define z 'composit)
>
>         (print "next line should be '" y "':")
>         (print (case-member (string-append "do" "g") (("cat" "dog" "mouse")
> y) (else "mineral or vegetable")))
>
>         (print (string-append "next line should be '" x "':"))
>         (case-member x
>                 (("foo")  (print 'foo))
>                 (("bar")  (print 'bar))
>                 (else "it was not foo or bar"))
>
>         (print (string-append "next line should be '" (symbol->string z)
> "':"))
>         (print (case-member (* 2 3) ((2 3 5 7) 'prime)
>                                     ((1 4 6 8 9) z))))
>
> ---------------------------------
>
> Best regards
>
> Bent
>
>
> 2017-01-16 14:32 GMT+01:00 <[hidden email]>:
>>
>> Hi Damien,
>>
>> Bigloo complies with the R5RS specification (see section 4.2) that says:
>>
>>
>> -----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
>> case <key> <clause1> <clause2> ...,     library syntax
>> Syntax: <Key> may be any expression. Each <clause> should have the form
>>
>> ((<datum1> ...,) <expression1> <expression2> ...,),
>>
>> where each <datum> is an external representation of some object. All the
>> <datum>s must be distinct. The last <clause> may be an ``else clause,''
>> which has the form
>>
>> (else <expression1> <expression2> ...,).
>>
>> Semantics: A case expression is evaluated as follows. <Key> is evaluated
>> and its result is compared against each <datum>. If the result of evaluating
>> <key> is equivalent (in the sense of eqv?; see section Equivalence
>> predicates) to a <datum>, then the expressions in the corresponding <clause>
>> are evaluated from left to right and the result(s) of the last expression in
>> the <clause> is(are) returned as the result(s) of the case expression. If
>> the result of evaluating <key> is different from every <datum>, then if
>> there is an else clause its expressions are evaluated and the result(s) of
>> the last is(are) the result(s) of the case expression; otherwise the result
>> of the case expression is unspecified.
>>
>> (case (* 2 3)
>>   ((2 3 5 7) 'prime)
>>   ((1 4 6 8 9) 'composite))            =>  composite
>> (case (car '(c d))
>>   ((a) 'a)
>>   ((b) 'b))                            =>  unspecified
>> (case (car '(c d))
>>   ((a e i o u) 'vowel)
>>   ((w y) 'semivowel)
>>   (else 'consonant))                   =>  consonant
>>
>> -----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
>>
>> You can observe that with:
>>
>> (pp (expand '(case x (("foo") 1) (("bar" ) 2))))
>> =>
>> (let ((case-value x))
>>   (if (eqv? case-value '"foo")
>>     1
>>     (if (eqv? case-value '"bar") 2 #unspecified)))
>>
>> Cheers,
>>
>> --
>> Manuel
>
>
Reply | Threaded
Open this post in threaded view
|

Re: [bigloo] behavior of CASE with strings

Per Bothner
On Tue, Jan 17, 2017 at 8:27 PM, Bent Phillipsen <[hidden email]> wrote:

> This has the consequence that stings cannot be used as key and clause in
> case expressions in a well defined way (or at least portable way). You can
> however easily define a macro that *also* can use strings. You can write
> your own; but simply taking the case macro defined in R5RS (p.43) ensures
> that all corner cases are handled correctly. You then just need to replace
> 'memv' with 'member' (this has the effect of testing equivalence with equal?
> instead of eqv?). You probably want to change the name of the macro also,
> for instance to case-member, to avoid shadowing the original case
> expression. You will get something like the following, which should work and
> which I think is portable. (There is of cause a (mostly insignificant)
> performance penalty in testing with equal? instead of eqv?):

In Kawa 'case' is optimized, so the performance penalty of re-implementing
case "by hand" would be more significant.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/