From: Kenneth Tilton on 5 Jan 2010 22:12 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 6 Jan 2010 01:49 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 6 Jan 2010 03:56 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 6 Jan 2010 13:37 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 6 Jan 2010 13:56
* (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 |