module Pure {
// PURE FUNCTIONS
// A function is considered "pure" if all of the following are true:
// • it does not call any impure functions, other than those passed to it
// • it is not a closure
// • it does not use thread local variables
//
// Note that a function may be pure even if it accesses mutable types
// or has mutable types in it's signature.
//
// The compiler automatically classifies function implementations as
// pure or impure based on their implementation.
//
// Generic functions are evaluated at to their purity based on the
// specific types involved.
//
// External functions are considered impure by default but can be annotated
// with pure if the implementation meets the requirements.
//
// Function types are considered impure by default, but may be modified
// with the pure keyword. A cast to a pure function type will fail
// if the function is not pure.
// define a row structure
struct Row {
values: string[];
}
// define a query function for rows where the implementation must be pure
typedef QueryFn = pure fn(rows : Row[]) : Row[];
// implement a query function that is pure
fn simple_query_fn(rows : Row[]) : Row[] => {
let new_rows : mut Row[] = [];
for (row in rows) {
if (new_rows.values[0] == "keep") {
new_rows.append(row);
}
}
return new_rows.take(); // convert mutable to immutable
}
fn test1() {
// cast query function to function type
let q = simple_query_fn::QueryFn; // ok: function meets pure requirements
}
// PURE INTERFACES
// Interfaces are considered impure by default, but can be annotated with
// pure to indicate that all methods must be pure.
// define an query interface that works on rows
pure interface Query {
query(rows : Row[]) : Row[];
}
// define a simple query struct
struct SimpleQuery {
value: string;
}
impl Query {
query(this : SimpleQuery, rows : Row[]) : Row[] => {
let new_rows : mut Row[] = [];
for (row in rows) {
if (new_rows.values[0] == this.value) {
new_rows.append(row);
}
}
return new_rows.take(); // convert mutable to immutable
}
}
fn test2() {
// cast SimpleQuery to Query interaface
let q = SimpleQuery::Query; // ok: implementation meets requirements
}
}