On 11 May 2014 15:18, Hussein B. <hubaghd...@gmail.com> wrote:
> Hi,
>
> I'm trying to learn how to make  DSL in Clojure and Korma project is a
> really good place to learn from. I'm trying this very simple stuff (inspired
> by Korma, not Korma code):

[code snipped]

> But when I'm trying in the REPL:
>
> (select
>   (where
>     (and (= :version 1.6) (= :name "Clojure"))
>
> I'm getting:
>
> ClassCastException java.lang.Character cannot be cast to
> clojure.lang.IPersistentCollection  clojure.core/conj (core.clj:83)
>
> It is really hard to me to know what is going wrong. What is confusing me,
> if I'm trying the where macro alone, it is working as excepted but when
> integrating it with select macro, I got the exception.

Generally, when macros are causing problems, it's good to start
debugging with macroexpand to see what's actually getting executed.

> (macroexpand '(select
  (where
    (and (= :version 1.6) (= :name "Clojure")))))

; (let* [query-map__696__auto__ (clojure.core/-> (#'dsltmp/select*)
(where (and (= :version 1.6) (= :name "Clojure"))))]
query-map__696__auto__)

I then tried macroexpand on the where clause that that would generate:

> (macroexpand '(where select* (and (= :version 1.6) (= :name "Clojure"))))
; (let* [q__703__auto__ select*] (#'dsltmp/where* q__703__auto__
(dsltmp/clauses->vec (:and (:eq :version 1.6) (:eq :name
"Clojure")))))

So the argument getting passed into clauses->vec is (:and (:eq
:version 1.6) (:eq :name "Clojure")) - but it's not a macro, so this
is evaluated:

> (:and (:eq :version 1.6) (:eq :name "Clojure"))
; "Clojure"

(If it's not clear what's going on here, remember that keywords try to
look themselves up in their first argument, and default to their
second argument.)

So 'clauses' is "Clojure", '(rest clauses)' is '(\l \o \j \u \r \e)',
and condition->map is invoked with the argument \l, which triggers the
error you saw:

> (condition->map \l)
; ClassCastException java.lang.Character cannot be cast to
clojure.lang.IPersistentCollection  clojure.core/conj (core.clj:83)

Since the problem is that clauses->vec evaluates its argument,
defining it as a macro instead of a function should fix it.

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to