Skip to content

Latest commit

 

History

History
128 lines (92 loc) · 3.65 KB

about.md

File metadata and controls

128 lines (92 loc) · 3.65 KB

About

A Tuple is quite similar to a Vector (1-D array) in many ways. However, there are a few important differences.

  • Tuples are written in parentheses ( ) instead of brackets [ ], though the parentheses can be omitted in cases where the meaning is unambiguous.
  • Tuples are not required to be homogeneous: the type of each element is stored independently.
  • Tuples are immutable.

Immutability allows more compiler optimizations and makes tuples more performant than vectors, so they should be preferred in cases where mutability is not necessary.

julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")

# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
  1: Int64 3
  2: Float64 5.2
  3: String "xyz"

julia> t[2]
5.2

# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String}

For any tuple, it is possible to access elements by index or loop over them.

Any purely numerical tuple can also be used in mathematical functions such as sum(), exactly like arrays.

Named tuples

A Tuple contains only values. A NamedTuple pairs each value with a name.

Individual fields can then be accessed with "dot" notation:

julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)

julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
  a: Int64 1
  b: Float64 7.3

julia> nt.b
7.3

The name is stored internally as a Symbol (discussed in a later Concept), so there is an alternative syntax available:

julia> nt[:b]
7.3

It is sometimes useful to split creation of a named tuple into two steps:

  1. Define the fields as as custom data type.
  2. Use this as a constructor to convert a tuple to a named tuple.
# Step 1
julia> Student = NamedTuple{(:name, :grade), Tuple{String, Int}}
@NamedTuple{name::String, grade::Int64}

julia> typeof(Student)
DataType

# Step 2
julia> s = Student( ("Helen", 3) )
(name = "Helen", grade = 3)

julia> dump(s)
@NamedTuple{name::String, grade::Int64}
  name: String "Helen"
  grade: Int64 3

There are surprisingly many other ways to create a named tuple, so check the documentation if you are interested.

It is easy to get either the names (also called "keys") or values separately:

julia> keys(s)
(:name, :grade)

julia> values(s)
("Helen", 3)

Note that iteration over a named tuple only produces the values, and the names are ignored.

If the names are also useful in an iteration, more steps are needed. The NamedTuple can be converted to a Vector of Pairs (Pairs are the subject of another Concept).

julia> pairs(s)
pairs(::NamedTuple) with 2 entries:
  :name  => "Helen"
  :grade => 3

julia> collect(pairs(s))
2-element Vector{Pair{Symbol, Any}}:
  :name => "Helen"
  :grade => 3

The named tuple is thus quite dictionary-like. However, it differs from a [Dict][dict] in Julia in some important ways:

  • A Dict is mutable; a NamedTuple, like any tuple, is immutable.
  • A Dict is flexible in the type of keys it accepts; a NamedTuple can only use symbols as keys.

Tuples (named or not) are a very common way to transfer structured data to and from functions. Immutability is good in this use case, providing data safety and allowing more aggressive compiler optimizations.