# How one can evaluate @printf to be returned to a value

**URL:** <https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [July 31, 2024, 10:03am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669 "2024-07-31T10:03:49Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![khaledharizb](https://avatars.discourse-cdn.com/v4/letter/k/57b2e6/32.png) [@khaledharizb](https://discourse.julialang.org/u/khaledharizb)\
**Post date:** [July 31, 2024, 10:03am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/1 "2024-07-31T10:03:49Z")

</div>

Hi all, for a technical reason I would like to define functions as below. My problem is how to evaluate `func(xx)` to get a value

```julia
function DeltaAI(z)
return 1/(1+z)
end

function DeltaAII(z)
return √(1-z^2)
end

if (F==0)
    myfunc = "IA"
elseif (F==1)
    myfunc = "IIA"
end
F=0;

func(x) = @printf("Delta%s(%f)",myfunc,x)
func(1) # it sould be = 0.5 whlie I've got DeltaIA(1.000000)

```

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [July 31, 2024, 10:11am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/2 "2024-07-31T10:11:27Z")

</div>

You could do something like

```julia
function DeltaAI(z)
    return 1/(1+z)
end

function DeltaAII(z)
    return √(1-z^2)
end

F=0;
if (F==0)
    myfunc = "AI"
elseif (F==1)
    myfunc = "AII"
end

func(x) = getfield(@ __MODULE__ , Symbol("Delta", myfunc))(x)
func(1)

```

but I would very much recommend structuring your code differently and explicitly writing out the logic in `func`. E.g.

```julia
function func(x, F)
    if F == 0
        DeltaAI(x)
    elseif F == 1
        DeltaAII(x)
    else
        throw(ArgumentError("F must be 0 or 1"))
    end
end

```

---

<div class="post-metadata">

**Author:** ![khaledharizb](https://avatars.discourse-cdn.com/v4/letter/k/57b2e6/32.png) [@khaledharizb](https://discourse.julialang.org/u/khaledharizb)\
**Post date:** [July 31, 2024, 10:19am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/3 "2024-07-31T10:19:46Z")

</div>

> [@pfitzseb](#):
>
> ```julia
> func(x) = getfield(@ __MODULE__ , Symbol("Delta", myfunc))(x)
> 
> ```

Thanks for very nice reply. I agree with you, but I would prefer the first like `func(x) = getfield(@ __MODULE__ , Symbol("Delta", myfunc))(x) ` however I got the following error `UndefVarError: DeltaIA not defined`

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [July 31, 2024, 10:21am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/4 "2024-07-31T10:21:39Z")

</div>

Your original code has a typo in your definition of `myfunc`. You have `"IA"` instead of `"AI"` and similarly for `IIA` instead of `AII` (@pfitzseb fixed this in the solution given)

---

<div class="post-metadata">

**Author:** ![khaledharizb](https://avatars.discourse-cdn.com/v4/letter/k/57b2e6/32.png) [@khaledharizb](https://discourse.julialang.org/u/khaledharizb)\
**Post date:** [July 31, 2024, 10:25am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/5 "2024-07-31T10:25:10Z")

</div>

I got it, thanks a lot @DanielVandH and @pfitzseb

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 31, 2024, 11:41am UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/6 "2024-07-31T11:41:00Z")

</div>

> [@khaledharizb](#):
>
> ```julia
> if (F==0)
> myfunc = "IA"
> elseif (F==1)
> myfunc = "IIA"
> end
> 
> ```

Instead of passing around functions as strings (or encoded as numbers like `F`), it is much better to simply pass them around as functions. e.g. if you set

```julia
myfunc = DeltaAII

```

you can just call `myfunc(1)`. A function called `DeltaAII` can also be passed as an argument to another function. This is called a [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function).

PS. The literal answer to your original question is

```julia
func(x) = eval(Meta.parse(@sprintf("Delta%s(%f)",myfunc,x)))

```

but this is a classic anti-pattern. See [How to warn new users away from metaprogramming](https://discourse.julialang.org/t/how-to-warn-new-users-away-from-metaprogramming/35022) … in particular, you almost never want to pass functions or expressions as strings that you parse and evaluate. It’s fragile, slow, and inflexible. Julia has [first-class functions](https://en.wikipedia.org/wiki/First-class_function) — enjoy it!

---

<div class="post-metadata">

**Author:** ![khaledharizb](https://avatars.discourse-cdn.com/v4/letter/k/57b2e6/32.png) [@khaledharizb](https://discourse.julialang.org/u/khaledharizb)\
**Post date:** [July 31, 2024, 4:12pm UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/7 "2024-07-31T16:12:08Z")

</div>

Thanks @stevengj for your comment, but the idea of @pfitzseb is faster than `Meta.parse`. However, I don’t know about `first-class function` or `higher order` one. Could you show me in a simple example how can we use that?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 31, 2024, 6:16pm UTC](https://discourse.julialang.org/t/how-one-can-evaluate-printf-to-be-returned-to-a-value/117669/8 "2024-07-31T18:16:15Z")

</div>

> [@khaledharizb](#):
>
> Thanks @stevengj for your comment, but the idea of @pfitzseb is faster than `Meta.parse`.

My point is that you should use **neither** `eval(Meta.parse(...))` (which is slow) nor `getfield(@ __MODULE__ , Symbol(...))` which is faster but still slow.

The `eval(Meta.parse(@sprintf(...)))` answer was the _literal_ answer to your question (how can you evaluate the output of `@printf` as code), but you are probably asking the wrong question. This is a classic [XY problem](https://xyproblem.info/).

> [@khaledharizb](#):
>
> However, I don’t know about “first-class function” or “higher order” one. Could you show me in a simple example how can we use that?

Since I don’t know what your ultimate goal is, I can only give a made-up example. Suppose you want to write a function `integrate(f, a, b; N=100)` that computes \int\_a^b f(x) dx for a user-specified function `f` from `a` to `b` using an `N`-point [trapezoidal rule](https://en.wikipedia.org/wiki/Trapezoidal_rule). You could implement this with:

```julia
function integrate(f, a, b; N=100)
    dx = (b - a) / (N-1)
    I = (f(a) + f(b)) * dx / 2 # endpoints
    for i = 1:N-2 # interior points
        I += f(i * dx) * dx
    end
    return I
end

```

This is a “higher-order function” because it takes in a _function_ `f` as an argument. For example, we could use this to approximately integrate your function `DeltaAI` from 0 to 1:

```julia
julia> integrate(DeltaAI, 0, 1)
0.6931535573789361

```

which matches the exact answer \ln 2 \approx 0.6931471805599453 to four digits, and we can get more digits correct by increasing `N`:

```julia
julia> integrate(DeltaAI, 0, 1, N=10^6)
0.6931471805600137

```

Notice how we can simply pass `DeltaAI` as an argument. No string evaluation etcetera is required, and Julia compiles this to very efficient code. We can even define new functions on the fly to integrate, e.g.

```julia
julia> integrate(x -> x^2, 0, 1) # ∫x² ≈ 1/3
0.3333503384008435

```

In this way, functions are “first-class” objects in Julia — you can pass them as arguments, return them from other functions, manipulate them to make new functions, etcetera, on the fly.

You wouldn’t store numbers as strings in Julia. Don’t store functions as strings either.
