The 'case' statement

Started by pjot, November 14, 2005, 03:36:43 AM

Previous topic - Next topic

pjot

Hi,



As known, the 'case' statement must be used as follows:



(case n
    (1 "one")
    (2 "two")          
    (3 "three")
    (4 "four")
    (true "Can't translate this")
)


This works fine but I find it a bit limited. Because it is impossible to use constants instead of the actual values. E.g. this is impossible:



(constant 'one 1)
(constant 'two 2)
(constant 'three 3)
(constant 'four 4)
(case n
    (one "this is one")
    (two "this is two")
    (three "this is three")
    (four "this is four")
    (true "Can't translate this")
)


So there is no way to compare variable or constant names in a case statement. In case of programs using an external context for example, this turns out to be quite annoying:



(case k
(0x0065: #GLUT:GLUT_KEY_UP:
(set 'view_rotx (add view_rotx 5.0))
)
(0x0067: #GLUT:GLUT_KEY_DOWN:
(set 'view_rotx (sub view_rotx 5.0))
)
(0x0064: #GLUT:GLUT_KEY_LEFT:
(set 'view_roty (add view_roty 5.0))
)
(0x0066: #GLUT:GLUT_KEY_RIGHT:
(set 'view_roty (sub view_roty 5.0))
)
)


So the constant values which are intentionally kept in a separate context, cannot be used in a case statement. Instead, I have to lookup the actual values again and use those. If not, I receive the error 'symbol expected'.



Why is this case statement designed this way? Wouldn't it be more convenient to use constants and even expressions as well?



Peter

HPW

#1
How about if:



(constant 'one 1)
(constant 'two 2)
(constant 'three 3)
(constant 'four 4)

(setq n 4)

(if
    (= n one) "this is one"
    (= n two) "this is two"
    (= n three) "this is three"
    (= n four) "this is four"
    "Can't translate this"
)
Hans-Peter

Lutz

#2
and you also use symbol(constant)s:

(define (select-sym s)
  (case s
    (one 1)
    (two 2)
    (three 3)
    "unknown"))

(select-sym 'one) => 1
(select-sym 'two) => 2


Lutz

pjot

#3
Hm, ok. But then I don't see the use of the 'case' statement. It can be withdrawn from newLisp completely, since all selections can be peformed with 'if' just as easy.



The use of symbols may not be convenient in my case, since the selection needs values kept in a context.



Thanks for the suggestions!

Peter

PapoAnaya

#4
Quote from: "pjot"Hm, ok. But then I don't see the use of the 'case' statement. It can be withdrawn from newLisp completely, since all selections can be peformed with 'if' just as easy.


Well, there might be a case for "case" if there is less overhead than "if" or "cond".



Papo

Dmi

#5
'case' doesn't evaluate its "key" argument, so it must be faster in computations...



Otherwise, you can use something like:
(define-macro (ecase _v)
  (eval (append (list 'case _v)
(map (fn (_i) (set-nth 0 _i (eval (_i 0))))
    (args)))))

so
(set 'c 'a)
(ecase 'a (c 1) (b 2)) => 1
WBR, Dmi