Slide 20 of 74

Walking and sorting

map, filter and filterMap
func isLong(fruit: Str): Bool {
	return len(fruit) > 4
}

func shout(fruit: Str): Str {
	return fruit + "!"
}

func evenHalf(n: Int): Result<Int, Bool> {
	if n % 2 == 0 {
		return Result.Ok(n / 2)
	}
	return Result.Error(false)
}

proc main(): void {
	fruit := ["pear", "apple", "kiwi"]
	echo map(fruit, shout)                   // ["pear!", "apple!", "kiwi!"]
	echo filter(fruit, isLong)               // ["apple"]
	echo filterMap([1, 2, 3, 4], evenHalf)   // [1, 2]
}
Sorting
func longerFirst(a: Str, b: Str): Bool {
	return len(a) > len(b)
}

proc main(): void {
	echo sort(["pear", "Apple", "kiwi"])        // ["Apple", "kiwi", "pear"] — by bytes
	echo sort([true, false])                    // [false, true]
	echo sort([[2, 1], [1, 9], [1, 2]])         // [[1, 2], [1, 9], [2, 1]]
	echo sort(["fig", "banana", "kiwi"], longerFirst)

	mut ranks := [3, 1, 2]
	sort(ranks)                                 // a statement: sorts ranks in place
	echo ranks
}

Four builtins walk a vector with a func, once per element, in order, on the calling thread — a proc is refused, since a walk has nowhere to put what one writes:

  • map(values, transform) answers with every element transformed, and keeps the vector's length. A transform that answers with nothing is refused: a walk that only acts is a for each.
  • filter(values, keep) answers with the elements keep says true to.
  • filterMap(values, transform) does both at once: transform answers with a Result, and the Ok payloads are kept.
  • sort(values) answers with the elements in order, and sort(values, first) in the order a func(a, b): Bool gives, true when a comes first. Equal elements keep the order they had.

Without a comparator, sort uses the elements' own order: numbers by value, a Str by its bytes (so "B" comes before "a"), false before true, an atom by where it was first mentioned, a vector element by element, a declared type field by field in declaration order, a union by the order its variants were declared in, and a Result's Errors before its Oks. A map, an address and a function value have no order, nor does a type holding one, so sorting those takes a comparator.

sort written as a statement, on a mut vector, sorts it in place instead.