What is Clio?

Clio is a pure functional lazy-evaluated programming language targeting decentralized and distributed systems. It is made to take advantage of multiple CPUs and CPU cores (parallelism) by default, to run on clusters and on the cloud easily.

Clio compiles to JavaScript. This makes Clio fast, easy to port and easy to extend. It gives Clio a free JIT compiler, a powerful VM and access to lots of existing libraries. It enables Clio to run in the browser and on servers, and anywhere JavaScript can run.

Why a new language?

A few months back I was working on a project that required a lot of remote calls and APIs to be implemented. For that project, I used a combination of Python, C, and JavaScript. While these languages can handle everything you will ever need to accomplish, they weren’t designed with today’s needs in mind. It just felt like the languages I mostly use aren’t suitable for doing what I had in mind.

A programming language is there to help solve a problem, but sometimes the programming language itself is a problem. A programmer should focus on solving the problem they’re trying to solve, not dealing with the problems caused by choosing a specific language.

I love programming language design, I’ve made a few toy languages and I’ve studied a lot of programming languages. So I decided to start writing a prototype of the language I had in mind, trying to target decentralized and distributed systems, a programming language for the cloud. After a few months, I was satisfied by the result, so I decided to turn it to a serious project from just a hobby project and I’m glad to publicly introduce it today.

Language syntax and features

Let’s quickly review the syntax and features of Clio together! I kept the following explanations short and to the point. I will write on more detailed and advanced topics in separate blog posts.

You can view all the code snippets presented in this blog post in their dedicated GitHub repository.

Classical hello world program!

Clio: Hello world!

In Clio, functions can be called only using the -> pipe operator. In the above example, we pass a string 'Hello world' to the print function.

Assignments

Clio: Defining variables

We use => operator for assignments in Clio, this can be used to update the value of a variable or define a new one. In the above example, we define a new variable name message and then pass it to the print function.

Chaining

Clio: Chaining function calls and assignments

We can chain as many pipes or assignment operators as we need. This is called a flow. Each flow starts with a set of data or a data source and continues with pipes and assignment operators. In the above example, we start with 'Hello world' as data, store it in a message variable, then pass it to upper , and then we get the result of this function call and put it in the MESSAGE variable, finally we pass the end result to the print function.

Mapping

Clio: Mapping a function to a list

We can use the ->* or -> * operator to map a function to our data. In the above example, we map the print function to our list of numbers.

Conditionals

Clio: Conditionals and indentation

Clio uses indentation for structuring the program and to define the program scopes. In the above example, we check if our number is bigger or smaller than zero, or maybe just zero, then we print an appropriate message.

Clio supports words. Words are strings that do not have any spaces or special characters in them. In the above example, #positive , #negative and #zero are words.

In-flow conditionals

Clio: In-flow conditionals

Clio supports using conditionals in flows. In the above example, we pipe our number directly to our conditional. When conditionals are used inside flows, they act like functions and will return the last evaluated expression. In the above example, our conditional returns zero which will be piped to the print function.

Argument position

Clio: Argument position

It is necessary to pass several arguments to a function or select the position of our arguments. In the above example, in each call, we pass two numbers and a string. Each flow has 42 and 56 as data. By default, our data will be passed as the first argument, unless we use the @ operator (which points to our data). If used alone, @ will refer to index 0 (or the first argument).

Transforms

Clio: Transforms

Clio supports transforms to transform an argument before passing it to a function. In the above example, we use a transform to double our argument and pass it to the print function.

Functions

Clio: Function definition

We use the fn keyword to define new functions. Each function should have at least one argument. Returns are implicit and there’s no need to use the return keyword, the last evaluated expression will be returned.

Laziness

Clio: Lazy and eager functions

Functions are lazy by default. They will not get executed unless their value is needed. But Clio provides a built-in @eager decorator to make a function non-lazy.

Quick functions

Clio: Quick functions

Clio supports quick, in-flow, one-line functions to quickly transform data in a flow.

In-flow functions

Clio: In-flow functions

When a quick one-line function isn’t enough, you can use in-flow functions instead.

Anonymous recursion

Clio: Anonymous recursion

Clio also supports anonymous recursion using a special recall variable, which refers to the current anonymous function.

Tensor programming

Clio: Mathematical operations on lists

In Clio, you can easily do mathematical operations on vectors, tensors and lists. These mathematical operations will be mapped to your vector, tensor or list.

Ranges

Clio: Lazy ranges

Clio has a built-in range literal. Ranges are lazy in Clio, that way you can create infinite ranges easily.

Multidimensional slicing

Clio: Multidimensional slicing

Clio supports multidimensional slicing. Each slicer can be either a number, a list or a range. If given a number, it will return the corresponding item with that index, if given a list of numbers it will return a list of items based on the provided indexes, and finally if given a range it will return all items with indexes in that range.

Modules

Clio supports defining and importing modules. Let’s put our fib function in a separate file and use it as a module:

Clio: Fibonacci module

Now we can load this module in some other file and use it:

Clio: Modules

Modules can be used on both server- and browser-sides. Clio can import .js and .clio files. The relative path of the file is used to import the module. Clio has built-in support for the Clio Virtual Environment which has an easy to use dependency management environment.

The Clio Virtual Environment is a solution similar to the Python Virtual Environment that also integrates some of the features of npm and its node_modules . With this feature, it’s possible to have different versions of the same library installed in the same project. That way it’s easier to manage dependencies.

Host

Clio: Host utility

Clio functions are isolated and the outer scope is frozen for them. This means they cannot change their outer environment and they will not see any changes in their outer environment. This makes it easy to host these functions and use them as microservices. Currently, the Clio host utility supports hosting functions, basic data types, and events.

I am currently implementing a protocol to allow hosting functions that are written in other languages (there’s a Python example here) or to import these microservices in other environments and languages.

Microservices

Clio: Microservices

You can import your hosted functions and use them just like any other function. These functions run on your server and report back the answer to your client. In the above example, we import the factorial function from our previous example.

Events

Clio: Events

Clio supports event-driven programming. In the above example, every time the time event of our emitter is triggered, it will cause the flow to rerun with the newly received data.

Project status

I’m actively working on and improving the Clio programming language. Built-ins, sets of features, syntax, and APIs aren’t stable and complete yet. I stopped adding new features to the language and I want to focus on fixing current bugs, writing some example programs and completing the documentation. At this stage, I would like to know what other people think of Clio, so feel free to leave me your opinion and suggestions in the comments below.

You can get more info about this language at its GitHub repository. There’s also an online playground if you don’t want to install the NPM package. If you’re interested in this language, it would be nice of you to give it a star on GitHub. I thank you in advance for your interest and support!