aaa ok now I understand what you mean....I'm really sorry but I hadn't
read all your original questions. So lets set things straight:
1. should I attach the meta to the object, or to its var? or maybe I
shouldn't do it at all, and just omit such checks altogether? (but I
would still like to know how to make it work ;d)
meta-data are always attached on the var if I'm not mistaken...
2. how do I retrieve the meta of an object that is specified by a
symbol passed to a macro by the user?
the general answer here is that you use ~ inside a syntax-quote to jump
right out of the quoting which results in evaluating the expression. If
you're not in a syntax-quoted form then I can only think of 'eval' which
will resolve the var anyway...
4. in the exception above, the symbol is resolved to the
clojure.core/name, which is wrong as well; I know I can change the
symbol name, but I have the feeling that this is not the way to go ;d
I'm not sure how to answer this...I know what t do inside the macro to
avoid symbol capturing but I'm not sure what to do in the actual
parameter list of the macro...
So, with all these in place I'd say you're looking for something like this:
(defmacro with-obj [ob]
(if-let [obj-meta (eval `(meta ~ob))] (println "nice")
(throw (IllegalArgumentException. (str ob " seems not be our
object")))))
Let's see how it works:
user=> (def my-name "JIM")
#'user/my-name
user=> (defrecord NAME [^String s])
user.NAME
user=> (def your-name (NAME. "Wujek" {:surname "Srujek"} nil))
;;your-name has meta-data
#'user/your-name
user=> (macroexpand '(with-obj my-name))
IllegalArgumentException my-name seems not be our object user/with-obj
(NO_SOURCE_FILE:4)
user=> (macroexpand '(with-obj your-name))
nice
nil
I think we 're getting there yes? Is this more helpful?
Jim
On 14/01/13 15:46, Wujek Srujek wrote:
When I invoke a macro:
(with-object someobject)
someobject is not evaluated, it is passed as a symbol to the macro. I
need somehow to get the meta for the object that is hidden behind that
symbol. So, I won't be passing objects in-line, as you did in your Foo
example, I will first be doing:
(defobject foo {map of my functions / values})
(with-object foo (some-expressions))
Throwing an exception when meta is not there is one thing what I want
(the missing part); the printing was just there to make the example
shorter, it's not actually the real code - I don't need a macro for
that. In reality, after all checks, there is code generated that
desctructures the map in a (let) and executes some-expressions in this
context, making certain bindings available for the expressions. This
bit works fine, it's just the meta check that doesn't work as I don't
know how to get the object that the symbol points to (in the macro,
all I have is just a symbol):
user=> (def somename 17)
#'user/somename
user=> (defmacro testabc [name] (class name))
#'user/testabc
user=> (testabc somename)
clojure.lang.Symbol
When I change the macro like this:
user=> (defmacro testabc [name] name)
the object is returned:
user=> (testabc somename)
17
but it is because after macro expansion the returned symbol resolves
to the object I set before. I would like to be able to get access to
that object at macro call time.
But when I come to think about it now, I guess this would be
impossible? Are the vars available when the macro is called? i.e.:
user=> (def somename 17)
user=> (testabc somename) ; <- in this macro, I need to take the
'somename' symbol and retrieve value 17 from above - is this possible
at all?
Thanks for your help,
wujek
On Mon, Jan 14, 2013 at 4:25 PM, Jim foo.bar <jimpil1...@gmail.com
<mailto:jimpil1...@gmail.com>> wrote:
I am not sure I follow...Do you by any chance want the
macro-expansion to lead you directly to one of your two options
(printing or exception)? In this case you can do this:
(defmacro with-obj [ob]
(if-let [obj-meta (meta ob)] (eval ob) ;not replacing any code
but eval-ing on the fly
(throw (IllegalArgumentException. (str ob " seems not be our
object")))))
(defrecord Foo [a b])
user=> (macroexpand '(with-obj "Jim"))
IllegalArgumentException Jim seems not be our object user/with-obj
(NO_SOURCE_FILE:3)
user=> (macroexpand '(with-obj (with-meta (Foo. 'x 'y) {:t 1 :p 2})))
#user.Foo{:a x, :b y}
So now you get the exception or the actual object at
macro-expansion time...Does that help at all?
Jim
On 14/01/13 14:56, Wujek Srujek wrote:
Actually, the with-object mecro is very similar to
clojure.algo.monads/with-monad - it also lets a few bindings,
like m-bind or m-result, and executes user-defined expressions in
the context of the monad specified by a name. They just don't
perform such checks, you can call with-monad with any symbol, and
you will get an NPE:
user=> (require '[clojure.algo.monads :refer :all])
user=> (domonad identity-m [a 2 b 3] (* a b))
6
user=> (domonad whatever [a 2 b 3] (* a b))
NullPointerException user/eval1803 (NO_SOURCE_FILE:1)
That's probably because the monad functions set up by with-monad
are nils. (domonad uses with-monad under the hood.) If I perform
my check, I will be able to give a much nicer error message, and
there is a lot value in that.
wujek
On Mon, Jan 14, 2013 at 3:45 PM, Wujek Srujek
<wujek.sru...@gmail.com <mailto:wujek.sru...@gmail.com>> wrote:
Because this is not the whole functionality ;d The check is
just a fragment, the one that doesn't work. There is much
more to it, like taking the object, taking some keys and
values and using them in (let) and then executing some code
in this context (which is another parameter, which is not in
my example as I wanted to keep it simple).
If I could do it with a function, I would of course prefer
it, but I am not sure if it can work.
wujek
On Mon, Jan 14, 2013 at 3:41 PM, Jim foo.bar
<jimpil1...@gmail.com <mailto:jimpil1...@gmail.com>> wrote:
Why does this have to be a macro? Why can't it be a
first-class function instead?
(defn with-obj [ob]
(if-let [obj-meta (meta ob)] name
(throw (IllegalArgumentException. (str ob " seems not
be our object")))))
Jim
On 14/01/13 14:34, Jim foo.bar wrote:
Of course you should know that built-in java types do
not support meta-data...You need to implement IObj
in order to provide meta-data support to your own
types...otherwise use records...
Jim
On 14/01/13 14:32, Jim foo.bar wrote:
On 14/01/13 14:27, wujek.sru...@gmail.com
<mailto:wujek.sru...@gmail.com> wrote:
(defmacro with-obj [name]
(let [obj-meta (meta name)]
(if (or (nil? obj-meta)) ; (not (::my-obj
obj-meta)))
(throw (IllegalArgumentException. (str
name " seems not be our object")))))
`(println "nice"))
Try this:
(defmacro with-obj [name]
`(if-let [obj-meta# (meta ~name)]
(println "nice")
(throw (IllegalArgumentException. (str ~name "
seems not be our object")))))
HTH...
Jim
--
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 <mailto: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
<mailto:clojure%2bunsubscr...@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 post to this group, send email to clojure@googlegroups.com
<mailto: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
<mailto: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 post to this group, send email to clojure@googlegroups.com
<mailto: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
<mailto:clojure%2bunsubscr...@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 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 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