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
>