# Metaprogramming - defining a function

**URL:** https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491
**Category:** New to Julia
**Tags:** metaprogramming
**Created:** [September 25, 2018, 10:06pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491 "2018-09-25T22:06:50Z")
**Posts on this page:** 17
**Page:** 2

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 2, 2018, 8:32pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/21 "2018-10-02T20:32:55Z")

</div>

This looks much better. I will give it a try.

---

<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: [October 2, 2018, 8:50pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/22 "2018-10-02T20:50:34Z")

</div>

Very high level comment. Some people come to Julia from other dynamic languages and want to call eval inside of a function in order to do something specified by some end user in a dynamic way. Instead, the right approach in Julia is to splice a bit of end-user-specified code into a function definition, evaluate that function definition and then call that function as needed. The trick is to move the eval call outward. Hopefully that’s conceptually helpful.

---

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 2, 2018, 9:00pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/23 "2018-10-02T21:00:49Z")

</div>

I know the problem is how I am addressing Julia. For me “it feels bad” moving stuff outside. It feels like polluting the global space.

I will see tomorrow how it looks in my case.

Thanks for all your advices. They are all welcomed.

---

<div class="post-metadata">

### Author: ![wherrera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wherrera/32/5288_2.png) [@wherrera](https://discourse.julialang.org/u/wherrera)
#### Post date: [October 3, 2018, 6:35am UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/24 "2018-10-03T06:35:33Z")

</div>

I have a question about a modification of Kristopher’s code and “world age” errors. See code below:

```
function create_function_expr(function_name, sig, variables, body)
    Expr(:function, 
	Expr(:call,
		function_name,
		[Expr(:(::), s, t) for (s, t) in zip(variables, sig)]...),
	body
)
end

function makefunc()
    fname = :foobar
    sg = (Int, Float64, Int32)
    vars = [:a, :q, :d]
    bdy = :(a + q * d)
    return eval(create_function_expr(fname, sg, vars, bdy))
end

function runfunc()
    f = makefunc()
    println("within a function: ", f(1, 2.0, Int32(3)))
end

# runfunc()

f = makefunc()
println("from global scope: ", f(1, 2.0, Int32(3)))

runfunc()

```

In this code, running runfunc() after the call from global scope works, and calling runfunc before the global call does not. Is this due to when the runfunc function is first compiled? Why?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 3, 2018, 12:28pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/25 "2018-10-03T12:28:12Z")

</div>

See [Methods · The Julia Language](https://docs.julialang.org/en/v1/manual/methods/#Redefining-Methods-1) which describes this quite well.

---

<div class="post-metadata">

### Author: ![wherrera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wherrera/32/5288_2.png) [@wherrera](https://discourse.julialang.org/u/wherrera)
#### Post date: [October 4, 2018, 5:38am UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/26 "2018-10-04T05:38:55Z")

</div>

Thanks. Yet another metaprogramming gotcha I see :).

---

<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: [October 4, 2018, 2:18pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/28 "2018-10-04T14:18:40Z")

</div>

