That will work, but it is often an indication that you are working down the wrong path here, and will keep finding little issues with `eval` that you have to alter your code handle (like that globals are slow and have to deal with choosing the right module scope).
For example, in your case here, simply passing `wrapper(foo)` (instead of putting foo in quotes)` would remove the need to call parse-eval. On Sat, May 2, 2015 at 12:12 PM Edward Chen <[email protected]> wrote: > nvm, I just needed to define the variables to have a global scope > > > On Saturday, May 2, 2015 at 12:09:14 PM UTC-4, Edward Chen wrote: >> >> To follow up on this question, if I am using this eval(parse(foo)) >> formalism within a wrapper function, it seems that if I define the input >> arguments for foo (a first-class function object) within this wrapper >> function that the arguments can't be found. >> >> example: >> >> function foo(arg) >> >> return arg+3 >> >> end >> >> function wrapper(bar) >> >> arg = 3 >> >> output = eval(parse("foo")) >> >> end >> >> then I get an error saying that the "arg" is not defined when I run: >> >> julia>> wrapper("foo") >> >> Much appreciated, >> Ed >> >> On Wednesday, May 8, 2013 at 12:44:58 PM UTC-4, Stefan Karpinski wrote: >>> >>> Excellent. Have fun! First-class metaprogramming is addictive. >>> >>> >>> On Wed, May 8, 2013 at 12:22 PM, Theodore Papamarkou < >>> [email protected]> wrote: >>> >>>> P.S. I also noted your comment on avoiding building up strings and then >>>> parsing them, I will alter my approach so as to work with expressions >>>> directly. Cheers! >>>> >>>> >>>> On Wednesday, May 8, 2013 5:19:25 PM UTC+1, Theodore Papamarkou wrote: >>>>> >>>>> Thank you very much Stefan, this is really helpful. I understood your >>>>> reply and educative comments, which by the way helped me get on with what >>>>> I >>>>> was doing. I wanted to access nested elements of an the args field of an >>>>> expression as part of the tree traversal I have been working on, and your >>>>> eval(parse()) suggestion resolved my problems: >>>>> >>>>> julia> tmp01 = :(x+3y) >>>>> :(+(x,*(3,y))) >>>>> >>>>> julia> eval(parse("tmp01.args[3].args[3]")) >>>>> :y >>>>> >>>>> I wasn't aware of the powerful parse() function. Thanks a lot! >>>>> >>>>> On Wednesday, May 8, 2013 5:05:02 PM UTC+1, Stefan Karpinski wrote: >>>>>> >>>>>> On Wed, May 8, 2013 at 11:15 AM, Theodore Papamarkou < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> I'm trying to do sth that I'm not sure it's doable in Julia (and if >>>>>>> it is, I am not sure it is good Julia programming practice). Is it >>>>>>> possible >>>>>>> to parse and evaluate some code from an arbitrary string? For example, >>>>>>> if I >>>>>>> have the string "atype"*".args[2]"^2, is it possible somehow to evaluate >>>>>>> the corresponding code atype.args[2].args[2] in order to access the >>>>>>> nested >>>>>>> field of the atype array? Sth along the lines @eval >>>>>>> symbol("atype"*".args[2]"^2) or @eval $symbol("atype"*".args[2]"^2) is >>>>>>> apparently wrong coding. >>>>>> >>>>>> >>>>>> Yes, but unlike the "scripting languages" where the only way to >>>>>> generate and eval code is to build a string and then parse+evaluate it, >>>>>> Julia has a first-class representation of expressions, which are the >>>>>> preferred means of doing metaprogramming. You can, however, explicitly >>>>>> call >>>>>> the parse function to accomplish what you're talking about: >>>>>> >>>>>> julia> ex = parse("z = 2x + y^2 + 1") >>>>>> :(z = +(*(2,x),^(y,2),1)) >>>>>> >>>>>> >>>>>> Of course, that just gives you a expression object and doesn't >>>>>> evaluate it. You need to call eval for that: >>>>>> >>>>>> julia> x,y = 2,3; >>>>>> >>>>>> julia> eval(ex) >>>>>> 14 >>>>>> >>>>>> >>>>>> So the equivalent of eval(str) in Python (or Perl or Ruby) is >>>>>> eval(parse(str)) in Julia. >>>>>> >>>>>> <aside> >>>>>> When you write something like symbol("atype"*".args[2]"^2) you are >>>>>> creating a symbol with the very odd name "atype.args[2].args[2]", which >>>>>> is >>>>>> unlikely to be bound to anything when you evaluate it, although you could >>>>>> arrange for that to happen like this: >>>>>> >>>>>> julia> eval(:($(symbol("atype"*".args[2]"^2)) = 1)) >>>>>> 1 >>>>>> >>>>>> julia> eval(symbol("atype"*".args[2]"^2)) >>>>>> 1 >>>>>> >>>>>> >>>>>> </aside> >>>>>> >>>>>> In general, you're much better off manipulating Expr objects and >>>>>> Symbols than trying to build up strings for code and then parsing and >>>>>> evaluating them. It's much efficient, much more reliable, and you can do >>>>>> quite powerful, general transformations on expressions. >>>>>> >>>>>> >>>>>>> As side-questions (sorry to trouble you folks with several >>>>>>> questions, just getting to understand how to do metaprogramming in >>>>>>> Julia): >>>>>>> >>>>>> >>>>>> No problem. >>>>>> >>>>>> >>>>>>> * is there a Julia function that takes an object as argument and >>>>>>> returns a string with the name of the object? As a continuation of the >>>>>>> above example, I am looking for a "name" function along the lines >>>>>>> name(atype) so as to get back the string "atype". >>>>>>> >>>>>> >>>>>> Objects don't have names, they're just values. Symbols have names and >>>>>> are bound to values, but many different names can be bound to the same >>>>>> value. You can sensibly say string(:atype) and you will get "atype" back, >>>>>> but you're asking for the string representation of the symbol :atype, not >>>>>> for the name of the value that atype refers to (it has no name). >>>>>> >>>>>> <aside> >>>>>> Then only exception to this is named functions, which do actually >>>>>> have a name: >>>>>> >>>>>> julia> f() = 1 >>>>>> # methods for generic function f >>>>>> f() at none:1 >>>>>> >>>>>> julia> g = f >>>>>> # methods for generic function f >>>>>> f() at none:1 >>>>>> >>>>>> >>>>>> The function object still knows its original name was "f". >>>>>> </aside> >>>>>> >>>>>> >>>>>>> * I was looking at the function _jl_pre_exec in base/process.jl as a >>>>>>> means of understanding how Julia pointers work and noticed that C_NULL >>>>>>> is >>>>>>> the last element of ptrs... what does C_NULL do - why is it needed? >>>>>>> >>>>>> >>>>>> The execvp function >>>>>> <http://man7.org/linux/man-pages/man3/execvp.3.html> expects its >>>>>> second argument to be a NULL-terminated array of pointers to strings >>>>>> (which >>>>>> are themselves NULL-terminated arrays of bytes). The C_NULL has to be >>>>>> there >>>>>> so that execvp knows when it's done with the arguments to the program its >>>>>> going to exec. >>>>>> >>>>> >>>
