Thanks for both answers! I figured out a slightly different way of doing it 
by putting the let assignments into a string with a "nothing" expression, 
parsing the string, and then inserting the actual expression to be 
evaluated into the correct place in the let block:

function run(assignments,program)
  program_string="let"
  for pair in assignments
    program_string="$(program_string) $(pair[1])=$(pair[2]);"
  end
  program_string="$(program_string) nothing; end"
  program_final=parse(program_string)
  program_final.args[1].args[end]=program
  eval(program_final)
end

I can now evaluate the same expression with different inputs in parallel 
without worrying that they might conflict because all the variables are 
local, e.g.:

pmap(dict->run(dict,:(x+y*y)), [{:x=>2,:y=>5},{:x=>6,:y=>10}])

*2-element Array{Any,1}:*

*  27*

* 106*

Thanks for your help!
Mike



On Thursday, December 11, 2014 10:34:22 PM UTC+13, Mike Innes wrote:
>
> You can do this just fine, but you have to be explicit about what 
> variables you want to pass in, e.g.
>
> let x=2
>   exp=:(x+1)
>   eval(:(let x = $x; $exp; end))
> end
>
> If you want to call the expression with multiple inputs, wrap it in a 
> function:
>
> let x=2
>   exp=:(x+1)
>   f = eval(:(x -> $exp))
>   f(x)
> end
>
>
> On 11 December 2014 at 06:32, Jameson Nash <vtj...@gmail.com <javascript:>
> > wrote:
>
>> I'm not quite sure what a genetic program of that sort would look like. I 
>> would be interested to hear if you get something out of it.
>>
>> Another alternative is to use a module as the environment:
>>
>> module MyEnv
>> end
>> eval(MyEnv, :(code block))
>>
>> This is (roughly) how the REPL is implemented to work.
>>
>> On Thu Dec 11 2014 at 1:26:57 AM Michael Mayo <mm...@waikato.ac.nz 
>> <javascript:>> wrote:
>>
>>> Thanks, but its not quite what I'm looking for. I want to be able to 
>>> edit the Expr tree and then evaluate different expressions using variables 
>>> defined in the local scope,not the global scope (e.g. for genetic 
>>> programming, where random changes to an expression are repeatedly evaluated 
>>> to find the best one). Using anonymous functions could work but modifying 
>>> the .code property of an anonymous function looks much more complex than 
>>> modifying the Expr types.
>>>
>>> Anyway thanks for your answer, maybe your suggestion is the only 
>>> possible way to achieve this!
>>>
>>> Mike 
>>>
>>>
>>> On Thursday, December 11, 2014 6:56:15 PM UTC+13, Jameson wrote:
>>>
>>>> eval, by design, doesn't work that way. there are just too many better 
>>>> alternatives. typically, an anonymous function / lambda is the best and 
>>>> most direct replacement:
>>>>
>>>> let x=2
>>>>   println(x)            # Line 1
>>>>   exp = () -> x+1
>>>>   println(exp())    # Line 2
>>>> end
>>>>
>>>>
>>>> On Wed Dec 10 2014 at 10:43:00 PM Michael Mayo <mm...@waikato.ac.nz> 
>>>> wrote:
>>>>
>>>>> Hi folks,
>>>>>
>>>>> I have the following code fragment:
>>>>>
>>>>> x=1
>>>>> let x=2
>>>>>   println(x)            # Line 1
>>>>>   exp=:(x+1)
>>>>>   println(eval(exp))    # Line 2
>>>>> end
>>>>>
>>>>> It contains two variables both named x, one inside the scope defined 
>>>>> by let, and one at global scope.
>>>>>
>>>>> If I run this code the output is:
>>>>> 2
>>>>> 2
>>>>>
>>>>> This indicates that (i) that line 1 is using the local version of x, 
>>>>> and (ii) that line 2 is using the global version of x.
>>>>>
>>>>> If I remove this global x I now get an error because eval() is looking 
>>>>> for the global x which no longer exists:
>>>>>
>>>>> let x=2
>>>>>   println(x)            # Line 1
>>>>>   exp=:(x+1)
>>>>>   println(eval(exp))    # Line 2
>>>>> end
>>>>>
>>>>> 2
>>>>>
>>>>> ERROR: x not defined
>>>>>
>>>>>
>>>>> My question: when evaluating an expression using eval() such as line 
>>>>> 2, how can I force Julia to use the local (not global) version of x and 
>>>>> thus avoid this error?
>>>>>
>>>>>
>>>>> Thanks
>>>>>
>>>>> Mike
>>>>>
>>>>  
>

Reply via email to