6.27. kink/VEC¶
6.27.1. type vec¶
`vec` is a mutable and variable-length sequence of values.
Elements of a `vec` are indexed using consequent integers starting from 0.
A `vec` is a subtype of `plain_param`. See kink/param/PLAIN_PARAM.
6.27.1.1. Vec.get(Ind)¶
`get` returns the element at the index `Ind`.
Precondition
`Ind` must be an integer `num` in the range [0, Vec.size).
Example
:Vec <- ['foo' 'bar' 'baz']
stdout.print_line(Vec.get(0).repr) # => "foo"
stdout.print_line(Vec.get(1).repr) # => "bar"
stdout.print_line(Vec.get(2).repr) # => "baz"
6.27.1.2. Vec.size¶
`size` returns the number of elements of `Vec` as an integer `num` value.
Example
:Vec <- ['foo' 'bar' 'baz']
stdout.print_line(Vec.size.repr) # => 3
6.27.1.3. Vec.front¶
`front` returns the first element of `Vec`.
Precondition
`Vec` must not be empty.
Example
stdout.print_line(['foo' 'bar' 'baz'].front.repr) # => "foo"
6.27.1.4. Vec.back¶
`back` returns the last element of `Vec`.
Precondition
`Vec` must not be empty.
Example
stdout.print_line(['foo' 'bar' 'baz'].back.repr) # => "baz"
6.27.1.5. Vec.take_front(N)¶
`take_front` returns a new `vec` containing the first `N` elements of `Vec`.
Precondition
`N` must be an integer `num` in the range [0, Vec.size].
Example
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
stdout.print_line(Vec.take_front(2).repr) # => ["0" "1"]
6.27.1.6. Vec.take_back(N)¶
`take_back` returns a new `vec` containing the last `N` elements of `Vec`.
Precondition
`N` must be an integer `num` in the range [0, Vec.size].
Example
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
stdout.print_line(Vec.take_back(2).repr) # => ["5" "6"]
6.27.1.7. Vec.drop_front(N)¶
`drop_front` returns a new `vec` which contains the elements of the slice of `Vec` in the range [N, Vec.size).
Precondition
`N` must be an integer `num` in the range [0, Vec.size].
Example
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
stdout.print_line(Vec.drop_front(2).repr) # => ["2" "3" "4" "5" "6"]
6.27.1.8. Vec.drop_back(N)¶
`drop_back` returns a new `vec` which contains the elements of the slice of `Vec` in the range [0, Vec.size - N).
Precondition
`N` must be an integer `num` in the range [0, Vec.size].
Example
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
stdout.print_line(Vec.drop_back(2).repr) # => ["0" "1" "2" "3" "4"]
6.27.1.9. Vec.slice(From To)¶
`slice` returns a new `vec` which contains the elements of the slice of `Vec` in the range [From, To).
Preconditions
`From` and `To` must be integer `num` values.
0 <= From <= To <= Vec.size
Example
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
stdout.print_line(Vec.slice(1 4).repr) # => ["1" "2" "3"]
6.27.1.10. Vec.set(Ind Val)¶
`set` stores `Val` at the index `Ind`.
The size of `Vec` does not change.
Precondition
`Ind` must be an integer `num` in the range [0, Vec.size).
Example
:Vec <- ['foo' 'bar' 'baz']
Vec.set(1 'X')
stdout.print_line(Vec.repr) # => ["foo" "X" "baz']
6.27.1.11. Vec.push_front(Val)¶
`push_front` inserts `Val` as the first element of `Vec`.
The size of `Vec` is extended by one. The existing elements are copied to the back by one.
Example
:Vec <- ['0' '1' '2' '3']
Vec.push_front('X')
stdout.print_line(Vec.repr) # => ["X" "0" "1" "2" "3"]
6.27.1.12. Vec.push_back(Val)¶
`push_back` inserts `Val` as the last element of `Vec`.
The size of `Vec` is extended by one.
Example
:Vec <- ['0' '1' '2' '3']
Vec.push_back('X')
stdout.print_line(Vec.repr) # => ["0" "1" "2" "3" "X"]
6.27.1.13. Vec.push_at(Pos Val)¶
`push_at` inserts `Val` at the index `Pos`.
The size of `Vec` is extended by one. The existing elements at and after `Pos` are copied to the back by one.
Preconditions
`Pos` must be an integer `num`.
0 <= Pos <= Vec.size
Example
:Vec <- ['foo' 'bar' 'baz']
Vec.push_at(2 'X')
stdout.print_line(Vec.repr) # => ["foo" "bar" "X" "baz"]
6.27.1.14. Vec.append_front(Eacher)¶
`append_front` inserts all the elements of `Eacher` to the front of `Vec`.
If Eacher.each passes E(0), E(1), ,,, E(n-1) to $consume for each invocation, and `Vec` currently contains V(0), V(1), ,,, V(m-1), the elements of Vec will be E(0) E(1) ,,, E(n-1) V(0) V(1) ,,, V(m-1) after the invocation of `append_front`.
Precondition
`Eacher` must support each($consume) method, which calls $consume with each element of `Eacher`.
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
Vec.append_front(['X' 'Y' 'Z'])
stdout.print_line(Vec.repr)
# => ["X" "Y" "Z" "foo" "bar" "baz" "qux" "grault"]
6.27.1.15. Vec.append_back(Eacher)¶
`append_back` inserts all the elements of `Eacher` to the back of `Vec`.
If Eacher.each passes E(0), E(1), ,,, E(n-1) to $consume for each invocation, and `Vec` currently contains V(0), V(1), ,,, V(m-1), the elements of Vec will be V(0) V(1) ,,, V(m-1) E(0) E(1) ,,, E(n-1) after the invocation of `append_back`.
Precondition
`Eacher` must support each($consume) method, which calls $consume with each element of `Eacher`.
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
Vec.append_back(['X' 'Y' 'Z'])
stdout.print_line(Vec.repr)
# => ["foo" "bar" "baz" "qux" "grault" "X" "Y" "Z"]
6.27.1.16. Vec.append_at(Pos Eacher)¶
`append_at` inserts all the elements of `Eacher` to `Vec` at the index `Pos`.
If Eacher.each passes E(0), E(1), ,,, E(n-1) to $consume for each invocation, and `Vec` currently contains V(0), V(1), ,,, V(m-1), the elements of `Vec` will be V(0), V(1) ,,, V(Pos-1), E(0), E(1) ,,, E(n-1), V(Pos) ,,, V(m-1) after the invocation of `append_at`.
Preconditions
`Pos` must be an integer `num`.
0 <= Pos <= Vec.size
`Eacher` must support each($consume) method, which calls $consume with each element of `Eacher`.
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
Vec.append_at(2 ['X' 'Y' 'Z'])
stdout.print_line(Vec.repr)
# => ["foo" "bar" "X" "Y" "Z" "baz" "qux" "grault"]
6.27.1.17. Vec.pop_front¶
`pop_front` removes the first element of `Vec` and returns the removed element.
The elements after the removed element are copied to the front by one. The size of `Vec` is curtailed by one.
Precondition
`Vec` must not be empty.
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
:Result <- Vec.pop_front
stdout.print_line(Result.repr) # => "foo"
stdout.print_line(Vec.repr) # => ["bar" "baz" "qux" "grault"]
6.27.1.18. Vec.pop_back¶
`pop_back` removes the last element of `Vec` and returns the removed element.
The size of `Vec` is curtailed by one.
Precondition
`Vec` must not be empty.
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
:Result <- Vec.pop_back
stdout.print_line(Result.repr) # => "grault"
stdout.print_line(Vec.repr) # => ["foo" "bar" "baz" "qux"]
6.27.1.19. Vec.pop_at(Ind)¶
`pop_at` removes the element at the index `Ind` and returns the removed element.
The elements after the removed element are copied to the front by one. The size of `Vec` is curtailed by one.
Preconditions
`Ind` must be an integer `num`.
0 <= Ind < Vec.size
Example
:Vec <- ['foo' 'bar' 'baz' 'qux' 'grault']
:Result <- Vec.pop_at(1)
stdout.print_line(Result) # => "bar"
stdout.print_line(Vec.repr) # => ["foo" "baz" "qux" "grault"]
6.27.1.20. Vec.clear(...[From=0 To=Vec.size])¶
`clear` removes the elements from `Vec` in the slice of the range [From, To).
The elements after the removed slice are copied to the front by (To - From). The size of `Vec` is curtailed to Vec.size - (To - From).
Preconditions
`From` and `To` must be integer `num` values.
0 <= From <= To <= Vec.size
Example: with no arg
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
Vec.clear
stdout.print_line(Vec.repr)
# => []
Example: with From
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
Vec.clear(3)
stdout.print_line(Vec.repr)
# => ["0" "1" "2"]
Example: with From and To
:Vec <- ['0' '1' '2' '3' '4' '5' '6']
Vec.clear(3 5)
stdout.print_line(Vec.repr)
# => ["0" "1" "2" "5" "6"]
6.27.1.21. Vec.dup¶
`dup` makes a new `vec` containing the same sequence of elements as `Vec` has.
Example
:Orig <- ['foo' 'bar' 'baz']
:Dup <- Orig.dup
Orig.set(0 'X')
Dup.set(1 'Y')
stdout.print_line(Orig.repr) # => ["X" 'bar" "baz"]
stdout.print_line(Dup.repr) # => ["foo" 'Y" "baz"]
6.27.1.22. Vec.reverse¶
`reverse` makes a new `vec` containing the same elements as `Vec` has, in the reversed order.
Example
:Vec <- ['0' '1' '2' '3']
stdout.print_line(Vec.reverse.repr) # => ["3" "2" "1" "0"]
6.27.1.23. Vec.concat¶
`concat` concatenates `vec`s in `Vec`.
`concat` assumes all the elements of `Vec` are `vec`s. `concat` returns a new `vec` which has all the elements of those `vec`s in the order of those `vec`s, and in the order of the elements of thsoe `vec`s.
Precondition
All the elements of `Vec` must be `vec`s.
Example
:Vecs <- [['0' '1'] ['2' '3'] ['4']]
stdout.print_line(Vecs.concat.repr) # => ["0" "1" "2" "3" "4"]
6.27.1.24. Vec.unconcat(N)¶
`unconcat` splits `Vec` into groups of `N` elements, and returns a new `vec` of `vec`s which have those `N` elements.
If `Vec` contains E(0), E(1) ,,, E(N-1), E(N), E(N+1) ,,, E(N+(N-1)) ,,, E(m*N), E(m*N+1) ,,, E(m*N+(N-1)), the result `vec` will contain `vec`s [E(0) E(1) ,,, E(N-1)], [E(N) E(N+1) ,,, E(N+(N-1))] ,,, [E(m*N) E(m*N+1) ,,, E(m*N+(N-1))].
Preconditions
`N` must be a positive integer `num`.
Vec.size % N == 0
Example
:Vec <- ['0' '1' '2' '3' '4' '5']
stdout.print_line(Vec.unconcat(2).repr) # => [["0" "1"] ["2" "3"] ["4" "5"]]
6.27.1.25. Vec.just(...[$if_empty])¶
`just` assumes `Vec` has only one element, and returns the element.
If `Vec` is empty, and $if_empty is passed, `just` tail-calls $if_empty.
Otherwise, `just` raises an exception.
Precondition
$if_empty must be a thunk.
Example
stdout.print_line([42].just.repr) # => 42
stdout.print_line([].just{ 'empty' }.repr) # => "empty"
[].just
# Output:
# -- main exception
# ,,,
# {(stdin) L4 C4 just} [].-->just
# Vec.just(...[$if_empty]): Vec must be a 1-elem vec, but the number of elems was 0
6.27.1.26. Vec.with_elems(...[$with0 $with1 $with2 ,,,])¶
`with_elems` tail-calls a fun with the elements of `Vec` as args.
`with_elems` takes an arbitrary number of funs. Let these be $with0, $with1, $with2, ,,, in that order. If the size of `Vec` is `N`, `with_elems` tail-calls $withN with the elements of `Vec` as args.
Preconditions
The size of `Vec` must be less than the number of args.
$withK (K = 0, 1, 2 ,,,) must take K args.
Example
:LOCALE.require_from('kink/')
:print_num <- {(:Num :Lang_tag.opt)
:Locale = Lang_tag.with_elems(
{ LOCALE.root }
{(:Lt) LOCALE.for(Lt) }
)
stdout.print_line(
Num.show{(:C)
C.locale(Locale)
C.group_len(3)
}
)
}
print_num(1234) # => 1,234
print_num(1234 'fr') # => 1 234
6.27.1.27. Vec.each($consume)¶
`each` calls $consume with each element from the front to the back.
If `Vec` is not empty, `each` tail-calls $consume for the last element.
Precondition
$consume must be a fun which takes a value.
Example
:Vec <- ['foo' 'bar' 'baz']
Vec.each{(:E)
stdout.print_line(E.repr)
}
# Output:
# "foo"
# "bar"
# "baz"
6.27.1.28. Vec.map($transform)¶
`map` makes a `vec` whose elements are transformed from the elements of `Vec` by $transform.
If `Vec` contains E(0), E(1) ,,, E(n-1), the result `vec` will contain transform(E(0)) transform(E(1)) ,,, transform(E(n-1)).
Precondition
$transform must be a fun which takes a value.
Example
:Vec <- [0 1 2 3 4]
:Mapped <- Vec.map{(:N) N * 10 }
stdout.print_line(Mapped.repr) # => [0 10 20 30 40]
6.27.1.29. Vec.concat_map($to_vec)¶
`concat_map` returns a `vec` which concatenates `vec`s which are results of to_vec(element-of-Vec)
Precondition
$to_vec must be a fun which takes a value and returns a `vec`.
Example
# extracts codepoints from the strs
:to_codepoints <- {(:Strs)
Strs.concat_map{(:S)
S.codepoints
}
}
:Codepoints <- to_codepoints(['foo' 'bar' 'baz'])
stdout.print_line(Codepoints.repr)
# => [102 111 111 98 97 114 98 97 122]
6.27.1.30. Vec.filter($include?)¶
`filter` returns a `vec` containing all the elements that satisfy the predicate $include?.
Precondition
$include? must be a predicate.
Example
:Nums <- [1 2 3 5 8 13 21 34 55 89]
:Evens <- Nums.filter{(:N)
N % 2 == 0
}
stdout.print_line(Evens.repr) # => [2 8 34]
6.27.1.31. Vec.count($counted?)¶
`count` returns the number of elements which satisfy the predicate $counted?, as an integer `num`.
Precondition
$counted? must be a predicate.
Example
:Nums <- [1 2 3 5 8 13 21 34 55 89]
:Even_count <- Nums.count{(:N)
N % 2 == 0
}
stdout.print_line(Even_count.repr) # => 3
6.27.1.32. Vec.fold(Init $combine)¶
`fold` folds elements seeded by `Init`.
If `Vec` contains elements E(0) E(1) ,,, E(n-1), the result will be combine(combine(,,, combine(combine(Init E(0)) E(1)) ,,,) E(n-1)).
Precondition
$combine must take two values.
Example
:to_quote_line <- {(:Words)
Words.fold('%'){(:Accum :Word)
Accum + ' ' + Word
}
}
:Quote <- to_quote_line(['foo' 'bar' 'baz'])
stdout.print_line(Quote.repr) # => "% foo bar baz"
6.27.1.33. Vec.reduce($combine ...[$empty_fallback])¶
`reduce` accumulates elements of `Vec` mutually.
If `Vec` has one or more elements, `reduce` tail-calls `Vec.drop_front(1).fold(Vec.front $combine)`.
If `Vec` is empty, and $empty_fallback is given, `reduce` tail-calls $empty_fallback with no arg.
If `Vec` is empty, and $empty_fallback is not given, `reduce` raises an exception.
Preconditions
$combine must be a fun which takes two values.
$empty_fallback must be a thunk.
Example: without fallback
:COMPARE.require_from('kink/')
stdout.print_line([31 41 59 26 53].reduce(COMPARE$max).repr) # => 59
Example: with fallback
:separate_by_commas <- {(:Args)
Args.reduce(
{(:Accum :Arg) Accum + ', ' + Arg }
{ '' }
)
}
stdout.print_line(separate_by_commas(['foo' 'bar' 'baz']).repr)
# => "foo, bar, baz"
stdout.print_line(separate_by_commas([]).repr)
# => ""
6.27.1.34. Vec.take_while($include?)¶
`take_while` returns a `vec` of the longest initial prefix whose elements satisfy the predicate $include?.
Precondition
$include? must be a predicate.
Example
:Nums <- [1 (-2) 3 (-4) 5 (-6) 7 (-8)]
:Prefix <- Nums.take_while{(:N)
N < 5
}
stdout.print_line(Prefix.repr)
# => [1 (-2) 3 (-4)]
6.27.1.35. Vec.drop_while($exclude?)¶
`drop_while` returns a `vec` of the elements after the longest initial prefix whose elements satisfy the predicate $exclude?.
Precondition
$exclude? must be a predicate.
Example
:Nums <- [1 (-2) 3 (-4) 5 (-6) 7 (-8)]
:Suffix <- Nums.drop_while{(:N)
N < 5
}
stdout.print_line(Suffix.repr)
# => [5 (-6) 7 (-8)]
6.27.1.36. Vec.all?($match?)¶
`all?` returns whether all the elements of `Vec` satisfy the predicate $match?.
Precondition
$match? must be a predicate.
Example
:all_even? <- {(:Nums)
Nums.all?{(:N)
N % 2 == 0
}
}
stdout.print_line(all_even?([0 2 4]).repr) # => true
stdout.print_line(all_even?([6 7 9]).repr) # => false
stdout.print_line(all_even?([1 3 5]).repr) # => false
6.27.1.37. Vec.any?(...[$match?={ true }])¶
`any?` returns whether at least one of the elements of `Vec` satisfies the predicate $match?.
$match? is an optional arg with a default value { true }, So, if $match? is not passed, `any?` returns whether `Vec` is nonempty.
Precondition
$match? must be a predicate.
Example
:any_even? <- {(:Nums)
Nums.any?{(:N)
N % 2 == 0
}
}
stdout.print_line(any_even?([0 2 4]).repr) # => true
stdout.print_line(any_even?([6 7 9]).repr) # => true
stdout.print_line(any_even?([1 3 5]).repr) # => false
Example
stdout.print_line([].any?.repr) # => false
stdout.print_line(['foo'].any?.repr) # => true
stdout.print_line(['foo' 'bar'].any?.repr) # => true
6.27.1.38. Vec.have?(Target)¶
`have?` returns whether `Vec` has an element which is equal to `Target` by `==` operator, or `op_eq` method.
Calling Vec.have?(Target) is equivalent to calling Vec.any?{(:E) Target == E }.
Example
stdout.print_line([1 3 5].have?(3).repr) # => true
stdout.print_line([2 4 6].have?(3).repr) # => false
6.27.1.39. Vec.have_all?(Vals)¶
`have_all?` returns whether `Vec` has all the elements of `Vals`.
Calling Vec.have_all?(Vals) is equivalent to calling Vals.all?{(:T) Vec.have?(T) }.
Preconditions
`Vals` must have all?($match?) method.
`==` operator, or `op_eq` method, must be able to compare elements of `Vec` and `Vals`.
Example
:FLAT_SET.require_from('kink/container/')
:Vec <- [2 4 6 8]
stdout.print_line(Vec.have_all?(FLAT_SET.of(2 4)).repr) # => true
stdout.print_line(Vec.have_all?(FLAT_SET.of(6 7)).repr) # => false
6.27.1.40. Vec.have_any?(Vals)¶
`have_any?` returns whether `Vec` has any element of `Vals`.
Calling Vec.have_any?(Vals) is equivalent to calling Vals.any?{(:T) Vec.have?(T) }.
Preconditions
`Vals` must have any?($match?) method.
`==` operator, or `op_eq` method, must be able to compare elements of `Vec` and `Vals`.
Example
:FLAT_SET.require_from('kink/container/')
:Vec <- [2 4 6 8]
stdout.print_line(Vec.have_any?(FLAT_SET.of(2 4)).repr) # => true
stdout.print_line(Vec.have_any?(FLAT_SET.of(6 7)).repr) # => true
stdout.print_line(Vec.have_any?(FLAT_SET.of(10 20)).repr) # => false
6.27.1.41. Vec.sort(...[$in_order?={(:X :Y) X <= Y }])¶
`sort` returns a `vec` whose elements are copied from `Vec` and sorted in the ascending order specified by $in_order?.
Comparison
Comparison of elements are done by $in_order?.
$in_order? must be a total order relation of the elements of `Vec`. For all `X`, `Y`, and `Z` in the elements of `Vec`, $in_order? must satisfy the following.
• reflexive: in_order?(X X)
• transitive: if in_order?(X Y) && in_order?(Y Z) then in_order?(X Z)
• antisymmetric: if in_order?(X Y) && in_order?(Y X) then X is equivalent to Y
• strongly connected: in_order?(X Y) || in_order?(Y X)
Stable sort
`sort` performs a stable sort. If in_order?(E1 E2) && in_order?(E2 E1), for `E1` and `E2` in `Vec`, `E1` and `E2` appear in the result `vec` in the same order as in `Vec`.
Precondition
$in_order? must be a fun which takes two values and returns a `bool`.
Example
:Vec <- ['foo' 'bar' 'baz' 'FOO' 'BAR' 'BAZ']
stdout.print_line(Vec.sort.repr)
# => ["BAR" "BAZ" "FOO" "bar" "baz" "foo"]
stdout.print_line(Vec.sort{(:X :Y) X.ascii_downcase <= Y.ascii_downcase }.repr)
# => ["bar" "BAR" "baz" "BAZ" "foo" "FOO"]
6.27.1.42. Vec.iter(...[From=0 To=Vec.size])¶
`iter` method returns an `iter` containing the elements of the slice in the range [From, To).
Preconditions
`From` and `To` must be integer `num` values.
0 <= From <= To <= Vec.size
Example
['0' '1' '2' '3' '4'].iter.each{(:S)
stdout.print_line(S.repr)
}
# Output:
# "0"
# "1"
# "2"
# "3"
# "4"
['0' '1' '2' '3' '4'].iter(2).each{(:S)
stdout.print_line(S.repr)
}
# Output:
# "2"
# "3"
# "4"
['0' '1' '2' '3' '4'].iter(2 4).each{(:S)
stdout.print_line(S.repr)
}
# Output:
# "2"
# "3"
6.27.1.43. Vec1 + Vec2¶
`+` operator, or `op_add` method, returns a `vec` containing all the elements of `Vec1` in the front, and all the elements of `Vec2` in the back.
Precondition
`Vec2` must be a `vec`.
Example
stdout.print_line((['0' '1'] + ['2' '3']).repr) # => ["0" "1" "2" "3"]
6.27.1.44. Vec * N¶
`*` operator, or `op_mul` method, returns a `vec` containing the elements of `Vec` repeated `N` times.
Preconditions
`N` must be a nonnegative integer `num`.
Example
stdout.print_line(([1 2] * 3).repr) # => [1 2 1 2 1 2]
6.27.1.45. Vec1 == Vec2¶
`==` operator, or `op_eq` method, returns whether `Vec1` and `Vec2` are equal, or they contain equal elements in the same order.
The two vecs are equal if:
1) Vec1.size == Vec2.size
2) For all i in [0, Vec1.size), Vec1.get(i) == Vec2.get(i)
The conditions are tested in the numbered order, and from the smallest `i` to the biggest `i`. If a test returns false, subsequent tests are not evaluated and two vecs are decided not equal.
Precondition
`Vec1` and `Vec2` must be `vec` values.
Example
:CONTROL.require_from('kink/')
:test_equality <- {(:Vec1 :Vec2)
CONTROL.try(
{ Vec1 == Vec2 }
{(:Result) stdout.print_line(Result.repr) }
{(:Exc)
stdout.print_line('op_eq: exception: {}'.format(Exc.message))
}
)
}
# equal
test_equality(['foo' 42] ['foo' 42])
# Output: true
# not equal because sizes differ
test_equality(['foo' 42] ['foo' 42 'bar'])
# Output: false
# not equal because the first elemenets differ
test_equality(['foo' 42] ['bar' 42])
# Output: false
# not equal because the first elemenets differ;
# the second elements are not tested
test_equality(['foo' 42] ['bar' '***'])
# Output: false
test_equality(['foo' 42] ['foo' '***'])
# Output:
# op_eq: exception: Num1.op_eq(Num2): the arg must be an int num, but got "***"
6.27.1.46. Vec1 <= Vec2¶
`<=` operator, or `op_le` method, returns whether `Vec1` is less than or equal to `Vec2` by the order defined by `<=` operator of the elements.
`Vec1` is less than or equal to `Vec2` when:
1) There is a nonnegative integer k (k < min(Vec1.size Vec2.size)), such that for all i in [0, k) Vec1.get(i) <= Vec2.get(i) && Vec2.get(i) <= Vec1.get(i), and ! (Vec2.get(k) <= Vec1.get(k)); or
2) Vec1.size <= Vec2.size and for all i in [0, Vec1.size), Vec1.get(i) <= Vec2.get(i) && Vec2.get(i) <= Vec1.get(i).
Comparisons are done from the smallest index to the biggest index. When the result is determined, the subsequent comparisons are not performed.
Precondition
`Vec2` must be a `vec`.
Example
:compare <- {(:Vec1 :Vec2)
[:Lt? :Le? :Gt? :Ge?] = [
Vec1 < Vec2
Vec1 <= Vec2
Vec1 > Vec2
Vec1 >= Vec2
]
stdout.print_line(
'Lt?={} Le?={} Gt?={} Ge?={}'.format(Lt?.repr Le?.repr Gt?.repr Ge?.repr))
}
compare(['A' 42] ['A' 42])
# => Lt?=false Le?=true Gt?=false Ge?=true
compare(['A' 42] ['A' 42 'foo'])
# => Lt?=true Le?=true Gt?=false Ge?=false
compare(['A' 42] ['A'])
# => Lt?=false Le?=false Gt?=true Ge?=true
compare(['A' 42] ['B' 42])
# => Lt?=true Le?=true Gt?=false Ge?=false
compare(['A' 42] ['A' 84])
# => Lt?=true Le?=true Gt?=false Ge?=false
6.27.1.47. Lhs <- Rhs¶
`<-` operator, or `op_store` method, performs multiple assignment between a `vec` on the left hand side, `Lhs`, and the `vec` on the right hand side, `Rhs.
Here, elements of `Lhs` are called params, and elements of `Rhs` are called args.
Params and args
There are three types of params:
• plain_param: ex. varref, vec. Can receive 1 arg.
• opt_param: ex. Varref.opt. Can receive 0 or 1 arg.
• rest_param: ex. Varref.rest. Can receive an arbitrary number of args.
`plain_param` and `opt_param` can appear any number of times in `Lhs`. An `opt_param` cannot precede a `plain_param`.
`Lhs` can have zero or one `rest_param` at the back.
Let `NP` be the number of `plain_param`, and `NO` be the number of `opt_param`. Here, P(0), P(1) ,,, P(NP-1), O(0), O(1) ,,, O(NO-1) are params, where P(i) for each i (0 <= i < NP) is a `plain_param`, and O(j) for each j (0 <= j < NO) is an `opt_param`.
In addition, let `NA` be the number of args, and A(k) for each k (0 <= k < NA) be an arg.
`op_store` behaves differently depending on whether `Lhs` has a `rest_param` or not.
When `Lhs` has no `rest_param`
In this case, the number of args `NA` is valid when NP <= NA <= NP+NO.
When the number of args is not valid, `op_store` raises an exception.
When the number of args is valid, `op_store` calls a method of each param as follows:
• P(k).op_store(A(k)) for each k (0 <= k < NP)
• O(k - NP).pass_arg(A(k)) for each k (NP <= k < NA)
• O(k - NP).pass_nothing for each k (NA <= k < NP+NO)
When `Lhs` has a `rest_param`, `R`
In this case, the number of args `NA` is valid when NP <= NA.
When the number of args is not valid, `op_store` raises an exception.
When the number of args is valid, `op_store` calls a method of each param as follows:
• P(k).op_store(A(k)) for each k (0 <= k < NP)
• O(k - NP).pass_arg(A(k)) for each k (NP <= k < NA)
• O(k - NP).pass_nothing for each k (NA <= k < NP+NO)
• R.pass_rest(vec of A(k) for each k (NP+NO <= k < NA))
Precondition
`Rhs` must be a `vec`.
Example
:CONTROL.require_from('kink/')
[:X :Y] <- ['x' 'y']
stdout.print_line('X={} Y={}'.format(X.repr Y.repr))
# => X="x" Y="y"
[:X :Y :Z.opt :W.opt] <- ['x' 'y']
stdout.print_line('X={} Y={} Z={} W={}'.format(X.repr Y.repr Z.repr W.repr))
# => X="x" Y="y Z=[] W=[]"
[:X :Y :Z.opt :W.opt] <- ['x' 'y' 'z']
stdout.print_line('X={} Y={} Z={} W={}'.format(X.repr Y.repr Z.repr W.repr))
# => X="x" Y="y Z=["z"] W=[]"
[:X :Y :Z.opt :W.opt] <- ['x' 'y' 'z' 'w']
stdout.print_line('X={} Y={} Z={} W={}'.format(X.repr Y.repr Z.repr W.repr))
# => X="x" Y="y Z=["z"] W=["w"]"
[:X :Y :R.rest] <- ['x' 'y']
stdout.print_line('X={} Y={} R={}'.format(X.repr Y.repr R.repr))
# => X="x" Y="y" R=[]
[:X :Y :R.rest] <- ['x' 'y' 'r1' 'r2']
stdout.print_line('X={} Y={} R={}'.format(X.repr Y.repr R.repr))
# => X="x" Y="y" R=["r1" "r2"]
[:X :Y :Z.opt :W.opt :R.rest] <- ['x' 'y']
stdout.print_line('X={} Y={} Z={} W={} R={}'.format(X.repr Y.repr Z.repr W.repr R.repr))
# => X="x" Y="y" Z=[] W=[] R=[]
[:X :Y :Z.opt :W.opt :R.rest] <- ['x' 'y' 'z']
stdout.print_line('X={} Y={} Z={} W={} R={}'.format(X.repr Y.repr Z.repr W.repr R.repr))
# => X="x" Y="y" Z=["z"] W=[] R=[]
[:X :Y :Z.opt :W.opt :R.rest] <- ['x' 'y' 'z' 'w']
stdout.print_line('X={} Y={} Z={} W={} R={}'.format(X.repr Y.repr Z.repr W.repr R.repr))
# => X="x" Y="y" Z=["z"] W=["w"] R=[]
[:X :Y :Z.opt :W.opt :R.rest] <- ['x' 'y' 'z' 'w' 'r1' 'r2']
stdout.print_line('X={} Y={} Z={} W={} R={}'.format(X.repr Y.repr Z.repr W.repr R.repr))
# => X="x" Y="y" Z=["z"] W=["w"] R=["r1" "r2"]
# Invalid numbers of right-hand-side vals:
CONTROL.try(
{ [:X :Y] <- [1 2 3] }
{ raise('must not reach here') }
{(:Exc)
stdout.print_line('exception: {}'.format(Exc.message))
}
)
# => exception: too many args: for [:X :Y], got [1 2 3]
CONTROL.try(
{ [:X :Y] <- [1] }
{ raise('must not reach here') }
{(:Exc)
stdout.print_line('exception: {}'.format(Exc.message))
}
)
# => exception: too few args: for [:X :Y], got [1]
6.27.1.48. Vec.repr¶
`repr` returns a `str` representation of `Vec`.
Example
stdout.print_line(['foo' 42].repr) # => ["foo" 42]
6.27.2. VEC.is?(Val)¶
`is?` returns whether `Val` is a `vec`.
6.27.3. VEC.from_each(Eacher)¶
`from_each` returns a new `vec` including all the elements of `Eacher`.
`Eacher` must have .each($consume) method which calls $consume for each element.
Example
:VEC.require_from('kink/')
:FLAT_SET.require_from('kink/container/')
:Set <- FLAT_SET.of('foo' 'bar' 'baz')
stdout.print_line(VEC.from_each(Set).repr)
# => ["bar" "baz" "foo"]