The 'case' statement

For the Compleat Fan
Locked
pjot
Posts: 733
Joined: Thu Feb 26, 2004 10:19 pm
Location: The Hague, The Netherlands
Contact:

The 'case' statement

Post by pjot »

Hi,

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

Code: Select all

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

Code: Select all

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

Code: Select all

(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
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

How about if:

Code: Select all

(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
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

and you also use symbol(constant)s:

Code: Select all

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

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

pjot
Posts: 733
Joined: Thu Feb 26, 2004 10:19 pm
Location: The Hague, The Netherlands
Contact:

Post by 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.

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
Posts: 16
Joined: Mon Oct 24, 2005 6:55 pm

Post by PapoAnaya »

pjot wrote: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
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Post by Dmi »

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

Otherwise, you can use something like:

Code: Select all

(define-macro (ecase _v)
  (eval (append (list 'case _v)
		(map (fn (_i) (set-nth 0 _i (eval (_i 0))))
		     (args)))))
so

Code: Select all

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

Locked