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

Reply via email to