Tuple

Overview

A lightweight sequence type mainly for use as keys in a map or as elements of a set.

Examples of usage:

> tuple = sano.makers.tuple
> t = tuple(1,2,3); print(t)
(1, 2, 3)
> print(t == tuple(1, 2, 3))
true
> print(t == tuple(1, 2))
false
> for e in t:iter() do print(e) end
1
2
3
> a, b, c = t:unpack() -- built-in unpack(t) has same effect
> print(a, b, c)
123
> hashset = sano.makers.hashset
> tuples = hashset(t, tuple(8,7,6))
> print(tuples:contains(tuple(8, 7, 6)))
true

It's possible to give any table tuple-like powers simply by setting its metatable to be Tuple, for instance:

> t = {1,2,3,4}
> print(t)
table: 0x82cb810
> setmetatable(t, Tuple)
> print(t)
(1, 2, 3, 4)
> h = hashset{tuple(1,2,3,4)}
> print(h:contains(t))
true
> setmetatable(t, nil) -- restore back to normal
> print(h:contains(t))
false

Tuples are ordered lexicographically in the obvious way, for example:

(1,1) <= (1,1), (1,2,2) < (1,2,3), () < (1), (1,2,1) < (1,3), etc.

More precisely, if a = (a1, a2, ..., aN) and b = (b1, b2, ..., bN), then a < b if:

b1 > a1
OR
b1 == a1, b2 == a2, ..., bK == aK, bK+1 > aK+1 (b is greater than a)

If a and b have different sizes, the smaller Tuple will be ordered before the larger if pairwise comparisons do not reveal an ordering.

Summary

makeIdentical behavior to Tuple:new(), except that if just one argument is passed, it is assumed to be *iterable* and the elements of the iteration are added to the Tuple.
newReturns a newly constructed Tuple containing all elements passed as arguments to this method.
__eqReturns true if both Tuples have the same size and contain the same elements in the same order.
__hashReturns a number that will be used as the hash code when this Tuple is stored in a HashMap or HashSet.
__ltReturns true if this Tuple is lexicographically less than other.
iterReturns an iterator over the elements in this Tuple.
rehashRecompute and return the hash value for this Tuple.
sizeReturns the number of elements in this tuple.
testUnit test.
unpackWrapper around built-in unpack method.

Detail

Tuple:make(...)

Identical behavior to Tuple:new(), except that if just one argument is passed, it is assumed to be iterable and the elements of the iteration are added to the Tuple.

Example: Tuple:make(iter.count(3)) == Tuple:make{1,2,3} == Tuple:make(1,2,3)

Tuple:new(...)

Returns a newly constructed Tuple containing all elements passed as arguments to this method.

It is perfectly fine to pass zero arguments (this creates an empty tuple) or one argument (this creates a tuple containing just that argument)

Examples:

> print( Tuple:new(1,2,3) )
(1, 2, 3)
> print( Tuple:new(1) ) 
(1)
> print( Tuple:new() )
()

Tuple:__eq(other)

Returns true if both Tuples have the same size and contain the same elements in the same order.

Tuple:__hash()

Returns a number that will be used as the hash code when this Tuple is stored in a HashMap or HashSet.

The value is cached in the field self.hash. Tuples are intended to be used as immutable objects (otherwise, use Vector). Although there is nothing stopping a determined soul from modifying a Tuple, if it is being used as a key in a map, this will result in the Tuple being stored in the wrong bucket.

See HashMap and SkipMap for more information on using Tuples or other composite objects as keys.

In keeping with the contract of the __hash metamethod Tuple objects that are equal return the same hash value.

Tuple:__lt(other)

Returns true if this Tuple is lexicographically less than other.

If a = (a1, a2, ..., aN) and b = (b1, b2, ..., bN), then a < b iff:

b1 > a1
OR
b1 == a1, b2 == a2, ..., bK == aK, bK+1 > aK+1 (b is greater than a)

If a and b have different sizes, the smaller Tuple will be ordered before the larger if pairwise comparisons do not reveal an ordering.

Examples: (1,1) <= (1,1), () <= (1), (1,2,1) <= (1,3)

The evaluation is 'short-circuit' and halts as soon as there is enough information to determine the ordering.

See Tuple.documentation.general for more information on how Tuples are ordered.

Also see ordering.lexicographical.

Tuple:__tostring()

Returns a string of the form "(e1, e2, ..., eN)"

Tuple:iter()

Returns an iterator over the elements in this Tuple.

Tuple:rehash()

Recompute and return the hash value for this Tuple.

Since Tuples are intended mostly to be used as immutable objects, this method shouldn't normally be called (once the hash value is computed once, it shouldn't need to be computed again).

Tuple:size()

Returns the number of elements in this tuple.

If the tuple, t, has no holes, then #t will return the same result as t:size().

Tuple:test()

Unit test.

Tuple:unpack()

Wrapper around built-in unpack method.

Given a Tuple, t, t:unpack() and unpack(t) are equivalent, since t is just a table with a few convenience methods.