Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

tuple.fz


# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation.  If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
#  Tokiwa Software GmbH, Germany
#
#  Source code of Fuzion standard library feature tuple
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------

# tuple -- feature used to define tuple types
#
# tuple types provide algebraic product types of all the generic arguments
# provided to tuple.
#
# The values within a tuple 'tuple<A, B, C>' can be accessed via the tuple's
# argument field 'values' followed by a selector referring to the generic
# argument's position: 'values.0', 'values.1' and 'values.2', respectively.
#
# Syntactic sugar of the Fuzion language permits an alternative notation
# to create values of tuple types as follows
#
#   t := (a, b, c, ... )
#
# is equivalent to
#
#   t := tuple(a, b, c, ... )
#
# The actual generic types are inferred from the static types of the values
# 'a', 'b', 'c', ... the tuple is created from.
#
# Similarly, syntactic sugar for the destructuring of tuples can be used
# to access the values as in
#
#   (a, b, c, ...) := t
#
# In destructurings, we can denote values we are not interested in using
# '_' as in
#
#  (_, b) := ("first", "second")
#
# which will set 'b' to '"second"' and drop the first element of the tuple.
#
# As an example, say we want to identify a person by its name and its age,
# so we can define
#
#   a := ("Alice" , 11)
#   b := ("Bob"   , 22)
#   c := ("Claire", 33)
#
# Then, we could extract Bob's age using
#
#   (_, age) := b
#
# or Claire's name using
#
#   (name, _) := c
#
# Destructuring also works for general features, e.g.
#
#   point (x,y i32) is {}
#
#   p := point 3, 4
#   (px, py) := p       # will set px to 3 and py to 4
#
# and the destructured value can then be used to create a tuple
#
#   t := (px, py)       # will create tuple<i32,i32> instance
#
# however, tuples are not assignment compatible with general features even
# if they would destructure into the same types, i.e.,
#
#   u tuple<i32, i32> = p  # will cause compile time error
#   q point = (7, 12)      # will cause compile time error
#
# The unit tuple '()' can be used as a short-hand to create the empty tuple
# 'tuple<>()'.  The empty tuple can be destructured like any other tuple
# using
#
#   () := ()
#
# even though this has no effect.
#
# An instance of the single tuple 'tuple<A>(a)' can not be created using
# syntactic sugar '(a)', this will produce the plain value of 'a' instead.
# However, destructuring of a single tuple is possible:
#
#  (a0) := tuple<A>(a)
#
# which is equivalent to
#
#   a0 := a
#
# NYI: A single tuple 'tuple<A>' is currently not assignment compatible with
# type 'A', which would make handling of general tuples easier.
#
# tuples and destructuring can be used to swap two elements or create a
# permutation as in
#
#   (a, b) := (b, a)
#   (o, t, a, n) := (n, a, t, o)
#
# A tuple type with no actual generic arguments is isomorphic to 'unit', i.e, it
# is a type that has only one single value: '()'.
#

tuple<A...>(values A) is