Gluon is a statically typed, functional programming language designed for application embedding.

After a bit of a longer time at next version soon stage, Gluon 0.8 is now released! This version contains numerous new features and bug fixes, bringing gluon ever so slightly closer to being usable!

As always, the full changelog for 0.8 (and all previous versions) can be found in the github repo.

Implicit arguments

let { ? } = import! std.list

let min l r : [Ord a] -> a -> a -> a =
    if l <= r then l else r

min 1 2 // 1
min (Cons "abc" Nil) None // None

Implicit arguments finally makes ad-hoc polymorphism possible. It completely replaces the limited (and rather hacky) implementation of overloading that were used before.

If you haven’t heard of implicits before then it can be good idea to think of it in terms of traits in Rust of type classes in Haskell as that is the most common use of implicit arguments. Where it differs is that conflicting “instances” are only an issue at a local level (as opposed to a program global level) which makes it possible to define, say Show Float in multiple ways and they will only conflict if and when they actually cause an ambiguity.

It’s not without its drawbacks though as this same flexibility also makes it more difficult to reason about what instance is actually used for a given implicit argument. For gluon, this drawback is a necessary evil however, as the ad-hoc module system already lends itself poorly to supporting a more rigid trait/class system so we might as well reap the benefits of implicits instead.

More documentation can be found in the Implicit arguments section of the book.

Reference documentation

/// Takes the first `n` elements of `xs`.
/// ```
/// let stream @ { take, repeat, empty, ? } = import!
/// let { assert } = import! std.test
/// assert (take 0 (repeat "abc") == empty)
/// assert (take 3 (repeat 1) == stream.of [1, 1, 1])
/// ```
let take n xs : Int -> Stream a -> Stream a = // ...

The example is lifted directly from the standard library and is tested automatically.

Gluon now supports documentation generation and publishes this to . While there is plenty of room for improvement in both the formatting and the documentation itself this should still be a helpful improvement for discoverability. Of course, this documentation is not limited to the standard library so if you want to generate documentation for your own code that can be done by running gluon doc <SOURCE> <TARGET> or by importing and using the gluon_doc crate directly from Rust.

Marshalling derive

#[derive(Getable, Pushable, VmType)]
#[gluon(vm_type = "examples.either.Either")]
enum Either<L, R> {

Thanks to @Laegluin’s awesome work in #541 and #546 gluon there is now a gluon_codegen crate which makes it possible to automatically derive the traits used to marshal data to and from gluon! As an example, the above derive on Either will generate the code necessary to let Either::Left(3) on the Rust side, be passed to a gluon function which expects Either Int a.

type Either l r = | Left l | Right r

// We can use `f` from Rust, caling normal Rust values of the `enum Either` type
let f e : Either Int a -> Int =
    match e with
    | Left l -> l
    | Right _ -> 0
{ f }

More documentation on this can be found in the marshalling chapter of the gluon book.

Language server improvements

The language server has seen several improvements as well to improve its stability and let it return completion in more places. For instance, record expressions now gets suggestions for the local bindings which can be used as fields (taking into account the fields that have already been written).

let abc = 123
let ab = "test"
let c = False
    // Suggestion will give `ab`

The signature help request of the Language Server Protocol were also implemented which makes it easier to visualize which type the argument under the cursor has.

Refactored the standard library

The std.prelude module is no longer the mishmash it previously was as all its functionality has been moved out into dedicated modules, letting the prelude only focus on documenting what all gluon code gets implicitly imported. Further refactoring of the standard library is still likely but most modules should now be focused enough that the functionality they contain are in the right module, it is just the module itself that may need to be moved or renamed.

What’s next?

For the next version I’d like to get some sort of “derive” functionality in place to remove tedium of writing Eq, Ord, Show, etc instances. With the attribute system in place this shouldn’t be to complicated at this point.

Building on “derive”, I’d also like to get JSON deserialization and serialization working (and possibly a more general serialization mechanism). Ideally this should have nice interop with serde though it still remains to be seen to what extent that is possible.

I will at least start on an effect system, primarily to replace the current IO monad. However, as it is a rather large addition I will probably not delay the next release for it.

And that’s all I have planned, any other changes will come as they are needed! Ideas, suggestions or bugs are very appreciated and can be reported on the issue tracker or at gitter.