Highly, terribly dangerous posts. Misuse of this profile can invite eggbug to trounce upon your data and then laugh in your face. You don't want this profile. Really.



So, I'm currently implementing polymorphic variants for Polaris. These are roughly the sum-type equivalent of row polymorphic records, i.e.

[ `A(5), `B("a") ]

has type

List(< A(Int), B(String) | r0 >)

Here r0 is a unification variable, which means that, depending on the choice of r0 this could be a type that contains the given constructors for A and B, one that additionally contains a constructor C(Bool), or any other variant type, as long as it contains constructors for A and B.

Most of this is relatively straight forward, but I'm really not sure how to deal with pattern matching. The issue here is that there are two ways to pattern match on a polymorphic variant



I'm going to write a longer, more detailed blog post about Polaris once it is ready, but I would like to share (and possibly get some feedback on) its package system first.

Something very important to keep in mind for this is that Polaris is not an ordinary programming language!

Polaris is a scripting language, but not in the sense that it has a weak dynamic type system and terrible performance (well, the performance is pretty terrible at the moment :) ).

Polaris is meant to replace shell scripts with a language with an awesome, heavily inferred static type system and a bunch of built-in features to make shell scripting slightly less painful (e.g. language support for command line arguments, running other programs, accessing environment variables, etc.)

Concretely for this post, this means that having a vanilla package manager and build system is simply not an option! The polaris executable is statically linked and only a few megabytes, so running a script should ideally only consist of possibly downloading this executable and then, well, running the script.

I've always really liked the imports in Dhall, but because Polaris scripts are allowed to execute arbitrary side effects, I cannot (well, should not) just copy them directly.

Instead, https imports need a content hash, to make sure that you download what you expect.

module SomeModule = import("https://someurl/somefile.pls", "87d4b6bc7c425cffa7384f73638c75f10ec5ef4a8fe53ad7777a84ed7f1fb737")

This way, if the file at this URL ever changes, your script will crash with an error message instead of running !rm "-rf" "/".

So, HTTPS imports are quite nice, but this still has a problem: How does a module import another module from the same repository?

If we didn't care about https imports, we could just import the file directly

module OtherModule = import("othermodule.pls")

but this is going to break if the other file is imported over HTTPS, since naively, this would try to import othermodule.pls from the filesystem and associating "the file relative to the current one" with its URL is not necessarily possible (if it is even public at all). Moreover, exposing files over HTTPS would be pretty awkward with this since all files would need to be downloadable separately.

Polaris takes a slightly different approach. Instead of downloading individual files, polaris borrows a concept from Java: JAR files!

Instead of running a file directly, Polaris has the option to resolve all imports and package them into a self contained package called a star.

These stars are essentially zip files that contain the entire polaris code, including every single local file dependency. In the future, I might even add the ability to import other files (executables, config files, etc.) to these, so that they are truly self contained.

Now, when importing a module from a star or running a star as a script, all local file imports are resolved inside the star! This means that in the example above, the repository just needs to expose a star containing both files and othermodule.pls will be resolved correctly from its relative import path.

Stars can even (optionally) contain pre-downloaded HTTPS dependencies (and even the polaris executable itself!), so that they can be run without internet access or any system dependencies.

I haven't implemented any of this yet, but I quite like the approach!