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.
AssignmentsClio: Defining variablesWe 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.
ChainingClio: Chaining function calls and assignmentsWe 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.
MappingClio: Mapping a function to a listWe 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.
ConditionalsClio: Conditionals and indentationClio 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 conditionalsClio: In-flow conditionalsClio 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 positionClio: Argument positionIt 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).
TransformsClio: TransformsClio 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.
FunctionsClio: Function definitionWe use the fn keyword to define new functions.
Each function should have at least one argument.
Returns are explicit and there’s no need to use the return keyword, the last evaluated expression will be returned.
LazinessClio: Lazy and eager functionsFunctions 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 functionsClio: Quick functionsClio supports quick, in-flow, one-line functions to quickly transform data in a flow.
In-flow functionsClio: In-flow functionsWhen a quick one-line function isn’t enough, you can use in-flow functions instead.
Anonymous recursionClio: Anonymous recursionClio also supports anonymous recursion using a special recall variable, which refers to the current anonymous function.
Tensor programmingClio: Mathematical operations on listsIn Clio, you can easily do mathematical operations on vectors, tensors and lists.
These mathematical operations will be mapped to your vector, tensor or list.
RangesClio: Lazy rangesClio has a built-in range literal.
Ranges are lazy in Clio, that way you can create infinite ranges easily.
Multidimensional slicingClio: Multidimensional slicingClio 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.
ModulesClio supports defining and importing modules.
Let’s put our fib function in a separate file and use it as a module:Clio: Fibonacci moduleNow we can load this module in some other file and use it:Clio: ModulesModules can be used on both server- and browser-sides.
Clio can import .
js and .
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.
HostClio: Host utilityClio 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.
MicroservicesClio: MicroservicesYou 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.
EventsClio: EventsClio 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.
OverloadingClio: Function overloadingClio has support for function overloading.
You can use different versions of a function simply by using the if keyword.
Custom typesClio: Custom typesCustom types can be defined using the type keyword.
Each type has an init function that takes care of setting up the initial instance values.
MethodsClio: MethodsMethods can be defined for custom types using the of keyword.
When a function is defined like this, it will expect an instance of the provided type as its first argument.
Overloading MethodsClio: Overloading methodsJust like normal functions, you can combine the if and the of keywords to create overloaded versions of methods.
Project statusI’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!Clio logo.