vector
vector, keyword
The vector keyword declares a user-defined vector function when it appears
after def.
‘def vector name«tables»(args) with’, vector function definition
A vector function binds table parameters between << and >>. Inside the
function body, expect table declares the tables and
dimensions required by the function. This declaration is optional for a
table parameter with no dimension requirements.
Unlike pure and process
functions, a vector function body may use table-prefixed vectors and may
aggregate from one declared table into another.
The result can be a scalar, a vector on a table parameter, or a tuple.
Returning a scalar does not require scalar-only inputs. Tuple components
are broadcast to a common table; for example, returning a scalar alongside
T.Value broadcasts the scalar to T.
To return a newly constructed table rather than values on existing tables,
use def table.
Examples
def vector daysAfterFirstSale<<Products, Sales>>(
Sales.Date : date) with
expect table Products[sku]
expect table Sales expect [sku]
Products.FirstSale = first(Sales.Date) sort Sales.Date
Sales.Age = Sales.Date - Products.FirstSale
return Sales.Age
table Products[sku] = with
[| as sku, as Label |]
[| "shirt", "Shirt" |]
[| "hat", "Hat" |]
table Sales = with
[| as ProductSku, as Date, as Qty |]
[| "shirt", date(2024, 1, 3), 2 |]
[| "shirt", date(2024, 1, 8), 1 |]
[| "hat", date(2024, 1, 5), 3 |]
keep where Sales.sku = Sales.ProductSku
Sales.DaysAfterFirst = daysAfterFirstSale<<Products, Sales>>(Sales.Date)
show table "Sales lines" with
Sales.ProductSku
Sales.Date
Sales.Qty
Sales.DaysAfterFirst
Scalar-only calls can use the vector-function pipeline and define local tables:
def vector innerSum(n : number) with
table Inner = extend.range(n)
return sum(Inner.N) when (Inner.N mod 2 == 0)
result = innerSum(6)
Table parameters can expose their primary dimension inside the vector function:
def vector shippedBefore<<Items, Orders>>(Orders.Qty : number) with
expect table Items[id]
expect table Orders expect [id]
Items.Total = sum(Orders.Qty)
return Items.Total
A scalar aggregation can be returned on its own or alongside a vector:
def vector totalQty<<T>>(T.Qty : number) with
return sum(T.Qty) into Scalar
def vector shares<<T>>(T.Qty : number) with
total = sum(T.Qty)
return (total, T.Qty / total)
table Orders = with
[| as Qty |]
[| 10 |]
[| 30 |]
total = totalQty<<Orders>>(Orders.Qty)
Orders.Total, Orders.Share = shares<<Orders>>(Orders.Qty)
show scalar "Total quantity" a1b1 with total
show table "Shares" a2d4 with
Orders.Qty
Orders.Total
Orders.Share
The scalar total is 40. The table contains (10, 40, 0.25) and
(30, 40, 0.75): the tuple’s scalar component is broadcast to each row.
Exporting a vector function
Vector functions can be exported from modules with export def vector.
An importing script can call them through the module alias or import their
name through a with block.
For example, the following module sums sales quantities per product:
// Module "/sample/sales-metrics"
export def vector totalQty<<Products, Sales>>(Sales.Qty : number) with
expect table Products[sku]
expect table Sales expect [sku]
Products.Total = sum(Sales.Qty)
return Products.Total
The importing script supplies its own tables and quantity vector:
import "/sample/sales-metrics" as Metrics
table Products[sku] = with
[| as sku |]
[| "shirt" |]
[| "hat" |]
table Sales = with
[| as Product, as Qty |]
[| "shirt", 2 |]
[| "shirt", 3 |]
[| "hat", 4 |]
keep where Sales.sku = Sales.Product
Products.Total = Metrics.totalQty<<Products, Sales>>(Sales.Qty)
show table "Totals" a1d3 with
sku
Products.Total
The table shows a total of 5 for “shirt” and 4 for “hat”.
Remarks
Filters inside the function have the same scope as in the calling script.
A vector initialized before a where block retains its initial values on
rows excluded by that block. Returning it after the block returns the full
vector, not just the selected rows. See the
filtered calculation example.
Vector functions must be declared at the top level, not inside another block. A vector function name cannot have multiple overloads.
Vector functions cannot be called inside each, autodiff, or montecarlo
blocks. This restriction concerns where the call appears, not which blocks
can be used within the function body.