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 > >
