"new" functions

new and list-new

The function for creating a new value is usually called new or list-new, and there is a special syntax for calling these functions.

main void() # Same as 'new 1, 2, 3' tuple (nat, nat, nat) = 1, 2, 3 log tuple # Same as 'list-new (1, 2, 3)' array nat[] = 1, 2, 3 log array

The syntax 1, 2, 3 may call either:

  • A new function taking those arguments, making it equivalent to new 1, 2, 3
  • A list-new function taking with an array containg 1, 2, 3

new is for functions that expect a fixed number of arguments.
list-new is for functions that take a variable number of arguments.

1, 2, 3 is a call expression. Keen will build the initial overload set using all functions named new or list-new, then go through the same logic described in Overloading.

foo 1, 2 and foo (1, 2) are two different expressions.
The former just calls foo. The latter calls new first, then foo on the result.

main void() log foo (1, 2) log foo 1, 2 foo nat(tuple (nat, nat)) tuple.a + tuple.b foo nat(a nat, b nat) a * b

More "new" syntax

Single-argument new

To call new with a single argument, end with a trailing comma.

main void() xs nat[] = 1, log xs

Empty new

To call new with no arguments, write ().

main void() xs nat[] = () log xs

Implicit empty new

In many contexts fn-new with no arguments will be called implicitly.

main void() xs nat[] = if false 1, 2 log xs

Defining a "new" function

new functions are just ordinary functions and are declared in the usual way.

main void() log (1, "hello", true)::nat new nat(a nat, b string, c bool) a + b.size + c.to

Defining a "list-new" function

list-new functions are also just ordinary functions.

main void() log (1, 2, 3)::string list-new string(values nat[]) to-json values

Keen generates an array from all the arguments before calling list-new.

Multi-line new

There is an equivalent syntax for calling new or list-new:

main void() xs nat[] = - 1 - 2 - 3 log xs

This behaves the same as 1, 2, 3, just with a multi-line syntax to make it convenient for bigger calls.

The extra indentation is not needed when it is the return value of a function:

main void() log xs xs nat[]() - 1 - 2 - 3

Multi-line new with arrays

Using -- instead of - concatenates all the elements of an array into the array passed to list-new.

main void() xs nat[] = 2, 3 log :: nat[] - 1 -- xs - 4

This can be used to conditionally include elements in an array.

main void() log :: nat[] -- if true - 1 -- if false - 2 - 3

Named-new

The syntax x: 1, y: 2 calls either:

  • A new function with parameters named x and y.
  • A named-new function taking an array of names and an array of values.

Keen will build the initial overload set with both kinds of function, then filter using the logic described in Overloading.

main void() # This calls 'named-new' a json = x: 1, y: 2 log a

This has a multi-line form which is usually preferred.

main void() log a a json() x: 1 y: 2

To demonstrate with a custom new:

main void() log (x: 1, y: 2)::nat new nat(x nat, y nat) x + y

To demonstrate with a custom named-new:

main void() log (x: 1, y: 2)::string named-new string(names symbol[], values nat[]) names.to-json ~~ values.to-json