From: Kenneth Tilton on
Thomas A. Russ wrote:
> Kenneth Tilton <kentilton(a)gmail.com> writes:
>
>> * But it /was/ funny to see the contorted monstrosities up with which
>> they came. kt
>
> Actually, I think the point of the contorted monstrosties was to
> demonstrate that while you COULD make it work, you wouldn't want to.
>

I don't know, I think they meant it: this group has a long tradition of
robotically answering nooby questions as if somehow the noobs were
master Lisp programmers asking perfect questions. The only thing missing
was Costanza with a CLOS metaclass-based solution, or something that
took a simple case statement and exploded it into a bunch of scattered
metods, that would have been nice.

Where do I go to retract a fortune cookie?

kt

--
"There are no mediocre Lisp programmers." - kenny tilton
From: Pascal J. Bourguignon on
Kenneth Tilton <kentilton(a)gmail.com> writes:

> Thomas A. Russ wrote:
>> Kenneth Tilton <kentilton(a)gmail.com> writes:
>>
>>> * But it /was/ funny to see the contorted monstrosities up with which
>>> they came. kt
>>
>> Actually, I think the point of the contorted monstrosties was to
>> demonstrate that while you COULD make it work, you wouldn't want to.
>>
>
> I don't know, I think they meant it: this group has a long tradition
> of robotically answering nooby questions as if somehow the noobs were
> master Lisp programmers asking perfect questions.

Clearly, you don't understand the zen of cll...


> The only thing
> missing was Costanza with a CLOS metaclass-based solution, or
> something that took a simple case statement and exploded it into a
> bunch of scattered metods, that would have been nice.

We didn't miss it, only it was latent. We explained how to use a
hash-table. There are two ways to fill it:

- either write a case-like macro that builds this hash-table at
run-time (because of the clause body closures), but it wouldn't be
efficient to build it each time...

- or bit the bullet and just build that hash-table once for all
explicitely, hence scatter the functions:

(define-case-clause my-command-case "d" (parameter)
(do-something-d parameter))

(define-case-clause my-command-case "e" (parameter)
(do-something-e parameter))

...


(string-case my-command-case (read-line) argument)


> Where do I go to retract a fortune cookie?

Not "Where". When!
When you invent a time machine.

--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Tamas K Papp on
On Wed, 06 Jan 2010 07:49:18 +0100, Pascal J. Bourguignon wrote:

> Kenneth Tilton <kentilton(a)gmail.com> writes:
>
>> Thomas A. Russ wrote:
>>> Kenneth Tilton <kentilton(a)gmail.com> writes:
>>>
>>>> * But it /was/ funny to see the contorted monstrosities up with which
>>>> they came. kt
>>>
>>> Actually, I think the point of the contorted monstrosties was to
>>> demonstrate that while you COULD make it work, you wouldn't want to.
>>>
>>>
>> I don't know, I think they meant it: this group has a long tradition of
>> robotically answering nooby questions as if somehow the noobs were
>> master Lisp programmers asking perfect questions.
>
> Clearly, you don't understand the zen of cll...
>
>
>> The only thing
>> missing was Costanza with a CLOS metaclass-based solution, or something
>> that took a simple case statement and exploded it into a bunch of
>> scattered metods, that would have been nice.
>
> We didn't miss it, only it was latent. We explained how to use a
> hash-table. There are two ways to fill it:
>
> - either write a case-like macro that builds this hash-table at
> run-time (because of the clause body closures), but it wouldn't be
> efficient to build it each time...
>
> - or bit the bullet and just build that hash-table once for all
> explicitely, hence scatter the functions:
>
> (define-case-clause my-command-case "d" (parameter)
> (do-something-d parameter))
>
> (define-case-clause my-command-case "e" (parameter)
> (do-something-e parameter))

Couldn't one use LOAD-TIME-VALUE? For example:

(defun make-hash-to-integers (test args keyslist)
(let ((hash-table (apply #'make-hash-table :test test args))
(i 0))
(dolist (keys keyslist)
(dolist (key (if (atom keys) (list keys) keys))
(setf (gethash key hash-table) i))
(incf i))
hash-table))

(defmacro hash-ecase (keyform (&optional (test '(function eql)) &rest
args) &body cases)
"ECASE construct using a hash table. TEST specifies the test
function to use, ARGS is passed to MAKE-HASH-TABLE directly. The hash
table is constructed using LOAD-TIME-VALUE, and it is supposed to
contain constants only."
(let ((hash-table (gensym "HASH-TABLE")))
`(let ((,hash-table (load-time-value
(make-hash-to-integers ,test ,args ',(mapcar #'car cases)))))
(ecase (gethash ,keyform ,hash-table)
,@(let ((i 0))
(mapcar (lambda (case)
(prog1 `(,i ,@(cdr case))
(incf i)))
cases))))))

