# Compile-time vs run-time

I saw people use ‘Val’ in their codes.

``````help?> ntuple
search: ntuple NTuple NamedTuple @NamedTuple UnitUpperTriangular

ntuple(f::Function, n::Integer)

Create a tuple of length n, computing each element as f(i), where i is the index of the element.

Examples
≡≡≡≡≡≡≡≡≡≡

julia> ntuple(i -> 2*i, 4)
(2, 4, 6, 8)

────────────────────────────────────────────────────
ntuple(f, ::Val{N})

Create a tuple of length N, computing each element as f(i), where i is the index of the element. By taking a Val(N) argument, it is possible that this version of
ntuple may generate more efficient code than the version taking the length as an integer. But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N
cannot be determined at compile time.

Examples
≡≡≡≡≡≡≡≡≡≡

julia> ntuple(i -> 2*i, Val(4))
(2, 4, 6, 8)
``````

I am not sure about the meaning of ’ But ntuple(f, N) is preferable to ntuple(f, Val(N)) in cases where N cannot be determined at compile time.’

what does it mean that a variable can be determined at compile time, or that it cannot be determined at compile time but only at run time?

At compile time, type information is known but not any information about values.

``````julia> f(A::Array{T,N}) where {T,N}= ntuple(i->zero(T), Val(N))
f (generic function with 2 methods)

julia> f(rand(2,3))
(0.0, 0.0)
``````

In `f` we know `T` and `N` at compile time since the information comes the `Array` type.

``````julia> g(x::T) where T = ntuple(i->zero(eltype(T)), length(x))
g (generic function with 2 methods)

julia> g([1,2,4])
(0, 0, 0)
``````

In `g` we do not know the length of `x` at compile time.

The reason this is important is dispatch. If we use `Val` we will dispatch to a specialized version of `ntuple` particular that value passed in. If it is runtime based, then we will end up compiling a new method of `ntuple` for every value.

Notice what `Val` does.

``````julia> Val(5)
Val{5}()
``````

The `5` is in curly brackets, `{5}`, meaning it is a type parameter. `Val` moves information from the value domain to the type domain sowe can use it at compile time.

3 Likes