diff --git a/NEWS.md b/NEWS.md index 9603660785caf..81f33a5089c5a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -143,6 +143,7 @@ Library improvements * The `randexp` and `randexp!` functions are exported ([#9144]) + * A new `Val{T}` type allows one to dispatch on bits-type values ([#9452]) Deprecated or removed --------------------- @@ -159,12 +160,12 @@ Deprecated or removed `trunc{T<:Integer}(T,x)`, `floor{T<:Integer}(T,x)`, etc.. `trunc` is now always bound-checked;`Base.unsafe_trunc` provides the old unchecked `itrunc` behaviour ([#9133]). - + * `squeeze` now requires that passed dimension(s) are an `Int` or tuple of `Int`s; calling `squeeze` with an arbitrary iterator is deprecated ([#9271]). Additionally, passed dimensions must be unique and correspond to extant dimensions of the input array. - + Julia v0.3.0 Release Notes ========================== @@ -1140,3 +1141,4 @@ Too numerous to mention. [#9261]: https://github.com/JuliaLang/julia/issues/9261 [#9271]: https://github.com/JuliaLang/julia/issues/9271 [#9294]: https://github.com/JuliaLang/julia/issues/9294 +[#9542]: https://github.com/JuliaLang/julia/issues/9542 diff --git a/doc/manual/types.rst b/doc/manual/types.rst index 92d459ab8b57a..6fd22fd129319 100644 --- a/doc/manual/types.rst +++ b/doc/manual/types.rst @@ -692,7 +692,7 @@ surrounded by curly braces:: This declaration defines a new parametric type, ``Point{T}``, holding two "coordinates" of type ``T``. What, one may ask, is ``T``? Well, that's precisely the point of parametric types: it can be any type at -all (or an integer, actually, although here it's clearly used as a +all (or any bits type, actually, although here it's clearly used as a type). ``Point{Float64}`` is a concrete type equivalent to the type defined by replacing ``T`` in the definition of ``Point`` with :class:`Float64`. Thus, this single declaration actually declares an @@ -1243,6 +1243,35 @@ If you apply :func:`super` to other type objects (or non-type objects), a julia> super((Float64,Int64)) ERROR: `super` has no method matching super(::Type{(Float64,Int64)}) +"Value types" +------------- + +As one application of these ideas, Julia includes a parametric type, +``Val{T}``, designated for dispatching on bits-type *values*. For +example, if you pass a boolean to a function, you have to test the +value at run-time: + +.. doctest:: + + function firstlast(b::Bool) + return b ? "First" : "Last" + end + + println(firstlast(true)) + +You can instead cause the conditional to be evaluated during function +compilation by using the ``Val`` trick: + +.. doctest:: + + firstlast(::Val{true}) = "First" + firstlast(::Val{false}) = "Last" + + println(firstlast(Val{true}())) + +Any legal type parameter (Types, Symbols, Integers, floating-point numbers, +tuples, etc.) can be passed via ``Val``. + Nullable Types: Representing Missing Values ------------------------------------------- diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index 204051d89c619..0b419b3ea9c13 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -438,6 +438,10 @@ Types Compute a type that contains the intersection of ``T`` and ``S``. Usually this will be the smallest such type or one close to it. +.. function:: Val{c}() + + Create a "value type" instance out of ``c``, which must be an ``isbits`` value. The intent of this construct is to be able to dispatch on constants, e.g., ``f(Val{false}())`` allows you to dispatch directly to an implementation ``f(::Val{false})``, without having to test the boolean value at runtime. + Generic Functions ----------------- diff --git a/test/core.jl b/test/core.jl index 2567606434c8b..f8d62e2c18cee 100644 --- a/test/core.jl +++ b/test/core.jl @@ -502,6 +502,16 @@ begin @test is(g(a),a) end +# dispatch using Val{T} +begin + local firstlast + firstlast(::Val{true}) = "First" + firstlast(::Val{false}) = "Last" + + @test firstlast(Val{true}()) == "First" + @test firstlast(Val{false}()) == "Last" +end + # try/finally begin after = 0