From: verec
Subject: unquote/eval/ecase
Date: 
Message-ID: <46e5d14e$0$653$5a6aecb4@news.aaisp.net.uk>
This works:

(defun foo2 (n)
  (ecase n
    (1 (prog1 'foo-one (hello)))
    (2 (prog1 'foo-two (hella)))))

(defun hello ()
  (format t "hello~%"))

(defun hella ()
  (format t "hella~%"))

CL-USER 4 > (foo2 1)
hello
foo-one

CL-USER 5 > (foo2 2)
hella
foo-two

This doesn't:

(defconstant +one+ 1)
(defconstant +two+ 2)

(defun foo (n)
  (ecase n
    (+one+ (prog1 'foo-one (hello)))
    (+two+ (prog1 'foo-two (hella)))))

CL-USER 6 > (foo 1)
1 fell through |ECASE| expression.
Wanted one of (+one+ +two+).

In this "ecase" case is there a way to force (eval) the key
or is ecase only to be used with literal values? CLHS says
that "keyform" is unevaluated. But is there a way to force
its evaluation?

Or any other xxxcase variant that would allow ne to use symbolic
values in place of literal constants?

I can obviously use cond instead:

(defun foo3 (n)
  (cond
    ((eql n +one+) (prog1 'foo-one (hello)))
    ((eql n +two+) (prog1 'foo-two (hella)))
    (t (prog1 'huh?))))

CL-USER 6 > (foo3 1)
hello
foo-one

CL-USER 7 > (foo3 2)
hella
foo-two

CL-USER 8 > (foo3 3)
huh?

But I was just wondering whether there was a ``usable case'' ?

Many thanks
--
JFB

From: Barry Margolin
Subject: Re: unquote/eval/ecase
Date: 
Message-ID: <barmar-174034.19385410092007@comcast.dca.giganews.com>
In article <·······················@news.aaisp.net.uk>,
 verec <·····@mac.com> wrote:

> In this "ecase" case is there a way to force (eval) the key
> or is ecase only to be used with literal values? CLHS says
> that "keyform" is unevaluated. But is there a way to force
> its evaluation?

CASE and ECASE are only for literal values.  The idea is that the 
compiler might be able to optimize it if it knows all the values (e.g. 
if they're integers in a small range, it can compile into a simple 
dispatch table).

You could use "#.".  But I'd recommend writing your own macro that does 
what you want instead.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Carl Taylor
Subject: Re: unquote/eval/ecase
Date: 
Message-ID: <yHkFi.84611$ax1.29978@bgtnsc05-news.ops.worldnet.att.net>
verec wrote:
> This works:
[...] 
> This doesn't:
> 
> (defconstant +one+ 1)
> (defconstant +two+ 2)
> 
> (defun foo (n)
>  (ecase n
>    (+one+ (prog1 'foo-one (hello)))
>    (+two+ (prog1 'foo-two (hella)))))
> 
> CL-USER 6 > (foo 1)
> 1 fell through |ECASE| expression.
> Wanted one of (+one+ +two+).

CL-USER 14 > 

(defun foo (n)
   (ecase n
       (#.+one+  (prog1 'foo-one (hello)))
       (#.+two+  (prog1 'foo-two (hella)))))
FOO

CL-USER 15 >  (foo 1)
hello
FOO-ONE

You could force read-time evaluation.

Carl Taylor
From: Madhu
Subject: Re: unquote/eval/ecase
Date: 
Message-ID: <m3sl5m9iu4.fsf@robolove.meer.net>
* verec <·······················@news.aaisp.net.uk> :

| (defconstant +one+ 1)
| (defconstant +two+ 2)
|
| (defun foo (n)
|  (ecase n
|    (+one+ (prog1 'foo-one (hello)))
|    (+two+ (prog1 'foo-two (hella)))))
|

Typically this is handled with the read time evaluation of the
constants like this:

(defun foo (n)
 (ecase n
   (#.+one+ (prog1 'foo-one (hello)))
   (#.+two+ (prog1 'foo-two (hella)))))

| In this "ecase" case is there a way to force (eval) the key
| or is ecase only to be used with literal values? CLHS says
| that "keyform" is unevaluated. But is there a way to force
| its evaluation?
|
| Or any other xxxcase variant that would allow ne to use symbolic
| values in place of literal constants?

You may want to wrap up your defconstant or defvar forms in an eval-when
depending on your lisp implementation
--
Madhu