# Evaluate expression with variables from a dictionary

**URL:** <https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047>\
**Category:** General Usage\
**Created:** [October 18, 2019, 8:49am UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047 "2019-10-18T08:49:20Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [October 18, 2019, 8:49am UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/1 "2019-10-18T08:49:20Z")

</div>

I have a set of variables stored in a `Dict{Symbol, Any}` like this:

```julia
data = Dict(
    :a=>1,
    :b=>2,
    :c=>3 # etc.
)

```

Then I’ve got a set of calculations that are defined as expressions with variable names that match the keys of the data set, e.g.

```julia
f1 = :(a + b)

```

I’m looking for a way of evaluating such expressions using the variables that are stored in `data`. But I prefer not to populate `Main` (or the module where the calculations are done) with those variables.

A macro like this might do the trick:

```julia
macro calculate(ex, dict_ex)
    dict = __module__.eval(dict_ex)
    vex = Expr[]
    for (k, v) in dict
        push!(vex, :($k = $v))
    end
    push!(vex, ex)
    return quote $(vex...) end
end

```

```julia-repl
julia> @calculate a + b data
3

julia> # Or if I want to use the expression stored in f1:

julia> @eval @calculate $f1 data
3

```

However, this macro allocates variables for _all_ the data contained in the dictionary, even if the expression only uses some of those variables:

```julia-repl
julia> @macroexpand @calculate a + b data
quote
    #= untitled-a25e1fb3875a91a253aef47c6b6eba3d:8 =#
    #36#a = 1
    #37#b = 2
    #38#c = 3
    #36#a + #37#b
end

```

Is there a smarter way to do this? E.g. something that lets me know what symbols are actually contained in the expression, which I could use to filter the dictionary entries that are converted into variables inside the macro.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [October 18, 2019, 9:51am UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/2 "2019-10-18T09:51:36Z")

</div>

This is one way to do it.

```julia
interpolate_from_dict(ex::Expr, dict) = Expr(ex.head, interpolate_from_dict.(ex.args, Ref(dict))...)
interpolate_from_dict(ex::Symbol, dict) = get(dict, ex, ex)
interpolate_from_dict(ex::Any, dict) = ex

```

Then you have

```julia
julia> interpolate_from_dict(f1, data)
:(1 + 2)

julia> eval(interpolate_from_dict(f1, data))
3

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [October 18, 2019, 10:05am UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/3 "2019-10-18T10:05:07Z")

</div>

Why do you need expressions? Can you just use normal functions?

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [October 18, 2019, 10:26am UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/4 "2019-10-18T10:26:07Z")

</div>

Expressions are nice for quickly writing down formulas that you find in papers. But functions would be fine as well. For instance, I don’t mind writing:

```julia
julia> f1(a, b) = a + b
f1 (generic function with 1 method)

```

Two drawbacks:

1. The code becomes “hidden”, you can’t type `f1` and see what it does anymore. But that’s not a real problem, as I do have the source anyway.
2. How can I tell `f1` who are `a` and `b` from the dictionary…?

… Oh, wait!

```julia
julia> f1(; a, b, _...) = a + b
f1 (generic function with 2 methods)

julia> f1(; data...)
3

```

Horray! 🥳

Thanks @dpsanders!

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [October 18, 2019, 12:15pm UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/5 "2019-10-18T12:15:08Z")

</div>

If you can use functions, I don’t quite see why the simple

```julia
function f1(data)
  return data[:a] + data[:b]
end

```

does not solve the problem. Am I missing some complication?

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [October 18, 2019, 3:51pm UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/6 "2019-10-18T15:51:00Z")

</div>

Yes, of course I can use functions. What I was looking for is a way to write code copying it straight from e.g. papers or textbooks. One thing I like of Julia is how easy is to write code as math formulas. So it’s nice to have a way to write `a + b` instead of `data[:a] + data[:b]` when you work with data from dictionaries.

(The example of `a+b` is perhaps too simple. The visual difference is greater when the formulas are more complicated, with many variables and combined operations.)

But in the end, it is just a cosmetic issue - in situations when you don’t really care about optimal code.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [October 18, 2019, 4:06pm UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/7 "2019-10-18T16:06:52Z")

</div>

An interesting use case.

Perhaps

```julia
using Parameters

function foo(data :: Dict)
  @unpack a,b = data
  return a+b
end

```

would be easier?

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [October 18, 2019, 4:29pm UTC](https://discourse.julialang.org/t/evaluate-expression-with-variables-from-a-dictionary/30047/8 "2019-10-18T16:29:01Z")

</div>

I didn’t know of Parameters.jl. Thank you!
