Tables & Language Integrated Query


Given a record such as:

record Rec {
public int id;
public string name;
public int age;
public int score;

This record can be used with the table:

table<Rec> _records;

This table is a way of organizing information per given record type. In general, the table is a useful construct which enables many common operations found in data structures. The above record would create a table like


Diving Into Details#

A table in and of itself requires a toolkit to handle it, and we introduce a variant of SQL in the form a language integrated query (LINQ). It is a variant in many ways, and we will introduce the mechanics.

Reactive lists#

Lists of records can be filtered, ordered, sequenced, and limited via language integrated query (LINQ).


First, the iterate keyword will convert the table<Rec> into a list<Rec>.

public formula all_records = iterate _records;

Now, by itself, it will list the records in their canonical ordering (by id). It is important to note that the list is lazily constructed up until the time that it is materialized by a consumer, and this enables some query optimizations to happen on the fly.


We can suffix a LINQ expression with where to filter items.

public formula young_records = iterate _records where age < 18;


Yes, we can make things faster by indexing our tables. The index keyword within a record will indicate how tables should index the record.

public formula lucky_people = iterate _records where age == 42;

This will accelerate the performance of where expressions when expressions like age == 42 are detected via analysis.


The canonical ordering by id is not great for card games, so we can randomize the order of the list. Now, this will materialize the list.

public formula random_people = iterate _records shuffle;
public formula random_young_people = iterate _records where age < 18 shuffle;


Since the canonical ordering by id is the insertion/creation ordering, order allows you to reorder any list;


public formula people_by_age = iterate _records order by age asc;


public formula youngest_person = iterate _records order by age asc limit;

Bulk Assignments#

A novel aspect of a reactive list is bulk field assignment, and this allows us to do some nice things. Take the following definition of a Card table representing a deck of cards.

record Card {
public int id;
public int value;
public client owner;
public int ordering;
table<Card> deck;

We can shuffle the deck using shuffle and bulk assignment.

procedure shuffle() {
int ordering = 0;
(iterate deck shuffle).ordering = ordering++;

This assignment of ordering will memorize the results from shuffling. With a single statement, we can deal cards by assigning ownership.

procedure deal_cards(client who, int count) {
(iterate deck // look at the deck
where owner == @no_one // for each card that isn't own
order by ordering asc // follow the memoized ordering
limit count // deal only $count cards
).owner = who; // for each card, assign an owner to the card

This ability makes it simple to update a single field, but it also applies to method invocation as well.

Bulk method execution#

Bulk Deletes#