-
Notifications
You must be signed in to change notification settings - Fork 0
Expressions in EK
There are not that many expressions in EK, but they are very powerful. This section will cover all of the expressions in EK.
There are two types of literals in EK: numbers and strings.
Integers are written as a sequence of digits. For example, 123 is an integer. You can also use a leading - to make the integer negative, like this: -123.
Floats are written as a sequence of digits, with a period in the middle. For example, 13.5 is a float. You can also use a leading - to make the float negative, like this: -5.0.
Strings are written as a sequence of characters surrounded by double quotes. For example, "Hello, world!" is a string.
You can also use escape sequences in strings. For example, \n is a newline, and \t is a tab. You can also use \ to escape a double quote, like this: \".
Calls are used to call functions. They are written according to the pattern of the function. For example, to call a prefix function f _, you can write f x. To call an infix function _ f _, you can write x f y. To call a postfix function _ f, you can write x f.
For functions with no arguments, you will just write the name of the function.
Arguments to a function work like functions with no arguments.
fn f (x) = x
Here, the body of the function is x, which calls the argument x. If the argument was marked as lazy, it could have side effects.
Lambda expressions are used to create functions, which may capture variables from the surrounding scope. They are written beginning with a \, followed by a list of argument names, followed by an =, followed by the body of the lambda function.
For example, the identity function can be written as \x = x. To call this function, you can then use the _ $ _ function defined in the std module.
import std
fn id = \x = x
fn main = print (id $ 1)
This will print 1.
Because lambdas are closures, they can capture variables from the surrounding scope. You can for example write a function that adds a constant to a number like this:
fn add (x) = \y = x + y
fn main = print (add 1 $ 2)
Partial application is used to create a new function from an existing function by applying only some of its arguments. It is written using the _ placeholder. For example, to create a function that adds 1 to a number, you can write:
fn inc = _ + 1
This will create a new function that takes one argument and adds 1 to it. You can then call it like this:
fn main = print (inc $ 1)
Placeholders can be used in any position in a function call. Note that the placeholder value creates a function, so it cannot be 'chain-called' like a normal function. For example, this is invalid:
fn f _ = 2 * _ + 1
This is because 2 * _ is a function, and the + 1 cannot be applied to it. Instead, you can write the following alternatives:
fn f _ = \x = 2 * x + 1
fn f (x) = 2 * x + 1
fn f _ = (_ + 1) . (2 * _)
The last one uses the composition operator _ . _, which is defined in the std module.
Type checks are used to check the type of a value. They are written using the is keyword, followed by the type to check for. For example, to check if a value is an integer, you can write value is int. Type checks can be used in if, like this:
fn main = if 1 is int then print "It's an integer!" else print "It's not an integer!"
Any type can be used in a type check, including user-defined types, and int ranges.
fn info (v) = if v is [0..] then "positive" else "negative"
More information about types can be found in the Types in EK section.
List expressions are used to create lists. They are written as a comma-separated list of values surrounded by square brackets. For example, [1, 2, 3] is a list of integers.
Lists can contain any type of value, including other lists. For example, [[1, 2], [3, 4]] is a list of lists of integers.
To use it, you have to import the list module.
import list
fn main = print [1, 2, 3]