Intrinsics
This page will cover how you can contribute new intrinsic libraries or globals to Cosmo.
Last updated
This page will cover how you can contribute new intrinsic libraries or globals to Cosmo.
Last updated
First, let me define what I mean when I say "intrinsic". I am referring to anything that is available to Cosmo without having to install a package. For example: the puts
and gets
functions are global intrinsics, and the HTTP
and System
libraries are imported intrinsics.
If you want to write any code in Cosmo that will be intrinsic to Cosmo, just create a new Cosmo file in and code away. Each file in libraries/
becomes an importable, except for global.⭐
, which is injected into the global scope. When creating an importable intrinsic in Cosmo, the name to import will be the file name without the extension. For example: if I created libraries/colors.⭐
, it would be importable via colors
.
If you want to define Cosmo intrinsics that rely on Crystal to run (or are performance intensive), you can refer to . There are two types of intrinsics you can create via Cosmo's Crystal API: s, and s.
A Lib
is just a table behind the scenes, and holds associated IFunction
s or other values. It contains an inject
method which assigns any associated values into the scope.
As you can see, it defines a hash called file
and assigns all of the File
library's functions into it. It then assigns the file
hash to the name File
in the scope.
An IFunction
is just a regular function, just without a body node. They are called like normal functions, besides having to interpret the function body. Arity checks are done just like normal functions as well. The below example of an IFunction
(taken from Math::atan
) has an arity of 1, meaning that it will throw if any more or any less arguments are provided. It also uses the method to make sure the input is a float or an integer.
Intrinsics written in Cosmo are not importable OR in the global scope by default. To finally implement your intrinsic, navigate to the method. Each call to declare_intrinsic
declares it as global. To make it importable, call the importable
method. The first argument to the importable
method is the name that it will be importable by. So for example, importing MathLib
would look like: