Skip to main content

Raven's Data Model

Tagged Tuples

Some object-oriented languages say that everything is an object, including basic types like integers and strings. In Raven, everything is a tagged tuple.

The basic built-in function for constructing tuples is called data, and it accepts a heterogeneous list of tuple elements.

xs = data(5, "foo", [])

println(part(xs, 0)) # => 5
println(part(xs, 1)) # => foo

We can index this tuple with the built-in part function, which is zero-indexed.

Conventionally, the first part of the tuple is a symbol, written like `Foo`. This first element is called the tag; tag(x) == part(x, 0).

xs = data(`Foo`, 2, 3)
println(tag(xs)) # => `Foo`

You'll notice that if we change the tag to Complex, the tuple prints as if it were a complex number.

println(data(Complex, 2, 3)) # => Complex(2, 3)

That's because it is a complex number. Conversely, a complex number is just a tuple with the tag `Complex`, followed by two scalars.

So everything in Raven is a data(...) tuple like this, with the tag describing what the tuple contains. Functions, including print, will check the tag to decide what to do. Even basic types like integers are (conceptually) tuples:

println(tag(1))         # => `Int64`
println(tag(1.5)) # => `Float64`
println(part(1.5, 1)) # => 1.5
println(data(Int64, 1)) # => 1

Certain built-in types contain themselves, so it's tuples all the way down. data(Int64, 1) is identical to 1.

Although somewhat unusual, this model is quite similar to Mathematica's "everything is an expression" (with Raven's "tag" as Mathematica's "head"), or TypeScript's design patterns for ADTs.

data, part and nparts are Raven's core primitives; almost all of the language is built on them. (Though for practical reasons, eg JS interop, they are not Raven's only primitives.)

Algebraic Data Types

Raven allows for definitions like

data LinkedList[T] {
Empty()
Prepend(x: T, xs: LinkedList[T])
}

which are reminiscent of ADTs in, say, Haskell. But Raven doesn't have any built-in notion of ADTs. Instead, data {} is simply a macro which creates a set of convenience functions using the tagged-tuple primitives described above.

caution

Work in progress