Documentation for gololang.Functions

This module contains several functions and higher order functions or decorators, mostly useful with HOF like map, reduce or in generators.

Indeed, using HOF often require some classical functions like constants one, identity, or classical operators.

Most of the times, these functions needs to be unary ones, i.e. have only one parameter. This module contains, among others, functions helping in the arity conversion of such functions:

Most of the binary operator functions defined here are curried. To ease partialization, the non commutative operators have a reversed version, with arguments swapped. For example, using the reverse division operator rdiv with map

[2, 4, 8]: map(rdiv(2)) == [1, 2, 4]

The identity function id, the constant function const, together with composition (FunctionReference::andThen, pipe, compose) and io can be used to create monad-like processing chains.

Functions

add(value, element)

Polymorphic addition and concatenation.

Adds value to element. The behavior depends on the type of element:

This function is swapped and curried. For instance:

add("b", "a") == "ab"

list[1, 2, 3]: map(add(3)) == list[4, 5, 6]

add("a", StringBuilder()): toString() == "a"

let f = add(42): andThen(add(1337)): andThen(add(69))
f(list[]) == list[42, 1337, 69]
f(0) == 1448
f(StringBuilder()): toString() == "42133769"

See also addTo

addTo(element, value)

Not swapped version of add

and(a)

Curried boolean and.

This implementation is lazy.

The arguments can be boolean expressions or predicate functions. If called with predicate functions, returns a new predicate function.

`and(a, b) == (a and b)
`and(gt(10), ^even) == |x| -> a > 10 and x % 2 == 0

See also or, not, xor

compose(funcs...)

Function composition.

compose(f1, f2, f3)(x) == f1(f2(f3(x)))

This is similar to pipe, but with functions order reversed (B combinator).

cond(predicate, ifTrue, ifFalse, x)

Conditional application combinator.

Equivalent to using the match construct:

let r = cond(predicate, ifTrue, ifFalse, x)

# equivalent to
let r = match {
  when predicate(x) then ifTrue(x)
  otherwise ifFalse(x)
}

Since this function is curried, it can be used as:

let f = cond(predicate, ifTrue, ifFalse)

# equivalent to
let f = |x| -> match {
  when predicate(x) then ifTrue(x)
  otherwise ifFalse(x)
}

const(val)

The constant function.

Returns a new variadic functions that always returns val, ignoring its arguments. For example:

let theAnswerTo = const(42)

theAnswerTo() == 42
theAnswerTo(1, 2, 3) == 42
theAnswerTo("Life, the Universe and Everything") == 42

One interesting use case is to write “pipe” like composition, with the argument on the left:

const(42): andThen(f): andThen(g): andThen(h)() == h(g(f(42)))

This is also the K combinator.

contains(value, collection)

Swapped curried containment test.

Checks if collection contains value. The collection object can be anything with a contains method.

For instance:

let predicate = contains(42)
if (predicate(collection)) {
  ...
}

curry(f)

Function to curryfy a function, i.e. transforms a polyadic function into a sequence of variadic functions. This allows for automatic partial application.

This is equivalent to applying invokeOrBind on each call.

E.g.

function f = |a, b, c| -> a + b + c

let g = curry(^f)

g(29)(10)(3) == f(29, 10, 3)
g(29, 10)(3) == 42
g(29)(10, 3) == 42

let g1 = g(29)
let g2 = g1(10)
let g3 = g(29, 10)

g(29, 10, 3) == 42
g1(10, 3) == 42
g1(10)(3) == 42
g2(3) == 42
g3(3) == 42

This is particularly useful to allow composing polyadic functions. For instance, with the previous g:

let h = g(2, 20): andThen(g("The answer", " is "))
h(20) == "The answer is 42"

If the function is variadic, only the fixed parameters can be partialized. For instance, given:

@!curry
function f = |a, b, c...| -> ...
...
let g = f(1, 2)

then g is a variadic function that can't be called partially. All the following calls are valids:

g()
g(1)
g(1, 2, 3)

but

g(1)(2)

is not.

This function can also be used as a decorator.

See also uncurry

div(x, y)

Curried division.

div(x, y) == x / y

See also mul, rdiv

eq(a, b)

Curried equal.

eq(a, b) == (a == b)

See also ne

even(a)

Checks if the value is even.

See also odd

False(_...)

false constant function.

fst(t)

First element of a list, tuple, vector, array.

fst([a, b]) == a

ge(a, b)

Curried swapped greater than or equal.

ge(a, b) == (b >= a)

