Introducing the Clio programming language
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!
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
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
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
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 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 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
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 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
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
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 supports quick, in-flow, one-line functions to quickly transform data in a flow.
In-flow functions
When a quick one-line function isn’t enough, you can use in-flow functions instead.
Anonymous recursion
Clio also supports anonymous recursion using a special recall
variable, which refers to the current anonymous function.
Tensor programming
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 has a built-in range literal. Ranges are lazy in Clio, that way you can create infinite ranges easily.
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:
Now we can load this module in some other file and use it:
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 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
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 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!
📝 Read this story later in Journal.
🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >