Hi,
i could used string->symbol instead of stings with the normal CASE but
i finally wrote a macro for CASE with strings,
it was harder than expected , i learned macro at university with the
define-macro style ,i was familiar with this style, now define-syntax is
used, here is my macro:
(define-syntax case-string
(syntax-rules ( => )
;; (define dog "dog")
;; (case-string dog (("dog") "animal") (else => "mineral or
vegetable"))
((case-string var
lst
(else => res-else ...))
(if (member var (car (quote lst)))
(cadr (quote lst))
(begin
res-else
...)))
;; (define cat "cat")
;; (case-string cat (("dog") "animal") (("cat") "my daughter say cats
are not animals!") (else => "mineral or vegetable"))
((case-string var
lst
lst2
...
(else => res-else ...))
(if (member var (car (quote lst)))
(cadr (quote lst))
(case-string var
lst2
...
(else => res-else ...))))
;;(case-string dog (else => "silly case"))
((case-string var
(else => res-else ...))
(begin
res-else
...))))
i'm not sure if this macro is r5rs compliant but i have test it working.
Regards,
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
>>
>
>