Note: this function is swapped to make curried version more readable.

See also lt, le, gt

getitem(obj, i)

Curried indexing.

getitem(obj, i) == obj: get(i)

Throws an IndexOutOfBoundsException (for a collection-like object) or returns null (for a map-like object) if the index is not present.

See also setitem, getter

getter(i)

Indexer factory (curried indexing).

let third = getter(2)
third([1, 2, 3, 4]) -> 3

See also getitem

gt(a, b)

Curried swapped greater than.

gt(a, b) == b > a

Note: this function is swapped to make curried version more readable.

See also lt, le, ge

id(x)

The identity function.

Returns it's argument unchanged. This can be useful with higher order functions (I combinator).

invokeWith(args...)

Reversed curried function application.

Apply the given function to the given value.

invokeWith("a", "b", "c")(f) == f("a", "b", "c")

For instance, given a list of functions:

list[f, g, h]: map(invokeWith(42)) == list[f(42), g(42), h(42)]

It can also be used to promote a value in continuation passing style.

io(block)

Transform a function with side effects (generally IO operations, thus the name) into a function applying the side effect. If the wrapped function returns null, its argument is return instead.

The given function can have no parameters, or accept an argument.

This can be used to insert such a function into a composition chain:

f1: andThen(io({println("hello")})): andThen(f2)

is an anonymous function equivalent to:

|x| {
  var result = f1(x)
  println("hello")
  return f2(result)
}

and

f1: andThen(io(|x|{println("got " + x)})): andThen(f2)

is an anonymous function equivalent to:

|x| {
  var result = f1(x)
  println("got " + result)
  return f2(result)
}

One last example with reading IO effect:

f1: andThen(io(|x| {
  println("Got " + x)
  return x + intValue(readln("Value to add? "))})
: andThen(f2)

is an anonymous function equivalent to:

|x| {
  var result = f1(x)
  println("Got " + x)
  result = result + intValue(readln("Value to add? "))
  return f2(result)
}

See also pipe and compose

is(ref, obj)

Curried identity comparison

`is(ref, obj) == obj is ref

Parameters are swapped to ease partialization, as in:

lst: filter(is(ref))

isEmpty(o)

Emptiness test.

Checks if the collection-like argument is empty.

isnt(ref, obj)

Curried difference comparison

`isnt(ref, obj) = obj isnt ref

Like is, this is more useful partialized. For instance:

lst: filter(`isnt(null))

le(a, b)

Curried swapped less than or equal.

le(a, b) == (a <= b)

Note: this function is swapped to make curried version more readable.

See also lt, ge, gt

lt(a, b)

Curried swapped less than.

lt(a, b) == b < a

lt(42) == |x| -> x < 42

Note: this function is swapped to make curried version more readable: lt(42) is a predicate testing if its argument is “less than 42”.

See also le, gt, ge

mod(a, b)

Curried modulo.

mod(a, b) == a % b

See also rmod

mul(x, y)

Curried multiplication.

mul(x, y) == x * y

See also div

ne(a, b)

Curried not equal.

ne(a, b) == (a != b)

See also eq

neg(x)

Opposite (negative value).

neg(x) == -x

Same as mul(-1)

not(a)

Polymorphic negation function.

E.g.

list[true, false, false]: map(^not) == list[false, true, true]

let even = |a| -> (a % 2) == 0
let odd = `not(even)

See also and, or

Null(_...)

null constant function.

odd(a)

Checks if the value is odd.

See also even

oftype(type, object)

Curried type checking

`oftype(type, obj) = obj oftype type

Partialized version can be used as a predicate, for instance in filter:

alist: filter(`oftype(String.class))

or(a)

Curried boolean or.

`or(a, b) == (a or b)

This implementation is lazy.

The arguments can be boolean expressions or predicate functions. If called with predicate functions, returns a new predicate function.

See also and, not, xor

orIfNull(fallback, value)

Null value substitution

`orIfNull(0, 3) == 3
`orIfNull(0, null) == 0

This function can be useful, for example, to replace null values in a list with a map:

list[1, 2, null, 3]:map(`orIfNull(0)) == list[1, 2, 0, 3]

pipe(funcs...)

Function chaining.

This is similar to Unix pipe:

pipe(f1, f2, f3)(x) == f3(f2(f1(x))))

i.e. apply f1 to x, then pass it to f2, and then f3. This is the same as f1: andThen(f2): andThen(f3)(x)

You can insert a side-effect only function in the chain using io:

pipe(f1, io({println("hello")}), f2)(42)

