Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instance of Value Type in Julia

Tags:

types

julia

Can I have an instance of a value type in Julia?

When I tried to enter isa(3, Val{3}) at the REPL console, it returns a false.

So what does three = Val{3}() give me?

like image 773
rakesh a Avatar asked Jul 12 '16 19:07

rakesh a


1 Answers

As you observed, it is indeed possible to create instances of Val types, but they bear little relation to the "values" from which you construct them. For example,

julia> 3 == Val{3}()
false

Val types (or Val instances) really have only one purpose: to pass information to Julia's compiler, which sees types but (generally) not instances. For example, you can't dispatch on an integer of a particular value:

julia> check_for_three(x::Int) = false
check_for_three (generic function with 1 method)

julia> check_for_three(x::3) = true
ERROR: ArgumentError: invalid type for argument x in method definition for check_for_three at REPL[3]:1
 in eval(::Module, ::Any) at ./boot.jl:234
 in macro expansion at ./REPL.jl:92 [inlined]
 in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46

However, you can dispatch on a Val type:

julia> check_for_three_val{N}(::Val{N}) = false
check_for_three_val (generic function with 1 method)

julia> check_for_three_val(::Val{3}) = true
check_for_three_val (generic function with 2 methods)

julia> check_for_three_val(Val{2}())
false

julia> check_for_three_val(Val{3}())
true

You can write the same code using types rather than instances:

julia> check_for_three_valtype{N}(::Type{Val{N}}) = false
check_for_three_valtype (generic function with 1 method)

julia> check_for_three_valtype(::Type{Val{3}}) = true
check_for_three_valtype (generic function with 2 methods)

julia> check_for_three_valtype(Val{2})
false

julia> check_for_three_valtype(Val{3})
true

The latter is a little harder on your function-author (you have to type that Type{}) but a little easier on the caller (you can skip the ()). The general convention is to adopt the latter so as to be nicer to the caller, but this is just a convention; either could be chosen.

Finally, Val is a fun trick, and sometimes it can be used to solve performance problems, but it's also easy to misunderstand it and indeed make performance worse. See these sections of the manual

  • https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-value-type
  • https://docs.julialang.org/en/v1/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)
like image 117
tholy Avatar answered Oct 05 '22 08:10

tholy