The following example shows an implementation of *eval-in* as a function. 

There are a some *println* added to show the namespace where the code is 
running at each point.

;;--------------------
(ns another-ns)

(defn X [w h]
  {:w w :h h})
;;--------------------
(ns this-ns)

(defn eval-in [code ns]
  (let [orig-ns *ns*]
    (println *ns*) ; we are in this-ns
    (in-ns (symbol ns))
    (println *ns* (resolve *ns* 'X)) ; not anymore, now it's another-ns
    (let [ret (eval (read-string code))]
      (println *ns* (resolve *ns* 'X) ret) ; it's still another-ns but now 
we have the return value
      (in-ns (ns-name orig-ns))
      (println *ns*) ; back to this-ns
      ret)))
      
(def generator "(X 20 20)")
(println (eval-in generator "another-ns"))
(println (eval-in "(X 20 20)" "another-ns"))
;;--------------------

Cheers,

Juan

On Wednesday, December 19, 2012 4:22:58 AM UTC-3, nodename wrote:
>
> As an aside, I'm curious about whether this could have been implemented 
> without a macro.
>
> -A
>  On Dec 18, 2012 11:06 PM, "Alan Shaw" <node...@gmail.com <javascript:>> 
> wrote:
>
>> Thanks very much Juan, that's some good study material for me.
>>
>> -A
>>  On Dec 18, 2012 10:45 PM, "juan.facorro" <juan.f...@gmail.com<javascript:>> 
>> wrote:
>>
>>> The macro sees it arguments as *symbols* and does not resolve to the 
>>> corresponding *var* until evaluation, so the value for the local *code* var 
>>> in the macro is actually the *symbol** generator.*
>>>
>>> The *eval-in* macro uses the *read-string* function to evaluate the 
>>> code you provide, this function expects a string but it's getting the* *
>>> *symbol** generator* instead, since that's what the macro got as a 
>>> first argument.
>>>
>>> Here's a modified version of the *eval-in* macro, that delays the 
>>> evaluation of the call to *read-string*:
>>>
>>> (require '[clojure.pprint :as p])
>>>
>>> (defmacro eval-in
>>>   [code ns]
>>>   `(do
>>>      (in-ns '~(symbol ns))
>>>      (let [ret# (eval *(read-string ~code)*)] ; This line was changed
>>>        (in-ns '~(ns-name *ns*))
>>>        ret#)))
>>>
>>> (p/pprint (macroexpand '(eval-in generator "another-ns")))
>>>
>>> Here's the output:
>>>
>>> (do
>>>  (clojure.core/in-ns 'another-ns)
>>>  (clojure.core/let
>>>   [ret__1879__auto__
>>>    (clojure.core/eval *(clojure.core/read-string generator)*)] ; The 
>>> unquoting of code resulted in the symbol generator
>>>   (clojure.core/in-ns 'test-eval)
>>>   ret__1879__auto__))
>>>
>>> If you want to use a var as an argument for the code, you could resolve 
>>> the var before changing namespaces, delaying the read-string until the 
>>> forms evaluation:
>>>
>>> (ns another-ns)
>>>
>>> (defn X [w h] [w h])
>>> ;---------------------------
>>> (ns this-ns
>>>   (:require [clojure.pprint :as p]))
>>>
>>> (defmacro eval-in
>>>   [code ns]
>>>   `(let [code# ~code]
>>>      (in-ns '~(symbol ns))
>>>       (let [ret# (eval (read-string code#))]
>>>        (in-ns '~(ns-name *ns*))
>>>        ret#)))
>>>
>>> (def generator "(X 300 300)")
>>> (p/pprint (eval-in generator another-ns))
>>>
>>> Hope it helps,
>>>
>>> Juan
>>>
>>>
>>> On Wednesday, December 19, 2012 1:13:00 AM UTC-3, nodename wrote:
>>>>
>>>> From yesterday:
>>>>
>>>> (defmacro eval-in
>>>>   "Eval a Clojure form in a different namespace and switch back to 
>>>> current namespace.
>>>>
>>>>    Args:
>>>>    code - Clojure form as string
>>>>    ns - Target namespace as string"
>>>>   [code ns]
>>>>   `(do
>>>>      (in-ns '~(symbol ns))
>>>>      (let [ret# (eval '~(read-string code))]
>>>>        (in-ns '~(ns-name *ns*))
>>>>        ret#)))
>>>>
>>>>
>>>>
>>>> user=> (def generator "(X 400 400)")
>>>> #'user/generator
>>>> user=> (def image (eval-in generator "clevolution.version.version0-**
>>>> 1-1"))
>>>> CompilerException java.lang.ClassCastException: clojure.lang.Symbol 
>>>> cannot be cast to java.lang.String, compiling:(NO_SOURCE_PATH:1)
>>>>
>>>> user=> (def image (eval-in "(X 400 400)" "clevolution.version.version0-
>>>> **1-1"))
>>>> #'user/image
>>>>
>>>> So it's OK to pass the explicit string but not the symbol. What am I 
>>>> not getting here?
>>>>
>>>> -A
>>>>
>>>>
>>>> On Tue, Dec 18, 2012 at 12:48 AM, Alan Shaw <node...@gmail.com> wrote:
>>>>
>>>>> Now I do, and the macro worked!
>>>>> I believe I have a problem using the macro from a function, but 
>>>>> leaving that for tomorrow.
>>>>>
>>>>> Thanks BG!
>>>>>
>>>>> -A
>>>>>
>>>>>
>>>>>
>>>>> On Tue, Dec 18, 2012 at 12:19 AM, Baishampayan Ghose <b.g...@gmail.com
>>>>> > wrote:
>>>>>
>>>>>> Do you have target ns "clevolution.version.version0-**1-1" required?
>>>>>>
>>>>>> -BG
>>>>>>
>>>>>> On Tue, Dec 18, 2012 at 1:38 PM, Alan Shaw <node...@gmail.com> wrote:
>>>>>> > BG,
>>>>>> > The macro doesn't seem to do the trick. The function X is interned 
>>>>>> in the
>>>>>> > target namespace, but:
>>>>>> >
>>>>>> > user=> (def image (eval-in "(X 400 400)"
>>>>>> > "clevolution.version.version0-**1-1"))
>>>>>> > CompilerException java.lang.RuntimeException: Unable to resolve 
>>>>>> symbol: X in
>>>>>> > this context, compiling:(NO_SOURCE_PATH:1)
>>>>>> >
>>>>>> >
>>>>>> > On Mon, Dec 17, 2012 at 11:53 PM, Alan Shaw <node...@gmail.com> 
>>>>>> wrote:
>>>>>> >>
>>>>>> >> Oh yes, the something.something is fixed so I can just prepend it, 
>>>>>> thanks.
>>>>>> >> (Hadn't noticed your macro takes the ns as a string!)
>>>>>> >>
>>>>>> >> -A
>>>>>> >>
>>>>>> >>
>>>>>> >>
>>>>>> >> On Mon, Dec 17, 2012 at 11:47 PM, Baishampayan Ghose <
>>>>>> b.g...@gmail.com>
>>>>>> >> wrote:
>>>>>> >>>
>>>>>> >>> Alan,
>>>>>> >>>
>>>>>> >>> What you're asking for is to derive the ns "clojure.core" given 
>>>>>> only
>>>>>> >>> "core". Not sure if that's possible.
>>>>>> >>>
>>>>>> >>> The namespace constitutes the whole dotted structure and not just 
>>>>>> the
>>>>>> >>> last component, I am afraid.
>>>>>> >>>
>>>>>> >>> If the actual ns is something.something.version-0-**1-1, then 
>>>>>> you need
>>>>>> >>> the string "something.something.version-**0-1-1" and not just
>>>>>> >>> "version-0-1-1" [unless of course you have some other way of 
>>>>>> deriving
>>>>>> >>> it from info that's embedded in _your_ code or structure thereof].
>>>>>> >>>
>>>>>> >>>
>>>>>> >>> -BG
>>>>>> >>>
>>>>>> >>> On Tue, Dec 18, 2012 at 1:10 PM, Alan Shaw <node...@gmail.com> 
>>>>>> wrote:
>>>>>> >>> > Thanks BG, I'm trying that.
>>>>>> >>> > But I don't think it addresses how to get from the string
>>>>>> >>> > "version-0-1-1" to
>>>>>> >>> > the namespace something.something.version-0-**1-1. How can I 
>>>>>> do that?
>>>>>> >>> >
>>>>>> >>> > -A
>>>>>> >>> >
>>>>>> >>> >
>>>>>> >>> >
>>>>>> >>> > On Mon, Dec 17, 2012 at 11:26 PM, Baishampayan Ghose
>>>>>> >>> > <b.g...@gmail.com>
>>>>>> >>> > wrote:
>>>>>> >>> >>
>>>>>> >>> >> Alan,
>>>>>> >>> >>
>>>>>> >>> >> Something like this might work for you -
>>>>>> >>> >>
>>>>>> >>> >> (defmacro eval-in
>>>>>> >>> >>   "Eval a Clojure form in a different namespace and switch 
>>>>>> back to
>>>>>> >>> >> current namespace.
>>>>>> >>> >>
>>>>>> >>> >>    Args:
>>>>>> >>> >>    code - Clojure form as string
>>>>>> >>> >>    ns - Target namespace as string"
>>>>>> >>> >>   [code ns]
>>>>>> >>> >>   `(do
>>>>>> >>> >>      (in-ns '~(symbol ns))
>>>>>> >>> >>      (let [ret# (eval '~(read-string code))]
>>>>>> >>> >>        (in-ns '~(ns-name *ns*))
>>>>>> >>> >>        ret#)))
>>>>>> >>> >>
>>>>>> >>> >> Warning - I haven't really tested this code.
>>>>>> >>> >>
>>>>>> >>> >> -BG
>>>>>> >>> >>
>>>>>> >>> >> On Tue, Dec 18, 2012 at 12:37 PM, Alan Shaw <node...@gmail.com
>>>>>> >
>>>>>> >>> >> wrote:
>>>>>> >>> >> > Thanks, Las!
>>>>>> >>> >> >
>>>>>> >>> >> > Ok say I have a file in which there is string such as
>>>>>> >>> >> >
>>>>>> >>> >> > "(- (atan (bw-noise 902 2 0.7604615575402431 400 400))
>>>>>> >>> >> > (read-image-from-file
>>>>>> >>> >> > \"images/Dawn_on_Callipygea.**png\"))"
>>>>>> >>> >> >
>>>>>> >>> >> > and another
>>>>>> >>> >> >
>>>>>> >>> >> > "version-0-0-1"
>>>>>> >>> >> >
>>>>>> >>> >> > and I have a namespace version-0-0-1 into which functions 
>>>>>> named atan
>>>>>> >>> >> > etc.
>>>>>> >>> >> > are all :referred.  I want to evaluate the expression in that
>>>>>> >>> >> > particular
>>>>>> >>> >> > context, and not remain there when I'm done.
>>>>>> >>> >> >
>>>>>> >>> >> > -A
>>>>>> >>> >> >
>>>>>> >>> >> >
>>>>>> >>> >> >
>>>>>> >>> >> > On Mon, Dec 17, 2012 at 11:00 PM, László Török <
>>>>>> ltor...@gmail.com>
>>>>>> >>> >> > wrote:
>>>>>> >>> >> >>
>>>>>> >>> >> >> ah, sorry, it's a bit early for me
>>>>>> >>> >> >>
>>>>>> >>> >> >> (in-ns (ns-name user-ns))
>>>>>> >>> >> >>
>>>>>> >>> >> >> if you could post a simple example for the second part of 
>>>>>> your
>>>>>> >>> >> >> question
>>>>>> >>> >> >> I
>>>>>> >>> >> >> maybe able to help.
>>>>>> >>> >> >>
>>>>>> >>> >> >> Las
>>>>>> >>> >> >>
>>>>>> >>> >> >> Alan Shaw 2012. december 18., kedd napon a következőt írta:
>>>>>> >>> >> >>
>>>>>> >>> >> >>> Ah no, that puts me in a new user-ns namespace! Not what I 
>>>>>> wanted!
>>>>>> >>> >> >>>
>>>>>> >>> >> >>>
>>>>>> >>> >> >>> On Mon, Dec 17, 2012 at 10:51 PM, László Török
>>>>>> >>> >> >>> <ltor...@gmail.com>
>>>>>> >>> >> >>> wrote:
>>>>>> >>> >> >>>>
>>>>>> >>> >> >>>> Try (in-ns 'user-ns)
>>>>>> >>> >> >>>>
>>>>>> >>> >> >>>> Las
>>>>>> >>> >> >>>>
>>>>>> >>> >> >>>> On Dec 18, 2012 7:50 AM, "Alan Shaw" <node...@gmail.com> 
>>>>>> wrote:
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> user=> *ns*
>>>>>> >>> >> >>>>> #<Namespace user>
>>>>>> >>> >> >>>>> user=> (def user-ns *ns*)
>>>>>> >>> >> >>>>> #'user/user-ns
>>>>>> >>> >> >>>>> user=> user-ns
>>>>>> >>> >> >>>>> #<Namespace user>
>>>>>> >>> >> >>>>> user=> (in-ns user-ns)
>>>>>> >>> >> >>>>> ClassCastException clojure.lang.Namespace cannot be cast 
>>>>>> to
>>>>>> >>> >> >>>>> clojure.lang.Symbol  clojure.lang.RT$1.invoke 
>>>>>> (RT.java:226)
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> It appears I'm not understanding how namespaces are 
>>>>>> represented.
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> Also, is it just wrong of me to want to remember a 
>>>>>> namespace I
>>>>>> >>> >> >>>>> was
>>>>>> >>> >> >>>>> working in and try to go back to it later?
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> The slightly larger context is: I'm saving an 
>>>>>> s-expression with
>>>>>> >>> >> >>>>> unqualified names in it into a file as a string. Also 
>>>>>> saving a
>>>>>> >>> >> >>>>> string
>>>>>> >>> >> >>>>> indicating the name of the environment in which that 
>>>>>> string
>>>>>> >>> >> >>>>> should
>>>>>> >>> >> >>>>> be (read
>>>>>> >>> >> >>>>> and) eval'ed so that the names will resolve to the 
>>>>>> appropriate
>>>>>> >>> >> >>>>> functions.
>>>>>> >>> >> >>>>> Advice on managing this would be appreciated.
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> -Alan Shaw
>>>>>> >>> >> >>>>>
>>>>>> >>> >> >>>>> --
>>>>>> >>> >> >>>>> You received this message because you are subscribed to 
>>>>>> the
>>>>>> >>> >> >>>>> Google
>>>>>> >>> >> >>>>> Groups "Clojure" group.
>>>>>> >>> >> >>>>> To post to this group, send email to 
>>>>>> clo...@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+u...@**googlegroups.com
>>>>>> >>> >> >>>>> For more options, visit this group at
>>>>>> >>> >> >>>>> http://groups.google.com/**group/clojure?hl=en<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 
>>>>>> clo...@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+u...@**googlegroups.com
>>>>>> >>> >> >>>> For more options, visit this group at
>>>>>> >>> >> >>>> http://groups.google.com/**group/clojure?hl=en<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 
>>>>>> clo...@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+u...@**googlegroups.com
>>>>>> >>> >> >>> For more options, visit this group at
>>>>>> >>> >> >>> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>>>> >>> >> >>
>>>>>> >>> >> >>
>>>>>> >>> >> >>
>>>>>> >>> >> >> --
>>>>>> >>> >> >> László Török
>>>>>> >>> >> >>
>>>>>> >>> >> >> --
>>>>>> >>> >> >> You received this message because you are subscribed to the 
>>>>>> Google
>>>>>> >>> >> >> Groups "Clojure" group.
>>>>>> >>> >> >> To post to this group, send email to 
>>>>>> clo...@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+u...@**googlegroups.com
>>>>>> >>> >> >> For more options, visit this group at
>>>>>> >>> >> >> http://groups.google.com/**group/clojure?hl=en<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 clo...@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+u...@**googlegroups.com
>>>>>> >>> >> > For more options, visit this group at
>>>>>> >>> >> > http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>>>> >>> >>
>>>>>> >>> >>
>>>>>> >>> >>
>>>>>> >>> >> --
>>>>>> >>> >> Baishampayan Ghose
>>>>>> >>> >> b.ghose at gmail.com
>>>>>> >>> >>
>>>>>> >>> >> --
>>>>>> >>> >> You received this message because you are subscribed to the 
>>>>>> Google
>>>>>> >>> >> Groups "Clojure" group.
>>>>>> >>> >> To post to this group, send email to clo...@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+u...@**googlegroups.com
>>>>>> >>> >> For more options, visit this group at
>>>>>> >>> >> http://groups.google.com/**group/clojure?hl=en<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 clo...@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+u...@**googlegroups.com
>>>>>> >>> > For more options, visit this group at
>>>>>> >>> > http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>>>> >>>
>>>>>> >>>
>>>>>> >>>
>>>>>> >>> --
>>>>>> >>> Baishampayan Ghose
>>>>>> >>> b.ghose at gmail.com
>>>>>> >>>
>>>>>> >>> --
>>>>>> >>> You received this message because you are subscribed to the Google
>>>>>> >>> Groups "Clojure" group.
>>>>>> >>> To post to this group, send email to clo...@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+u...@**googlegroups.com
>>>>>> >>> For more options, visit this group at
>>>>>> >>> http://groups.google.com/**group/clojure?hl=en<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 clo...@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+u...@**googlegroups.com
>>>>>> > For more options, visit this group at
>>>>>> > http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Baishampayan Ghose
>>>>>> b.ghose at gmail.com
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "Clojure" group.
>>>>>> To post to this group, send email to clo...@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+u...@**googlegroups.com
>>>>>> For more options, visit this group at
>>>>>> http://groups.google.com/**group/clojure?hl=en<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 clo...@googlegroups.com<javascript:>
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com <javascript:>
>>> 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