(defun test-hash-ecase (key)
(hash-ecase key (#'equal)
((1 2 3) :number)
(("foo" "bar") :string)
(symbol :symbol)))

(test-hash-ecase "bar")
(test-hash-ecase 3)
(test-hash-ecase 'symbol)


No bells/whistles (t/otherwise clause), but it could be done pretty
easily (eg mapping the default to 0 and starting numbering from 1).
There is a CASE left in there, but it is on a consecutive range of
integers, and most compilers should be able to optimize this very
easily.

Tamas
From: Pascal J. Bourguignon on
Tamas K Papp <tkpapp(a)gmail.com> writes:

> Couldn't one use LOAD-TIME-VALUE? For example:
>
> (defun make-hash-to-integers (test args keyslist)
> (let ((hash-table (apply #'make-hash-table :test test args))
> (i 0))
> (dolist (keys keyslist)
> (dolist (key (if (atom keys) (list keys) keys))
> (setf (gethash key hash-table) i))
> (incf i))
> hash-table))
>
> (defmacro hash-ecase (keyform (&optional (test '(function eql)) &rest
> args) &body cases)
> "ECASE construct using a hash table. TEST specifies the test
> function to use, ARGS is passed to MAKE-HASH-TABLE directly. The hash
> table is constructed using LOAD-TIME-VALUE, and it is supposed to
> contain constants only."
> (let ((hash-table (gensym "HASH-TABLE")))
> `(let ((,hash-table (load-time-value
> (make-hash-to-integers ,test ,args ',(mapcar #'car cases)))))
> (ecase (gethash ,keyform ,hash-table)
> ,@(let ((i 0))
> (mapcar (lambda (case)
> (prog1 `(,i ,@(cdr case))
> (incf i)))
> cases))))))
>
> (defun test-hash-ecase (key)
> (hash-ecase key (#'equal)
> ((1 2 3) :number)
> (("foo" "bar") :string)
> (symbol :symbol)))
>
> (test-hash-ecase "bar")
> (test-hash-ecase 3)
> (test-hash-ecase 'symbol)

Nice.

--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Madhu on

* (Pascal J. Bourguignon) <873a2jt6zl.fsf(a)hubble.informatimago.com> :
Wrote on Wed, 06 Jan 2010 19:37:18 +0100:

| Tamas K Papp <tkpapp(a)gmail.com> writes:
|
|> Couldn't one use LOAD-TIME-VALUE? For example:
|>
|> (defun make-hash-to-integers (test args keyslist)
|> (let ((hash-table (apply #'make-hash-table :test test args))
|> (i 0))
|> (dolist (keys keyslist)
|> (dolist (key (if (atom keys) (list keys) keys))
|> (setf (gethash key hash-table) i))
|> (incf i))
|> hash-table))
|>
|> (defmacro hash-ecase (keyform (&optional (test '(function eql)) &rest
|> args) &body cases)
|> "ECASE construct using a hash table. TEST specifies the test
|> function to use, ARGS is passed to MAKE-HASH-TABLE directly. The hash
|> table is constructed using LOAD-TIME-VALUE, and it is supposed to
|> contain constants only."
|> (let ((hash-table (gensym "HASH-TABLE")))
|> `(let ((,hash-table (load-time-value
|> (make-hash-to-integers ,test ,args ',(mapcar #'car cases)))))
|> (ecase (gethash ,keyform ,hash-table)
|> ,@(let ((i 0))
|> (mapcar (lambda (case)
|> (prog1 `(,i ,@(cdr case))
|> (incf i)))
|> cases))))))
|>
|> (defun test-hash-ecase (key)
|> (hash-ecase key (#'equal)
|> ((1 2 3) :number)
|> (("foo" "bar") :string)
|> (symbol :symbol)))
|>
|> (test-hash-ecase "bar")
|> (test-hash-ecase 3)
|> (test-hash-ecase 'symbol)
|
| Nice.

This looked vaguely familiar. Compare this solution with Naggum's
WITH-HASHED-IDENTITY solution at
<http://groups.google.com/group/comp.lang.lisp/msg/a79ba3b04895a4d8>

Message-ID: <3208606982556119(a)naggum.net>
Date: Tue, 04 Sep 2001 15:43:06 GMT
Subject: Re: How can i make "case" to use equal?
From: Erik Naggum <erik(a)naggum.net>



--
Madhu