Dex crash course
Dex is a strongly typed pure functional differentiable array processing language, designed with scientific computing and machine learning applications in mind. It is well-suited to statistical computing applications, and like JAX, can exploit a GPU if available.
Start a Dex REPL by entering dex repl
at your command prompt.
Immutability
Dex objects are immutable.
Immutable collections
Dex, like JAX, has arrays/tensors as its main data structure, which are referred to as tables, and these are immutable.
Dex has a strong static type system, including elements of dependent typing. Note how the length of an array (and in general, the dimensions of a tensor) is part of its type. This allows the detection of all kinds of dimension mismatch errors at compile time rather than runtime, and this is a very good thing! Notice that the type reflects the idea that conceptually, an array is essentially a function mapping from an index to a value.
We can't just directly index into a table with an integer, since this isn't safe - we might violate the table index bounds. We need to cast our integer to a typed index using the @
operator.
However, where things are unambiguous, we can use type inference.
It is relatively unusual to want to update a single element of a Dex table, but we can certaintly do it (immutably). Below we update the element with index 2 to be 9.0.
This syntax will gradually become clear.
Manipulating collections
We can map and reduce.
The main way of creating and transforming tables is using for
, which in Dex is more like a for-comprehension or for-expression in some languages than a traditional imperative for-loop. However, it is designed to allow the writing of index-based algorithms in a safe, pure functional way. For example, as an alternative to using map
we could write.
We can create a table of given length filled with the same element
or different elements
We can create 2d tables similarly.
Writing functions
We can write a log-factorial function as follows.
But this consumes heap. Dex, like JAX, is differentiable, so prohibits explicit recursion. However, it allows the creation of a mutable state variable that can be get and set via its algebraic effects system.
Note that for the final example, significant numerical error has accumulated in this naive sequential sum of 32 bit floats.
Curried functions
Note that we can curry functions as appropriate, using lambdas.