def
The keyword def is used in Envision to introduce user-defined functions.
The function type can be pure, process, or vector.
‘def funtype funname (args) with’, function definition
User-defined functions can be introduced with def:
def pure helloWorld() with
return "Hello World!"
def pure myMax(x : number, y : number) with
if x > y
return x
else
return x + y
def pure swap(a : text, b : text) with
return (b, a) // wrapping '(..)' needed, indicates a tuple
show scalar "" with helloWorld() // Hello World!
show scalar "" with myMax(2, 17) // 17
a, b = swap("foo", "bar")
show summary "" with a /* bar */, b /* foo */
The return type is implicit, based on the returned values. Envision does not support expliciting the return type of user-defined function.
Functions must be declared before they are called. Recursion is not supported.
def pure factorial(a : number) with
if a <= 1
return 1
return a * factorial(a - 1) // WRONG! recursive call not allowed
Overloading is allowed when argument types differ, but standard library names cannot be overloaded.
Function bodies are scalar: arguments and returns are table-free values, and table prefixes are not allowed inside the function body. Passing vectors to a function call triggers automatic vectorization by the runtime.
User-defined functions use positional arguments only; labeled arguments are reserved for selected built-in functions.
In pure and process functions, arguments and scalar parameters are
read-only. Assigning to their names inside the function body is rejected.
Functions do not mutate their arguments or call options.
‘def vector funname«tables»(args) with’, vector function definition
A vector function declares its table parameters between << and >>. Inside
the body, expect table introduces those tables and the dimensions they
require. Unlike pure and process, the body can use table-prefixed vectors
and aggregate from one declared table into another.
def vector summarize<<P, S>>(S.Qty : number, S.Price : number) with
expect table P[id]
expect table S expect [id]
P.TotalQty = sum(S.Qty)
P.TotalAmount = sum(S.Qty * S.Price)
return (P.TotalQty, P.TotalAmount)
table Products[id] = with
[| as id, as Label |]
[| "shirt", "Shirt" |]
[| "hat", "Hat" |]
table Sales = with
[| as ProductId, as Qty, as Price |]
[| "shirt", 2, 25 |]
[| "shirt", 1, 25 |]
[| "hat", 3, 10 |]
keep where Sales.id = Sales.ProductId
Products.TotalQty, Products.TotalAmount =
summarize<<Products, Sales>>(Sales.Qty, Sales.Price)
show table "Products" with
Products.Label
Products.TotalQty
Products.TotalAmount
The returned
values must be vectors defined on one of the expected tables. Scalar
parameters, if needed, are declared after ;, like in def process.
Context capture
Function bodies cannot access variables from the surrounding script, except for const values defined above the function.
const scale = 1.2
def pure applyScale(x : number) with
return x * scale
show scalar "" with applyScale(10) // 12
Pure functions can only call other pure functions. Process functions can call both pure and process functions.