# Executing code in @eval

**URL:** <https://discourse.julialang.org/t/executing-code-in-eval/62497>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 7, 2021, 7:49am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497 "2021-06-07T07:49:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)\
**Post date:** [June 7, 2021, 7:49am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497/1 "2021-06-07T07:49:31Z")

</div>

Hey all,

I don’t want to write lots of code and use `@eval` now. I want to generate different code depending on a condition inside `@eval`. It looks like this:

```julia
for (sym, len) in (
    (:sym1, nothing),
    (:sym2, 2)
)
    @eval struct $sym
        value::String
        function $sym(v::String)
            $( # This block doesn't work
                if len === nothing
                    nothing
                else
                    length(v) == len || throw(DomainError(v, "")) # Here the compiler says that it doesn't know `v`
                end
            )
            new(v)
        end
    end
    @eval Base.getindex(object::$sym) = object.value
    @eval Base.length(object::$sym) = length(object[])
end

```

Is there a way to execute code inside the expression I create for the `@eval` macro?

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [June 7, 2021, 8:05am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497/2 "2021-06-07T08:05:18Z")

</div>

This seems to work:

```julia
    @eval struct $sym
        value::String
        function $sym(v::String)
            $(
                if len === nothing
                    nothing
                else
                    :(length(v) == $len || throw(DomainError(v, "")))
                end
            )
            new(v)
        end

```

```julia
julia> sym2("aa")
sym2("aa")

julia> sym2("aaaa")
ERROR: DomainError with aaaa:

Stacktrace:
 [1] sym2(v::String)
   @ Main ./REPL[422]:8
 [2] top-level scope
   @ REPL[431]:1

julia> sym1("aaaa")
sym1("aaaa")

```

Are you sure this is the best way to handle your use case though? Obviously you are the best judge of that, and perhaps your real use is more complex, but for something like this I’d probably use a parametric type instead of defining types in a for loop

edit: looks like you can also simplify to

```julia
@eval struct $sym
    value::String
    function $sym(v::String)
        if $len !== nothing
            length(v) == $len || throw(DomainError(v, ""))
        end
        new(v)
     end

```

---

<div class="post-metadata">

**Author:** ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)\
**Post date:** [June 7, 2021, 8:18am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497/3 "2021-06-07T08:18:05Z")

</div>

I want to use types for better readability. So one string for name, one for country and so on.

I like the first solution more. Because as I understand the first one does the check at compile time and the second at runtime. I hope that is correct 😃

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [June 7, 2021, 8:41am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497/4 "2021-06-07T08:41:15Z")

</div>

In both cases, the check is done at compile time. The compiler does constant propagation and code elimination. For example, the following will compile to a no-op:

```julia
julia> function f()
           if 1+1 == 3
             error("Huh?")
           end
        end
f (generic function with 1 method)

julia> @code_llvm f()
; @ REPL[1]:1 within `f'
define void @julia_f_206() {
top:
; @ REPL[1]:3 within `f'
  ret void
}

```

(The test `len === nothing`, does not even depend on constant propagation. The compiler can figure it out from just the type information.)

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [June 7, 2021, 10:13am UTC](https://discourse.julialang.org/t/executing-code-in-eval/62497/5 "2021-06-07T10:13:56Z")

</div>

> [@Impressium](#):
>
> I want to use types for better readability.

To clarify what I meant, it would be something like

```julia
struct Sym{N}
    value::String
    function Sym{N}(v) where N
        N === nothing || @assert length(v) == N
        new{N}(v)
    end
end

# you can even make some aliases
for (sym, len) in ((:sym1, nothing), (:sym2, 2))
    @eval const $sym = Sym{$len}
end

```

Works the same way while also being more general, and requiring no metaprogramming.

```julia
julia> sym1("aaaa")
sym1("aaaa")

julia> sym2("aaaa")
ERROR: AssertionError: length(v) == N
Stacktrace:
 [1] sym2(v::String)
   @ Main ./REPL[16]:4
 [2] top-level scope
   @ REPL[24]:1

julia> sym2("aa")
sym2("aa")

julia> Sym{4}("aaaa") # can alias this one too if you want.
Sym{4}("aaaa")

```
