# How do I create a function from an expression

**URL:** <https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 13, 2018, 4:38am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349 "2018-07-13T04:38:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 4:38am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/1 "2018-07-13T04:38:40Z")

</div>

Suppose I have

```julia
expr = :(sin(x)+cos(x))

```

How can I get a function looking like

```julia
x->sin(x)+cos(x)

```

I have tried to write such a macro

```julia
macro expr2fn(expr, arg)
    return :($arg -> $(expr))
end

```

but it does not work

```julia
julia> f = @expr2fn expr x
(::#63) (generic function with 1 method)

julia> f(1.0)
:(sin(x) + cos(x))

```

Not sure what is happening here.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 7:46am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/2 "2018-07-13T07:46:11Z")

</div>

You _can_ call your macro as `f = @expr2fn sin(x) + cos(x) x`.

Taking the view of macros as functions that map expressions to expressions ([https://docs.julialang.org/en/latest/manual/metaprogramming/#Hold-up:-why-macros?-1](https://docs.julialang.org/en/latest/manual/metaprogramming/#Hold-up:-why-macros?-1)), with `@expr2fn expr x` you’re basically passing the arguments `:(expr)` and `:(x)` to a function with a signature `expr2fn(::Expr, ::Expr)::Expr`; that’s not what you want.

Instead you could do `f = eval(:(x -> $expr))`.

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 7:51am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/3 "2018-07-13T07:51:42Z")

</div>

Sadly that’s not I want.

1. `expr=:(sin(x)+cos(x))` is not constructed by hand. It’s returned symbolic calculation.
2. I don’t want `eval` since `eval` always acts on global scope, which limits the possibility of using it inside a function.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 8:02am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/4 "2018-07-13T08:02:09Z")

</div>

Could you post a concrete example where the `eval` construction doesn’t do what you want?

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 8:07am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/5 "2018-07-13T08:07:04Z")

</div>

Copied from [Generate functions inside a function from string](https://discourse.julialang.org/t/generate-functions-inside-a-function-from-string/12331)

```julia
function foo()
    return eval(parse("x->x"))
end
foo()(1)  
# ERROR: MethodError: no method matching (::##9#10)(::Int64)
# The applicable method may be too new: 
# running in world age 21870, while current world is 21871.

```

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 8:08am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/6 "2018-07-13T08:08:29Z")

</div>

But I think I found a fix

```julia
macro expr2fn(fname, expr, args...)
    fn = quote
        function $(esc(fname))()
            $(esc(expr.args[1]))
        end
    end
    for arg in args
        push!(fn.args[2].args[1].args, esc(arg))
    end
    return fn
end

@expr2fn(f, :(sin(x+y)), x, y)

julia> f(1.0, 1.0)
0.9092974268256817

```

I guess it’s just the documentation is never clear about what I can get if I pass a quoted expression into a macro.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 8:30am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/7 "2018-07-13T08:30:05Z")

</div>

FWIW, `eval` works fine on 0.7:

```julia
   _ _ _(_)_ | A fresh approach to technical computing
  (_) | (_) (_) | Documentation: https://docs.julialang.org
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 0.7.0-beta.201 (2018-07-07 22:13 UTC)
 _/ |\ __'_|_|_|\__'_| | Commit cdd4e84ac9 (5 days old master)
|__/ | x86_64-apple-darwin14.5.0

julia> function foo()
           return eval(Meta.parse("x->x"))
       end
foo (generic function with 1 method)

julia> foo()(1)
1

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 8:43am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/8 "2018-07-13T08:43:02Z")

</div>

Also, assigning the function to a variable circumvents the world age issue on 0.6:

```julia
julia> function foo()
           return eval(parse("x->x"))
       end
foo (generic function with 1 method)

