From: W. James on
Thomas A. Russ wrote:

> Cecil Westerhof <Cecil(a)decebal.nl> writes:
>
> > I can not find much about case, but I found the following:
> > case is a conditional that chooses one of its clauses to
> > execute by comparing a value to various constants, which are
> > typically keyword symbols, integers, or characters (but may be
> > any objects).
>
> Well, the key item you need to consider for any of these comparison
> constructs is to make sure you understand what predicate is used to do
> the comparison for the selection of the items. From the HyperSpec:
>
> "If the test-key is the SAME as any key for that clause, the forms
> in that clause are evaluated as an implicit progn, and the values
> it returns are returned as the value of the case, ccase, or ecase
> form."
>
> So, now we need to know what "SAME" means in this context. The
> HyperSpec definition that is relevant is the second one:
>
> SAME: "... 2. (of objects if no predicate is implied by context)
> indistinguishable by eql."
>
> So that means that EQL is the test used for matching. And constant
> strings with the same characters may or may not be EQL, and this can
> differ depending on whether the function or file is compiled or not.
>
> > So I would expect that I can use strings in a case statement.
> >
> > I tried the following:
> > (defun do-command (this-command)
> > (case this-command
> > ("d" (display-recipe-names))
> > (otherwise (format t "#~a# is an unknown command~%"
> > this-command))))
> >
> > But when feeding this "d" I get:
> > #d# is an unknown command
> >
> > So properly I need to do something special to use strings. How
> > would I do this?
>
> Yes. You either need to make sure that they are the same object
> (which can be a bit tricky for strings but is doable), or you need to
> INTERN the strings and use symbols (which is the easy way to make it
> work) or you need to use one of the 3rd party utility libraries that
> implements a different CASE-like statement that can handle strings.
>
> Or, as an exercise in macro writing, you could write your own
> STRING-CASE macro. That might be a nice learning exercise in its own
> right.
>
> One method of making it work would be:
>
> (progn ;; Needed to have a single READER context
> (defconstant D-COMMAND #1="d")
> (defun do-command (this-command)
> (case this-command
> (#1# (format t "Found command ~A" this-command))
> (otherwise (format t "#~a# is an unknown command~%"
> this-command)))))
>
> But to use this, you need to specify the stored constant D-COMMAND:
>
> (do-command d-command)
> Found command d
> NIL
>
> (do-command "d")
> #d# is an unknown command
> NIL
>
> So you can't use this to execute commands that you get, for example,
> by reading in terminal input. To do that you would need to either
> intern the string or use a different case structure.
>
> There is actually a cleverer solution that uses a hash table and
> registered functions that doesn't even use case at all. It is nicely
> extensible and very general. And it is dead simple to implement in
> Lisp.


Bigloo Scheme:


(match-case "d"
("d" (print "displaying recipes"))
(else (print "unknown command")))

--

From: refun on
In article <87wrzxse0p.fsf(a)Traian.DecebalComp>, Cecil(a)decebal.nl says...
>
> I can not find much about case, but I found the following:
> case is a conditional that chooses one of its clauses to execute by
> comparing a value to various constants, which are typically keyword
> symbols, integers, or characters (but may be any objects).
>
> So I would expect that I can use strings in a case statement.
>
> I tried the following:
> (defun do-command (this-command)
> (case this-command
> ("d" (display-recipe-names))
> (otherwise (format t "#~a# is an unknown command~%" this-command))))
>
> But when feeding this "d" I get:
> #d# is an unknown command
>
> So properly I need to do something special to use strings. How would I
> do this?

A few solutions to your problem as I see it:
1. Use symbols instead of strings.
2. Make your own case-like macro which uses a hashtable.
It would be an interesting exercise
3. Use a more general construct like SWITCH from the arnesi library.
http://common-lisp.net/project/bese/docs/arnesi/html/api/macro_
005FIT.BESE.ARNESI_003A_003ASWITCH.html
You would use it like this:

(defun do-command (this-command)
(switch (this-command :test #'equal)
("d" (display-recipe-names))
(t (format t "#~a# is an unknown command~%" this-command))))

;; The switch would expand to:
(let ((#:g1110 this-command) (#:g1111 #'equal))
(cond ((or (funcall #:g1111 '"d" #:g1110))
(display-recipe-names))
(t (format t "#~a# is an unknown command~%" this-command))))

This shows that each test will be evaluated sequentially, which means
it's less efficient than the hashtable solution.
From: Pillsy on
On Jan 4, 10:27 pm, Kenneth Tilton <kentil...(a)gmail.com> wrote:
[...]
> One of the best ideas in Lisp is that of the symbol. Use them. Not strings.

>       (do-command 'd)

> ...and...

>       (case cmd (d (display-recipe-names)))

> If you get a string, quick, intern it.

> kt

> * But it /was/ funny to see the contorted monstrosities up with which
> they came. kt

Like using FIND-SYMBOL instead of INTERN. Heathens!

Cheers,
Pillsy
From: joswig on
On 5 Jan., 15:31, refun <re...(a)nospam.gmx.com> wrote:

> (defun do-command (this-command)
>   (switch (this-command :test #'equal)
>     ("d"       (display-recipe-names))
>     (t         (format t "#~a# is an unknown command~%" this-command))))

Symbolics Common Lisp:

(defun do-command (this-command)
(scl:selector this-command equal
("d" (display-recipe-names))
(t (format t "#~a# is an unknown command~%" this-command))))





From: Kenneth Tilton on
Pillsy wrote:
> On Jan 4, 10:27 pm, Kenneth Tilton <kentil...(a)gmail.com> wrote:
> [...]
>> One of the best ideas in Lisp is that of the symbol. Use them. Not strings.
>
>> (do-command 'd)
>
>> ...and...
>
>> (case cmd (d (display-recipe-names)))
>
>> If you get a string, quick, intern it.
>
>> kt
>
>> * But it /was/ funny to see the contorted monstrosities up with which
>> they came. kt
>
> Like using FIND-SYMBOL instead of INTERN. Heathens!
>
> Cheers,
> Pillsy

Now, Pillsy, we talked about you needing to read the notes:

"Notes: find-symbol is operationally equivalent to intern, except that
it never creates a new symbol."

So if you /get/ a string (say, the column name of a CSV file) quick,
intern it. Do not build a string version of Lisp.

Why do You People bother trying to correct me? Even EG/RG acknowledges
that I am the final arbiter of all things Lisp.

His Kennyness

--

http://www.stuckonalgebra.com