Page 1 of 1

The 'case' statement

Posted: Mon Nov 14, 2005 11:36 am
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

Posted: Mon Nov 14, 2005 11:47 am
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"
) 

Posted: Mon Nov 14, 2005 12:02 pm
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

Posted: Mon Nov 14, 2005 12:19 pm
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

Posted: Mon Nov 14, 2005 2:56 pm
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

Posted: Tue Nov 15, 2005 6:57 am
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