julia> f = foo()
(::#3) (generic function with 1 method)

julia> f(1)
1

```

---

<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:** [July 13, 2018, 8:46am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/9 "2018-07-13T08:46:33Z")

</div>

> [@tkoolen](#):
>
> Also, assigning the function to a variable circumvents the world age issue on 0.6:

That helps you at the REPL but not so much in a function.

```julia
julia> function g()
           f = foo()
           println(f(1))
       end
g (generic function with 1 method)

julia> g()
ERROR: MethodError: no method matching (::##1#2)(::Int64)
The applicable method may be too new: running in world age 21838, while current world is 21839.
Closest candidates are:
  #1(::Any) at none:1 (method too new to be called from this world context.)
Stacktrace:
 [1] g() at ./REPL[13]:3

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 8:49am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/10 "2018-07-13T08:49:55Z")

</div>

Yep, you’re right. And that one doesn’t work on 0.7 either.

---

<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:** [July 13, 2018, 9:01am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/11 "2018-07-13T09:01:01Z")

</div>

> [@Chong\_Wang](#):
>
> But I think I found a fix
> 
> ```julia
> macro expr2fn(fname, expr, args...)
> fn = quote
> function $(esc(fname))()
> $(esc(expr.args[1]))
> end
> end
> for arg in args
> push!(fn.args[2].args[1].args, esc(arg))
> end
> return fn
> end
> 
> @expr2fn(f, :(sin(x+y)), x, y)
> 
> julia> f(1.0, 1.0)
> 0.9092974268256817
> 
> ```
> 
> I guess it’s just the documentation is never clear about what I can get if I pass a quoted expression into a macro.

This only works because you’re sending in the literal `:(sin(x+y))` to your macro.

```julia
julia> expr = :(sin(x+y))
:(sin(x + y))

julia> @expr2fn(f, expr, x, y)
ERROR: type Symbol has no field args

```

Fundamentally macros work on syntax, not on values, and since you want to be able to generate functions from values, macros are not the appropriate tool. As far as I know only `eval` in some form can get you there.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [July 13, 2018, 9:10am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/12 "2018-07-13T09:10:06Z")

</div>

Yeah, I think `invokelatest` is the only way out then if you really want this to work in local scope. I’ve personally never needed anything like this by the way; maybe you could talk a little about your intended application?

---

<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:** [July 13, 2018, 9:18am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/13 "2018-07-13T09:18:47Z")

</div>

This may be illustrative of the problem and two possible ways to circumvent the world age issue.

```julia
julia> expr = :(sin(x + y))
:(sin(x + y))

julia> function f1(expr, x, y)
           f = eval(:((x, y) -> $expr))
           return f(x, y)
       end
f1 (generic function with 1 method)

julia> function f2(expr, x, y)
           f = eval(:((x, y) -> $expr))
           return @eval $f($x, $y)
       end
f2 (generic function with 1 method)

julia> function f3(expr, x, y)
           f = eval(:((x, y) -> $expr))
           return Base.invokelatest(f, x, y)
       end
f3 (generic function with 1 method)

julia> f1(expr, 1, 2)
ERROR: MethodError: no method matching (::##1#2)(::Int64, ::Int64)
The applicable method may be too new: running in world age 21836, while current world is 21837.
Closest candidates are:
  #1(::Any, ::Any) at REPL[2]:2 (method too new to be called from this world context.)
Stacktrace:
 [1] f1(::Expr, ::Int64, ::Int64) at ./REPL[2]:3

julia> f2(expr, 1, 2)
0.1411200080598672

julia> f3(expr, 1, 2)
0.1411200080598672

```

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 9:27am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/14 "2018-07-13T09:27:36Z")

</div>

Thank you for all the comments. What do you think of my following implementation?

```julia
module Expr2Fn

export @expr2fn, setexpr

expr = :(sin(x+y))

macro expr2fn(fname, args...)
    fn = quote
        function $(esc(fname))()
            $expr
        end
    end
    for arg in args
        push!(fn.args[2].args[1].args, esc(arg))
    end
    return fn
end

function setexpr(extexpr)
    global expr = extexpr
end

end

using Expr2Fn

setexpr(:(cos(x+y)))

@expr2fn(f, x, y)

julia> f(1.0, 1.0)
-0.4161468365471424

```

A little bit abuse of Hygiene but seems to work.

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [July 13, 2018, 9:34am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/15 "2018-07-13T09:34:26Z")

</div>

Please see the post for intention (I am her colleague):

> [@Generate functions inside a function from string](https://discourse.julialang.org/t/generate-functions-inside-a-function-from-string/12331/10):
>
> Well, I am working with SymPy. I would like to build a symbolic matrix and then numerically calculate it. However I found SymPy cannot do the calculation fast enough, e.g. using SymPy @vars x expr=integrate(sin(x)) f=eval(parse("x-\>$(repr(expr))")) g=lambdify(expr,[x]) @time subs(expr,x=\>1.0) @time f(1.0) @time g(1.0) # timing: # 0.000365 seconds (80 allocations: 2.453 KiB) # 0.000003 seconds (5 allocations: 176 bytes) # 0.000016 seconds (9 allocations: 240 bytes) I found eval is the fast…

I am starting a new thread because I think `eval` is not the way out since it’s too restrictive to support local scope.

---

<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:** [July 13, 2018, 9:47am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/16 "2018-07-13T09:47:47Z")

</div>

> [@Chong\_Wang](#):
>
> Thank you for all the comments. What do you think of my following implementation?

I think you will find, when you try to run it in a local scope, that it’s less local than you hope and/or runs into world age issues.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [July 13, 2018, 9:47am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/17 "2018-07-13T09:47:54Z")

</div>

You can make that macro statement a lot simpler like this

```nohighlight
macro expr2fn(expr, fname, args...)
    return Expr(:function, Expr(:call, esc(fname), args...), expr)
end

```

although unfortunately the function that is defined by a macro like this is not accessible in the calling scope.

---

<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:** [July 13, 2018, 10:45am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/18 "2018-07-13T10:45:39Z")

</div>

Not sure if this is the “right” way to do it, but it works:

instead of  
`julia> f = @expr2fn expr x`

try:

```julia
julia> expr2 = :(f = @expr2fn $expr x)
:(f = @expr2fn(sin(x) + cos(x), x))

julia> eval(expr2)
(::#21) (generic function with 1 method)

julia> f(1.0)
1.3817732906760363

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [July 13, 2018, 11:35am UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/19 "2018-07-13T11:35:16Z")

</div>

Can I back this up a level and ask what you are trying to accomplish? I feel like this may be a [XY problem](https://meta.stackexchange.com/a/66378) situation.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [July 13, 2018, 1:02pm UTC](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349/20 "2018-07-13T13:02:04Z")

</div>

> [@Chong\_Wang](#):
>
> I don’t want `eval` since `eval` always acts on global scope, which limits the possibility of using it inside a function.

That’s impossible.

> [@tkoolen](#):
>
> Also, assigning the function to a variable circumvents the world age issue on 0.6:

No, it’s the global scope that does.

> [@Chong\_Wang](#):
>
> It’s returned symbolic calculation.

If the input is not static (if it’s static you should/could use a macro to do the symbolic calculation) then if you want to create the function you must use `eval`. After you’ve done with all the function/expression construction, you can use `eval` or `invokelatest` to call the code that uses those functions.

[Next page](https://discourse.julialang.org/t/how-do-i-create-a-function-from-an-expression/12349.md?page=2)