is equivalent to:

let tmp = f1(x)
println("hello")
f2(tmp)

This is similar to compose, but with functions order reversed.

Example:

let cmd = pipe(mul(2), add(4), ^toString, addTo("val: "))
cmd(19) == "val: 42"
let other = pipe(^intValue, add(4), mul(2))
other("17") == 42

If no function is given, returns id

For a similar construct that deal with errors, see for instance the gololang.Errors module

pow(a, b)

Curried power.

pow(a, 2) == a*a

Does an implicit conversion to double.

See also rpow

pred(x)

Number predecessor (side-effect free decrement).

pred(x) == x - 1

See also succ

rdiv(x, y)

Reverse curried division.

rdiv(y, x) == x / y

See also mul, div

recur(f)

Fixed-point combinator.

This is an abstraction of recursion.

rmod(a, b)

Reverse curried modulo.

rmod(a, b) == b % a

See also mod

rpow(a, b)

Reversed curried power.

rpow(2, a) == a*a

Does an implicit conversion to double.

See also pow

rsub(x, y)

Reversed curried subtract.

rsub(x, y) == y - x

See also sub

setitem(obj, i, v)

Curried indexed assignment

setitem(obj, i, v) == obj: set(i, v)

See also getitem, getter

snd(t)

Second element of a list, tuple, vector, array.

snd([a, b]) == b

spreader(f)

Convers a polyadic function into an unary function.

Similar to unary but using spread instead of invoke.

This function can also be used as a decorator.

See also varargs

str(o)

Converts its argument to a String.

sub(x, y)

Curried subtract.

sub(x, y) == x - y

See also add, rsub

succ(x)

Number successor (side-effect free increment).

succ(x) == x + 1

Equivalent to add(1)

See also pred

swap(v)

Polymorphic swapping.

This function dispatches on swapArgs, swapCurry or swapCouple according to its parameter.

Note that we have the property that given a binary function f and a couple c

unary(f)(swap(c)) == unary(swap(f))(c)

When applied to functions, equivalent to the C combinator.

swapArgs(func)

Change the signature of the given binary function by swapping its arguments, such that:

swapArgs(f)(b, a) == f(a, b)

Warning: when using this function with one previously wrapped in curry or uncurry, the resulting function can't be automatically partialized any more.

swapCouple(couple)

Swap the values of a couple.

The couple can be a tuple, a vector, a list or an array as long as its size is 2. The return value as the same type.

For example:

swap([a, b]) == [b, a]

swapCurry(func)

Change the signature of the given curried binary function by swapping its arguments, such that:

swapCurry(f)(a)(b) = f(b)(a)

True(_...)

true constant function.

unary(f)

Convers a polyadic function into an unary function. E.g.

let f = |a, b, c| -> a + b + c
let g = unary(f)

g([1, 2, 3]) == 6

If the function already takes zero or one argument, it is returned unchanged.

This can be useful in HOF, for example to map a binary function on a list of couple:

let f = |a, b| -> ...
list[["a", 1], ["b", 2], ["c", 3]]: map(unary(f))

results in list[f("a", 1), f("b", 2), f("c", 3)]

The resulting unary function will accept any object having a toArray method (array, tuple, collection, map entry, struct…)

Thus, unary(func)(arg) is equivalent to func: invoke(arg: toArray())

This function can also be used as a decorator.

See also spreader and varargs

uncurry(f)

Reverse of curry.

Take a curried function (e.g. |a| -> |b| -> a + b) and return a polyadic function (e.g. |a, b| -> a + b). It is actually a variadic function calling the curried one in sequence.

The two functions defined by

let f = curry(|a, b, c| -> a + b + c)
let g = uncurry(|a| -> |b| -> |c| -> a + b + c)

have the same behavior.

This function can also be used as a decorator.

See also curry

until(predicate, fun)

Apply the given function until the predicate holds.

For instance:

let f = until(gt(10), mul(2))
f(15) == 15
f(2) == 16
f(9) == 18

varargs(f)

Convert an unary function taking an array into a variadic function.

This is the contrary of unary. E.g.

let f = |t| -> t:get(0) + t:get(1) + t:get(2)
let g = varargs(f)

f([1, 2, 3]) == g(1, 2, 3)

This function can also be used as a decorator.

See also spreader and unary

xor(a, b)

Curried boolean xor.

xor(a, b) == (a or b) and not (a and b)

The arguments can be boolean expressions or predicate functions. If called with predicate functions, returns a new predicate function.

See also and, or