Hrm, okay you have my attention -- I do care about speed in this case. I am just trying to write a wrapper which tests different functions, such as foo and bar, in the psuedo code below.
What I'm trying to do is as follows: function foo(arg1,arg2) end function bar(arg1) end function wrapper(input) def arg1, arg2 if input == "bar" eval(bar(arg1)) elseif input == "foo" eval(foo(arg1,arg2)) end end On Saturday, May 2, 2015 at 1:26:32 PM UTC-4, Jameson wrote: > > 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] > <javascript:>> 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. >>>>>>> >>>>>> >>>>
