Re: behavior of CASE with strings

Damien Mattei <[email protected]>
Newsgroups gmane.lisp.scheme.bigloo
Message-ID <CADEOadf+++LDz8srLL2p3Vh6hgpjMiqF2-g1-O2_7K9bp1eGEw__24216.3487164818$1484993331$gmane$org@mail.gmail.com>
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
<[email protected]> 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 <[email protected]>:
>>
>> 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
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.