> [@NaOH](#):
>
> Put the function that returns the expression in a macro, taking care of escaping:

Don’t do this. If this is for private (package internal) use, just use `eval`, it’s much better and easier. If this is for external use, then this way of using `esc` incorrectly will guarantee you macro hygiene bug.

---

<div class="post-metadata">

### Author: ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)
#### Post date: [October 4, 2018, 5:10pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/29 "2018-10-04T17:10:56Z")

</div>

Sure, I should have commented more on escaping. I just wanted him to know this pattern of putting a function that retuns an expression into a macro, and that then you don’t need eval.

Althouhg `esc` the whole expression in not what you want most of the time, it is used a lot in thin kind of small examples.

---

<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: [October 4, 2018, 5:18pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/30 "2018-10-04T17:18:11Z")

</div>

> [@NaOH](#):
>
> and that then you don’t need eval.

And there’s absolutely nothing wrong with `eval`.

> [@NaOH](#):
>
> I just wanted him to know this pattern of putting a function that retuns an expression into a macro,

And that’s a wrong pattern. If you want/need a macro, don’t even start this way. If it’s just to automatically create functions internally, don’t use macro.

---

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 4, 2018, 8:19pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/31 "2018-10-04T20:19:26Z")

</div>

I am still not managing to do what I want. I am calling an already existing function from within the newly created function. The existing function complains about receiving a `::Symbol` instead of a value.

I am sure it is my wrong doing, but I got the feeling that Julia is getting in the middle, not allowing me to do what want in this particular task.

I really miss an easy way to refer to the symbol content in the context of the function, so I can use the symbol or its content as I need. Maybe this could be an _enhancement_ to Julia. (Regardless that for sure there are plenty of good technical reasons why this is not good or possible).

Regards

---

<div class="post-metadata">

### Author: ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)
#### Post date: [October 4, 2018, 8:41pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/32 "2018-10-04T20:41:56Z")

</div>

> [@yuyichao](#):
>
> And there’s absolutely nothing wrong with `eval` .

What I mean is that sometimes you don’t want to use eval because it is global scope only, you can use a macro when you need something local.

> [@yuyichao](#):
>
> And that’s a wrong pattern. If you want/need a macro, don’t even start this way.

I disagree, this is better to debug and reason about, specially if you are still learning, and also, it is a pattern indeed, seen in many places, and suggested by many (smart) people (that tought me it), I’m not just inventing stuff.

So you never ever do this function insede macro? How do you do it? I used to do only macros, until Total Verb and others told me it’s better to do it this way, now you say, we shouldn’t.

Perhaps if the documentation had more examples we could agree.

> [@yuyichao](#):
>
> If it’s just to automatically create functions internally, don’t use macro.

I agree, that the function in a macro in not needed in this case, but I was trying to show him how you can do it that way.

Hope I didn’t confuse you Jose, pasa un buen dia!

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 4, 2018, 8:46pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/33 "2018-10-04T20:46:41Z")

</div>

> [@josemaria](#):
>
> I am still not managing to do what I want. I am calling an already existing function from within the newly created function. The existing function complains about receiving a `::Symbol` instead of a value.

With trivial modifications to my code aobve

```julia
body = :(a + q * other_function(d))
other_function(x) = (println("Calling this function from inside"); x^5)

```

```julia
julia> eval(create_function_expr(function_name, sig, variables, body))
foobar (generic function with 1 method)

julia> foobar(1, 2.0, Int32(3))
Calling this function from inside
487.0

```

> [@josemaria](#):
>
> I am sure it is my wrong doing, but I got the feeling that Julia is getting in the middle, not allowing me to do what want in this particular task.

Hmm, yes maybe you are just doing it wrong. Without a clear example of what you actually want to do, it is hard to say.

---

<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: [October 4, 2018, 8:54pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/35 "2018-10-04T20:54:23Z")

</div>

> [@NaOH](#):
>
> you don’t want to use eval because it is global scope only, you can use a macro when you need something local.

This is defining a global function.

> [@NaOH](#):
>
> I disagree, this is better to debug and reason about, specially if you are still learning

It’s absolutely wrong to learn the wrong pattern. You can call the macro as function for debugging just fine.

> [@NaOH](#):
>
> it is a pattern indeed, seen in many places, and suggested by many (smart) people (that tought me it),

I know and I’m really sad to see that. It’s absolutely a bad idea to do it. I’ve seen many issue caused by it and  
I recommand against it everytime I see it. I’m not saying that you invented it, but you still shouldn’t do it.

> [@NaOH](#):
>
> So you never ever do this function insede macro? How do you do it? I used to do only macros, until Total Verb and others told me it’s better to do it this way, now you say, we shouldn’t.

I didn’t say you shouldn’t call function in macros, that’s just code organization and when you have something large that’s useful and that’s totally fine. I said your use of `esc` is completely wrong though.

---

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 9, 2018, 9:37pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/36 "2018-10-09T21:37:50Z")

</div>

I have put the code [here](https://github.com/mantielero/VapourSynth.jl). Really ugly because I am not a developer, I am new to julia and there is plenty of different tries already commented.

It requires to have [vapoursynth](http://www.vapoursynth.com/doc/installation.html) installed.

Vapoursynth (like Avisynth) allows editing videos by means of scripting. They allow doing things like [this](https://www.youtube.com/watch?v=ujhNZh62HN8).

Avisynth has an scripting language [AVS](http://avisynth.nl/index.php/Script_examples). Vapoursynth opted to [python](http://www.l33tmeatwad.com/vapoursynth101/script-basics). Both of them uses C for the plugins.

This is where Julia looks like a good fit: using one language for both scripting and plugins.

Somebody had the same idea using Lua -another good fit- (see [luasynth](https://github.com/tgoyne/luasynth)).

Being able to access [all those already existing plugins](http://avisynth.nl/index.php/External_filters) for video edition would be great.

---

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 10, 2018, 9:14pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/37 "2018-10-10T21:14:08Z")

</div>

One thing that I have observed is that when I print the declaration of the function I get something like:

```julia
function SetLogLevel(level::Int64)
    #= /home/jose/src/VapourSynth.jl/src/vsplugins.jl:405 =#
    vsmap = createMap()
    #= /home/jose/src/VapourSynth.jl/src/vsplugins.jl:406 =#
    for (t, s, ex, tipo, mandatory) = Any[("level", :level, :(level::Int64), Int64, true)]
        #= /home/jose/src/VapourSynth.jl/src/vsplugins.jl:407 =#
        println(s)
        #= /home/jose/src/VapourSynth.jl/src/vsplugins.jl:409 =#
        if tipo <: Int
...

```

It can be observed that in the function signature it appears **level** (not **:level** ) which is correct. But on the function body, it appears **:level** instead of **level** , which doesn’t seem correct. I don’t know why this is happening. I have made the following minimal example which behaves properlly:

```julia
function create_function(funcname::String )
    fname = Symbol(funcname)

    #println(var)
    # Creating function signature
    spath = Symbol("var")
    #spath = [Symbol("var")]
    arg = Expr(:kw, spath, String)
    f_call = Expr( :call,
                   fname,
                   arg )
    f_body = quote
        #tmp = $spath
        var = ccall((:getenv, "/lib/libc-2.28.so")
                     , Cstring, (Cstring,)
                     , $spath)
        return unsafe_string(var)
    end
    f_declare = Expr( :function, f_call, f_body )
    println(f_declare)
    eval(f_declare)
end

#params = [("path", String)]
create_function("testing")
println( testing("SHELL") )

```

that when executed it prints:

```shell
$ julia example.jl 
function prueba(var=String)
    #= /home/jose/src/example/example.jl:14 =#
    var = ccall((:getenv, "/lib/libc-2.28.so"), Cstring, (Cstring,), var)
    #= /home/jose/src/example/example.jl:17 =#
    return unsafe_string(var)
end
/bin/bash

```

It can be observed that in the minimal example, never appears **:var**.

Does anybody see what I am doing wrong in function [create\_function](https://github.com/mantielero/VapourSynth.jl/blob/master/src/vsplugins.jl#L300)?  
The function signature looks good, so:

- I would say that it is fine at least until [line 351](https://github.com/mantielero/VapourSynth.jl/blob/master/src/vsplugins.jl#L351).
- Everything is commented until [L405](https://github.com/mantielero/VapourSynth.jl/blob/master/src/vsplugins.jl#L405). This line creates a VapourSynth key/value list.
- [L406](https://github.com/mantielero/VapourSynth.jl/blob/master/src/vsplugins.jl#L406). This is the interesting one:

Why does it produce?

```julia
for (t, s, ex, tipo, mandatory) = Any[("level", :level, :(level::Int64), Int64, true)]

```

instead of:

```julia
for (t, s, ex, tipo, mandatory) = Any[("level", level, :(level::Int64), Int64, true)]

```

The same symbol is created in [L316](https://github.com/mantielero/VapourSynth.jl/blob/master/src/vsplugins.jl#L316) and used for both the function signature and the body.

> See the `:level` vs `level`

---

<div class="post-metadata">

### Author: ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)
#### Post date: [October 12, 2018, 2:51pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/38 "2018-10-12T14:51:56Z")

</div>

SOLVED

Just to say that I finally found the problem. (Just in case somebody is bothering with my code).

The problem seems to be due to having the symbols directly within the quoted section. The symbols get “quoted” themselves, so they evaluate again to symbols. I will try to post something later on when it gets clearer in my mind so this error I made might help others.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [October 12, 2018, 3:20pm UTC](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491/39 "2018-10-12T15:20:06Z")

</div>

> [@josemaria](#):
>
> The symbols get “quoted” themselves, so they evaluate again to symbols. I

Yes, for example

```julia
julia> dump(:( :sym ))
QuoteNode
  value: Symbol sym

julia> eval(QuoteNode(:sym))
:sym

```

[Previous page](https://discourse.julialang.org/t/metaprogramming-defining-a-function/15491.md?page=1)
