Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I eval a local variable in Julia

Tags:

julia

i = 50
function test()
  i = 10
  eval(:i)
end
test()  # => 50

Why does this evaluate to the global i instead of the local one? Is there a way to make it evaluate to the local?

like image 346
Sean Mackesey Avatar asked Jan 21 '14 20:01

Sean Mackesey


People also ask

What is :: In Julia?

A return type can be specified in the function declaration using the :: operator. This converts the return value to the specified type. This function will always return an Int8 regardless of the types of x and y .

Can eval be used as variable name?

In strict mode, declaring a variable named eval or re-assigning eval is a SyntaxError . If the argument of eval() is not a string, eval() returns the argument unchanged. In the following example, the String constructor is specified and eval() returns a String object rather than evaluating the string.

How do you declare a global variable in Julia?

For any assignment to a global, Julia will first try to convert it to the appropriate type using convert : julia> global y::Int julia> y = 1.0 1.0 julia> y 1 julia> y = 3.14 ERROR: InexactError: Int64(3.14) Stacktrace: [...]

Is eval a variable?

= is the assignment operator, and val and _val are variables.


1 Answers

You can't. Julia's eval always evaluates code the current module's scope, not your local scope. Calling eval in local scope is an anti-pattern and a performance killer. You can, however, construct a new function which includes a bit of user code that refers to local scope and then call that function. For example:

# user-supplied expression
expr = :(i^2 + 1)

# splice into function body
test = @eval function ()
    i = 10
    $expr
end

Now you can call test:

julia> test()
101

Why is this better than calling eval inside of test as in the question? Because in the original, eval needs to be called every time you call test whereas in this usage, eval is only called once when defining test; when test is called no eval is done. So while you may call eval "at run time" in the sense of "while your application is running, getting user input" it is not called "at run time" in the sense of when the function constructed with that user input is called. The former is fine, whereas the latter as distinctly an anti-pattern.

like image 123
StefanKarpinski Avatar answered Oct 10 '22 13:10

StefanKarpinski