On 18 March 2010 22:38, alux <alu...@googlemail.com> wrote:
> Again, from my translation of the http://www.lisperati.com/casting.html
> tutorial.
>
> I completely lost track at the macro generating macro (defspel game-
> action ..
>
> In short, Barski writes a very simple (and neat) text adventure. To
> avoid wrong assumtions he doesnt talk about macros but SPELs, using
>
> CL (defmacro defspel (&rest rest) `(defmacro ,@rest))
> Clj (defmacro defspel [& rest] `(defmacro ~...@rest))
>
> I translated everything up to the last page 
> http://www.lisperati.com/actions.html,
> then he arrives at
>
> (defspel game-action (command subj obj place &rest rest)
>  `(defspel ,command (subject object)
>     `(cond ((and (eq *location* ',',place)
>                  (eq ',subject ',',subj)
>                  (eq ',object ',',obj)
>                  (have ',',subj))
>             ,@',rest)
>            (t '(i cant ,',command like that.)))))
>
> Without CL knowledge, I dont really understand whats going on, but
> gave a try (please dont lough to hard :)
>
> (defspel game-action [command subj obj place & rest]
>  `(defspel ~command [subject# object#]
>     `(if ((and (= *location* '~'~place)
>                  (= '~subject# '~'~subj)
>                  (= '~object# '~'~obj)
>                  (have '~'~subj))
>             ~@'~rest)
>            '(i cant ~'~command like that.))))
>
> use
>
> (game-action weld chain bucket attic
>         (if ((and (have 'bucket) (alter-var-root (var *chain-welded*) (fn
> [_] true)))
>                   '(the chain is now securely welded to the bucket.))
>                   '(you do not have a bucket.)))
>
> If I try it, I get
>
> spels=> (weld chain bucket)
> java.lang.ClassCastException: java.lang.Boolean cannot be cast to
> clojure.lang.I
> Fn (NO_SOURCE_FILE:0)
>
> And I'm stuck.

I've just had a brief look and I can't say where it's coming from, but
if you try:

(macroexpand-1 '(weld chain bucket))

You get something like this (after some cleanup):

(if ((and (= *location* 'attic) (= 'chain 'chain) (= 'bucket 'bucket)
(have 'chain)) (if ((and ...

Those ((and ...)) are the problem.  (and ...) will return true or false.
(true) or (false) are invalid because they are true and false are not
functions (i.e. they don't implement the clojure.lang.IFn interface.)
So ((and ...)) is trying to treat a boolean as a function, which
explains the exception.

By the way, you might want to use keywords like :chain instead of
symbols.  Also your (fn [_] true) could be replaced by (constantly
true).  It's not exactly the same, because (constantly true) is more
like (fn [& rest] true), but it should be close enough.  :)

-- 
Michael Wood <esiot...@gmail.com>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.

Reply via email to