Skip to content

Commit

Permalink
Revert "Revert "Add documentation and test for Val{T}""
Browse files Browse the repository at this point in the history
This reverts commit ef7f5d4.

This is modified to incorporate the verdict in the discussion
of #9452.
  • Loading branch information
timholy committed Jan 4, 2015
1 parent 9451e4a commit 2447f79
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------------
Expand Down Expand Up @@ -1145,3 +1146,4 @@ Too numerous to mention.
[#9271]: https://github.com/JuliaLang/julia/issues/9271
[#9294]: https://github.com/JuliaLang/julia/issues/9294
[#9569]: https://github.com/JuliaLang/julia/issues/9569
[#9452]: https://github.com/JuliaLang/julia/issues/9452
35 changes: 34 additions & 1 deletion doc/manual/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1243,6 +1243,39 @@ 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(::Type{Val{true}}) = "First"
firstlast(::Type{Val{false}}) = "Last"

println(firstlast(Val{true}))

Any legal type parameter (Types, Symbols, Integers, floating-point
numbers, tuples, etc.) can be passed via ``Val``.

For consistency across Julia, the call site should always pass a
``Val`` type rather than creating an instance, i.e., use
``foo(Val{:bar})`` rather than ``foo(Val{:bar}())``.

Nullable Types: Representing Missing Values
-------------------------------------------

Expand Down
8 changes: 8 additions & 0 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,14 @@ 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" 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
(at compile-time) to an implementation ``f(::Type{Val{false}})``,
without having to test the boolean value at runtime.

Generic Functions
-----------------

Expand Down
10 changes: 10 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,16 @@ begin
@test is(g(a),a)
end

# dispatch using Val{T}. See discussion in #9452 for instances vs types
begin
local firstlast
firstlast(::Type{Val{true}}) = "First"
firstlast(::Type{Val{false}}) = "Last"

@test firstlast(Val{true}) == "First"
@test firstlast(Val{false}) == "Last"
end

# try/finally
begin
after = 0
Expand Down

0 comments on commit 2447f79

Please sign in to comment.