Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Foreword

Under Construction

Introduction

Welcome to The Calyxium Programming Language, an introductory book about Calyxium. The Calyxium programming language helps you write faster, reliable software. High-level ergonomics with purity, safety, and speed.

Who Calyxium is For

Calyxium is ideal for many people for a variety of reasons. Let’s look at a few of the most important groups.

Students

Calyxium is for students and those who are interested about learning functional programming concepts. Using Calyxium, many people have learned about topics like expression based languages, immutable variables and polymorphism. The community is very welcoming and happy to answer student questions. Through efforts such as this book, the Calyxium teams want to make functional concepts more accessible to more people, especially those new to programming.

who Is This Book For

This book assumes that you’ve written code in another programming language but doesn’t make any assumptions about which one. We’ve tried to make the material broadly accessible to those from a wide variety of programming backgrounds. We don’t spend a lot of time talking about what programming is or how to think about it. If you’re entirely new to programming, you would be better served by reading a book that specifically provides an introduction to programming. Don't feel threatened if you are new however, as it can be a good brain exercise, and you are also challenging yourself to do something new. Not a lot of people are doing that these days!

How to Use This Book

In general, this book assumes that you’re reading it in sequence from front to back. Later chapters build on concepts in earlier chapters, and earlier chapters might not delve into details on a particular topic but will revisit the topic in a later chapter.

You’ll find two kinds of chapters in this book: concept chapters and project chapters. In concept chapters, you’ll learn about an aspect of Calyxium. In project chapters, we’ll build small programs together, applying what you’ve learned so far. Chapters 2, 12, and 21 are project chapters; the rest are concept chapters.

Chapter 1 explains how to install Calyxium, how to write a “Hello, world!” program.

Chapter 2 is a hands-on introduction to writing a program in Calyxium, having you build up a number guessing game. Here we cover concepts at a high level, and later chapters will provide additional detail. If you want to get your hands dirty right away, Chapter 2 is the place for that.

Chapter 3 covers Calyxium's features that are similar to those of other programming languages. If you’re a particularly meticulous learner who prefers to learn every detail before moving on to the next, you might want to skip Chapter 2 and go straight to Chapter 3, returning to Chapter 2 when you’d like to work on a project applying the details you’ve learned.

Chapter 5 discusses classes, structs and methods, and Chapter 6 covers enums, match expressions, and the if then else control flow construct.

Finally, some appendixes contain useful information about the language in a more reference-like format. Appendix A covers Calyxium’s keywords, Appendix B covers Calyxium’s operators and symbols and Appendix C covers Calyxium's built-in functions.

There is no wrong way to read this book: if you want to skip ahead, go for it! You might have to jump back to earlier chapters if you experience any confusion. But do whatever works for you.

The website version also contains a handy search feature over   which you can use to search for Code Snippets in Appendix D or for anything else you can think of.

The Appendix

Under Construction

The following sections contain reference material you may find useful in your Calyxium journey.

Keywords

Operators

Functions

Snippets

Feel free to keep these tabs open in your browser as a reference you can alt + tab to quickly.

Appendix A: Keywords

The following list contains keywords that are reserved for current or future use by Calyxium. As such, they cannot be used as identifiers. Identifiers are names of functions, variables, parameters, structs fields, modules, types.

Keywords Currently in Use

The following is a list of keywords currently in use, with their functionality described.

  • rec - define a recursive function
  • if - branch based on the result of a conditional expression
  • then - fallback for if control flow constructs
  • else - fallback for then and if control flow constructs
  • let - bind a variable or function
  • match - match a value to patterns
  • with - branch based on the value of match
  • use - in a module path, refers to the modules root
  • mod - define a module
  • true - Boolean true literal
  • false - Boolean false literal
  • enum - define an enumeration
  • record - define a record
  • type - define a ADT
  • fn - define a anonymous functions, lambda abstraction

Deprecated keywords

Keywords Reserved for Future Use

The following keywords do not yet have any functionality but are reserved by Calyxium for potential future use.

  • class
  • extends
  • ref

Appendix B: Operators and Symbols

This appendix contains a glossary of Calyxium's syntax, including operators and other symbols that appear by themselves or in the context of paths, comments, tuples, brackets.

Operators

Table B-1 contains the operators in Calyxium, an example of how the operator would appear in context, a short explanation.

Table B-1: Operators

OperatorsExampleExplanation
notnot exprlogical complement.
!=expr != exprNonequality comparison.
==expr == exprEquality comparison.
>expr > exprGreater than comparison.
<expr < exprLess than comparison.
>=expr >= exprGreater than or equal to comparison.
<=expr <= exprLess than or equal to comparison.
&&expr && exprShort-circuiting logical AND.
+expr + exprArithmetic addition.
-expr - exprArithmetic subtraction.
-- exprArithmetic negation.
*expr * exprArithmetic multiplication.
/expr / exprArithmetic division.
%expr % exprArithmetic remainder.
**expr ** exprArithmetic power.
lslexpr lsl exprLeft-shift.
lsrexpr lsr exprRight-shift.
=var = exprAssignment.
+=var += exprArithmetic addition and assignment.
-=var -= exprArithmetic subtraction and assignment.
*=var *= exprArithmetic multiplication and assignment.
/=var /= exprArithmetic division and assignment.
&=var &= exprBitwise AND and assignment.
`=var `= exprBitwise OR and assignment.
$=var $= exprBitwise XOR and assignment.
<<=var <<= exprLeft-shift and assignment.
>>=var >>= exprRight-shift and assignment.
++var++, expr++Incrementation.
--var--, expr--Decrementation.
lorexpr lor exprBitwise OR.
lxorexpr lxor exprBitwise XOR.
lnotlnot exprBitwise NOT.
landexpr land exprBitwise AND.
->pat -> exprPart of match arm syntax.
|>var |> expr, expr |> exprPasses left-hand value as input to right-hand expression.
|| patPart of match arm syntax.
!!varDereference mutable copy.
^string ^ stringString concatenation.
@array @ arrayArray concatenation.
..1..10, 1..Range operator (inclusive).
?cond ? expr : exprPart of ternary conditional operator.
:var: type, cond ? expr : expr, array[start:end]Type ascription or ternary branch separator, or slice range separator.
;expr; exprExpression separator.
.object.fieldMember access.
_match x with | _ -> ...Wildcard pattern.
,(a, b)Comma separator (lists, tuples, args).
:=var := exprMutable copy assignment.

Table B-2 shows symbols that create comments.

Table B-2: Comments

SymbolExplanation
--Line comment
-- $Inner line doc comment

Table B-3 shows the contexts in which curly braces are used.

Table B-3: Curly Brackets

ContextExplanation
{...}Block expression

Table B-3 shows the contexts in which square brackets are used.

Table B-3: Square Brackets

ContextExplanation
[...]Array literal
expr[expr]Collection indexing. Overloadable (Index)

Appendix C: Built-in functions

This appendix contains a glossary of Calyxium's built-in functions.

Under Construction

Built-ins Currently in Use

The following is a list of built-ins currently in use, with their functionality described.

  • panic - immediately terminates the program and displays the given error message
  • print - prints to the terminal
  • to_float - converts integers to floats
  • to_int - converts floats to integers
  • to_bytes - converts strings to an array of bytes
  • length - returns the size of an array or string
  • input - displays the prompt and reads a line of text from standard input, returning it as a unit.
  • assert - fails if the boolean expression is false
  • head - returns the first element of an array
  • tail - returns a new array containing all elements except the first
  • reverse - returns a new array with elements in the opposite order

Built-ins Reserved for Future Use

The following built-ins do not yet have any functionality but are reserved by Calyxium for potential future use.

  • map - applies a function to each element of an array, returning a new array with the results
  • filter - returns a new array containing only the elements for which the function returns true
  • fold - reduces an array to a single value by applying a function cumulatively

Appendix D: Code Bytes

This appendix contains some commonly used snippet examples in Calyxium; designed to be searched by that search bar up    give it a try!

Under Construction

For loops

As you can see in Appendix A for loops have been discontinued and are no longer accessible. For those of you who are used to imperative programming this may seem like a shock; how am I supposed to loop things? You may ask, well its pretty simple. You use the rec keyword. Below is a template for loop and how to use it.

let rec iterator(index, max)  {
    if index < max then {
        print(index)
        iterator(index + 1, max)
    }
}

iterator(0, 9)

The following code will run print 10 times.
This is a very simple for loop style function but they can get much more complex giving you more control than the standard for keyword from other languages. Calling the iterator function starts the loop and you pass in index 0 and the max loop value.
Passing in the values like this is similar to for i in range(start, end) in Python.

While loops

You can do a similar thing for a while loop with the following code.

let rec iterator() {
    print("I'm a happy while loop!")
    iterator()
}

iterator()

Getting Started

Under Construction

Let's start your Calyxium journey! There’s a lot to learn, but every journey starts somewhere. In this chapter, we’ll discuss:

  • Installing Calyxium on Linux, macOS and Windows
  • Writing a program that prints Hello, world!

Feel free to keep the Appendix tab open in your browser.

Installation

The first step is to install Calyxium. We'll download Calyxium through calyxup, a command line tool for managing Calyxium versions and associated tools. You’ll need an internet connection for the download.

Note: if you prefer not to use calyxup for some reason, please see the Alternative Calyxium Installation Methods page for more options.

The following steps install the latest stable version of Calyxium, which is compatible with all of the book's examples. Some program outputs may vary from the book because Calyxium often improves error messages and warnings. In other words, any newer, stable version of Calyxium you install using these steps should work as expected with the content of this book.

Command Line Notation

Throughout the book, we’ll show some commands. Lines entered in the terminal all start with $ or >. You don’t need to type either character; it’s the command line prompt shown to indicate the start of each command. Lines that don’t start with $ typically show the output of the previous command. Unless stated otherwise, PowerShell-specific examples will use > rather than $.

Calyxium Installer

Currently Calyxup isn't finished so you are going to have to install the latest version semi manually from the downloads page

Installing Calyxium and calyxup on Windows, Linux and MacOS

PowerShell is required for calyxup you can find instructions on how to install PowerShell here

Open a PowerShell terminal and enter the following command:

> curl --proto '=https' --tlsv1.2 <add link> | pwsh -Command -

The command downloads a script and starts the installation of the calyxup tool, which installs the latest stable version of Calyxium. You might be prompted for your password.

TODO add install instructions when calyxup is done

Installing the calyxium-lang Extension

It is highly recommended to install the calyxium-lang extension by following the instructions here.

Useful Development Tools

This is a list of useful development tools

Formats

Extensions

Installing the calyxium-lang Extension

To enable syntax highlighting and LSP server support, it's recommended to install the calyxium-lang extension for your preferred text editor.

Visual Studio Code (VS Code)

Click this link to open VS Code to the extension page

Click install, you may be asked to restart VS Code.

Vim

Installation instructions coming soon.

Hello, world!

Now that you've installed Calyxium, it's time to write your first Calyxium program. It's traditional when learning a new language to write a little program that prints the text Hello, world! to the screen, so we’ll do the same here!

Creating a Project Directory

You'll start by making a directory to store your Calyxium code. It doesn't matter to Calyxium where your code lives, but for the exercises and projects in this book, we suggest making a projects directory in your home directory and keeping all your projects there.

Open a terminal and enter the following commands to make a projects directory and a directory for the “Hello, world!” project within the projects directory.

For Linux, macOS and PowerShell on Windows, enter this

$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world

For Windows CMD, enter this:

> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world

Writing and Running a Calyxium Program

Next, make a new source file and call it main.cx. Calyxium files always end with the .cx extension. If you’re using more than one word in your filename, the convention is to use an underscore to separate them. For example, use hello_world.cx rather than helloworld.cx.

Now open the main.cx file you just created and enter the code in listed below.

print("Hello, world!")

Save the file and go back to your terminal in the ~/projects/hello_world directory. Enter the following commands to run the file:

$ calyxium main.cx
Hello, world!

Regardless of your operating system, the string Hello, world! should print to the terminal.

If Hello, world! did print, congratulations! You’ve officially written a Calyxium program. That makes you a Calyxium programmer. Welcome to the club!

Let’s review this “Hello, world!” program in detail.

print("Hello, world!")

This line does all the work in this little program: it prints text to the screen. There are two important details to notice here.

  • print calls the function to display contents to your terminal.

  • You see the "Hello, world!" string. We pass this string as an argument to print, and the string is printed to the screen.

  • Unlike in Python, print does not automatically add a newline (\n) at the end. If you want a line break, you’ll need to include \n yourself.

Programming a Guessing Game

Under Construction

Common Programming Concepts

This chapter covers concepts that appear in almost every programming language and how they work in Calyxium. Many programming languages have much in common at their core. None of the concepts presented in this chapter are unique to Calyxium, but we’ll discuss them in the context of Calyxium and explain the conventions around using these concepts.

Specifically, you’ll learn about variables, basic types, functions, comments, and control flow. These foundations will be in every Calyxium program, and learning them early will give you a strong core to start from.

Keywords

The Calyxium language has a set of keywords that are reserved for use by the language only, much as in other languages. Keep in mind that you cannot use these words as names of variables or functions. Most of the keywords have special meanings, and you’ll be using them to do various tasks in your Calyxium programs; a few have no current functionality associated with them but have been reserved for functionality that might be added to Calyxium in the future. You can find a list of the keywords in Appendix A.

Variables and Mutability

By default, variables are immutable. This is one of the many nudges Calyxium gives you to write your code in a way that takes advantage of the safety that Calyxium offers. However, you still have the option to make your variables mutable. Let’s explore how and why Calyxium encourages you to favor immutability and why sometimes you might want to opt out.

When a variable is immutable, once a value is bound to a name, you can't change that value. To illustrate this, generate a new file called variables.cx in your projects directory.

Then, open variables.cx and add it's following code which won't interpret just yet:

Filename: variables.cx

let x = 10
x := 12

Save and run the program using calyxium variables.cx. You should receive an error message regarding an immutability error, as shown in this output:

This example shows how the interpreter helps you find errors in your programs. interpreter errors can be frustrating, but really they only mean your program isn’t safely doing what you want it to do yet; they do not mean that you’re not a good programmer! Experienced still get interpreter errors.

You received the error message: random `x` because mutable x doesn't exist yet add later.

Data Types

Under Construction

In calyxium there are 5 primitive data types

Int

This is an integer number (whole number) and is used to store numbers without decimals, it can be positive and negative. It ranges between LOWEST and HIGHEST. If you try to make it bigger or smaller than these ranges you will get unintended results.

For example 10 or -3000

To specify an int in code you can just type out the number.

Float

This is any number and is used to store numbers with decimals, it can be positive and negative. It ranges between LOWEST and HIGHEST. If you try to make it bigger or smaller than these ranges you will get unintended results. The term float refers to the fact that the decimal can "float" between positions. Its full name is Floating Point Number.

For example 10.009 or -3000.33

To specify a float in code you can add .0 to the end of the number.

One interesting property of floats is that the higher the number the less precise the number will be because there isn't enough room to store the digits after the decimal point.

Say a the max size of a float is 7 characters, when the numbers before the decimal are only 3 characters 200.457 you will have enough room for 3 more numbers, however if there are 5 characters 20000.1 you only have enough room for 1 number after the decimal making the number much less precise, and you can start to get artifacts in your computations. This is what causes graphical artifacts in games where the players position can become high enough to start allowing floating point precision problems.

String

This is a string (sequence) of chars and is used to store any word, phrase, paragraph you can think of! The term string comes from "stringing" a sequence of characters together. The longest string you can make is HIGHEST. Although some devices may not be able to display them, strings can hold any character you will come across; that is, if they are within the char size limit.

For example "Hello world!" or "جبن" or even "😎👍"

To specify a string in code you just surround anything you want to write with a " character

Byte

This is a single character and is want a string is composed of. Again, it can be any character you can think of. It can also be referred to as a char. The biggest character you can make is BYTES bytes. Once again, although some devices may not be able to display them, chars can be any character you will come across, as long as they are within the limit. If you try and put more than one character in a char you will get an error, so just make it a string if you are unsure.

For example 'ö' or 'ب' or even '😎'

To specify a byte in code you just surround a single character you want to write with a ' character

Bool

Short for boolean, this data type has 2 states true or false. Sort of like a yes or no.
By doing not my_boolean you can reverse a boolean. These are used to control the flow of a program. The name comes from English mathematician George Boole who developed Boolean algebra.
These are the least memory intensive only taking a single bit of storage.

To write a boolean simply write true or false.

How Functions Work

Under Construction

Comments

All programmers strive to make their code easy to understand, but sometimes extra explanation is warranted. In these cases, programmers leave comments in their source code that the interpreter will ignore but people reading the source code may find useful.

Here’s a simple comment:

-- hello, world

In Calyxium, the idiomatic comment style starts a comment with two dashes, and the comment continues until the end of the line. For comments that extend beyond a single line, you’ll need to include -- on each line, like this:

-- So we're doing something complicated here, long enough that we need
-- multiple lines of comments to do it! Whew! Hopefully, this comment will
-- explain what's going on.

Documentation Comments

Calyxium also supports a second kind of comment, documentation comments. These are used to provide structured, tool-readable documentation for your code, such as functions, constants, or modules.

Here’s a simple documentation comment:

-- $ hello, world i am a documentation comment $

In Calyxium, documentation comments follow the same syntax rules as normal comments, but with a special marker (-- $ ... $) to distinguish them. These comments are designed to integrate with your text editor to provide features like:

  • Hover tooltips

For example:

-- $ Returns the square of a number $
let square(x) {
    x * x
}

To enable documentation comment support in your editor, install the calyxium-lang Extension.

Control Flow

Under Construction

It's not a bug it's a feature

Under Construction

Alternative Installation methods

Note: It is highly recommend that you use calyxup. Standard Installation Method page.
This guide is not for the faint hearted. You have been warned!\

Building it yourself

This method may not always result in a successful install as the version of Calyxium on Github may have some compatibility issues; especially if you use the dev branch. It is recommend that you stay on the the main branch which has less updates but should remain compatible for all devices. Of course, because you are using a more up to date version of Calyxium that has not been publicly released yet there may be new breaking changes that have not yet been documented in the books. With that out of the way, lets start with cloning the repository:

Cloning the repository

The first thing you want to do to build calyxium yourself is to clone the repository

You will need some form of Git to clone the repository. See methods here

If you have Github Desktop installed you can go to the repository and click the Code Button, then press the Open with Github Desktop button and Github Desktop should open asking you if you would like to clone the repository, press the blue Clone button.


If you do not have Github Desktop but do have Git installed you can enter the following command into any terminal.

Make sure you are in the target parent directory of where you want the repository to be cloned.
This is normally located at %USERPROFILE%\Documents\Github\ for Windows users. To ensure the repository is cloned to that location enter this command into your terminal.

> git clone https://github.com/calyxium-lang/calyxium %USERPROFILE%\Documents\Github\calyxium

If you are not a Windows user or are already in the target parent directory run this command instead.

> git clone https://github.com/calyxium-lang/calyxium

Installing OCaml

Now that you have cloned the repository you will need to go through the process of installing OCaml onto your system.

You can download and install OCaml from the official site.

Installing Dune

Once you have installed OCaml you will need to install Dune using the following command.

$ opam install dune menhir

If you are having issues with opam, remember to activate the opam switch with the following command on cmd.

$ for /f "tokens=*" %i in ('opam env') do @%i

and for PowerShell use this command.

> (& opam env) -split '\r?\n' | ForEach-Object { Invoke-Expression $_ }

Please note that on Windows if you want to use the dune or calyxium commands you will need to run either of the above commands whenever you start a new terminal. opam should not require this. The book will assume you have ran the command above.

If you want to circumvent this you have 2 options, either add dune and calyxium to the system environment variables, or make a new terminal profile which automatically runs the command when opened. It is recommend to do the latter approach because you don't have to do this same process if you use other opam tools, you should also add calyxium to the system variables so its accessible to all terminal processes; calyxup would normally do this for you.

Adding to system variables

To add calyxium to the system environment variables run this command in PowerShell. This is assuming you cloned the repository to the recommended path.

For those curious USERPROFILE is just your C:\Users\NAME\ Folder, but it works for everybody, so no need to change anything!

> $target = "$env:USERPROFILE\Documents\GitHub\calyxium\_build\default\bin"; $old = [Environment]::GetEnvironmentVariable("Path", "User"); if (-not ($old -split ';' | ForEach-Object { $_.Trim() } | Where-Object { $_ -eq $target })) { [Environment]::SetEnvironmentVariable("Path", "$old;$target", "User") }

Creating terminal profile

To create a new terminal profile which automatically runs the command afore mentioned whenever opened begin by pressing Windows and then typing out terminal and pressing enter. This should open a new terminal. Now press the ^ button next to the + button. This should open a menu. Press the Settings button. Then down in the bottom left corner press the Open JSON file button. This should now open notepad. In here add the following JSON block in the list of profiles.

{
    "colorScheme": "CGA",
    "commandline": "cmd.exe /k for /f \"tokens=*\" %i in ('opam env') do @%i",
    "guid": "{f79c35ac-42f6-4755-82db-da7e34ac0399}",
    "hidden": false,
    "icon": "%USERPROFILE%\\Documents\\Apps\\ocaml-logo.png",
    "name": "OPAM",
    "startingDirectory": "%USERPROFILE%"
},

You can put it anywhere you like in the list to determine which order it shows up on the menu.

To give the terminal an icon like the rest you can download this picture.
This JSON specifies the logo to be located at Documents\Apps\ however you can put it wherever you like. You can also use a different icon if you wish. You can also use a different theme or even a different profile name, but keep the commandline the same.


Bonus tip

If you didn't know, in Windows Explorer you can click the directory bar, type cmd, and hit enter. This handy shortcut allows you to open a terminal right within the directory, so you don't have to cd to whichever folder you want to be in.

This bonus tip is going to show you how you can do this with this new profile you created with whatever keyword you want.


To do this make a new .bat file named what you want to type in to open this new profile terminal. For example opt (opam terminal) then enter the following code into the file and save it to where you want. In this instance we will use the directory where we put our icon earlier.

@echo off
setlocal
set "cwd=%cd%"
wt -p "OPAM" -d "%cwd%"

Alternatively with your new found shortcut abilities go into this directory in explorer and enter pwsh into the directory bar and hit enter. Now paste this code to generate the opt.bat script for you, and you can simply rename it after if you wish by hitting F2. Do not set the name to any pre existing command names or shortcuts as this will not work.

> Set-Content -Encoding ASCII opt-launch.bat "@echo off`nsetlocal`nset `"cwd=%cd%`"`nwt -p `"OPAM`" -d `"%cwd%`""; $s=(New-Object -ComObject WScript.Shell).CreateShortcut("$PWD\opt.lnk"); $s.TargetPath="$PWD\opt-launch.bat"; $s.WindowStyle=7; $s.Save()

After you've done this you can run the following script to add the path to your environmental variables. Again use PowerShell and note that this will assume you have put the .bat in the same directory as the .png icon.

> Set-Content -Encoding ASCII opt.bat "@echo off`nsetlocal`nset `"cwd=%cd%`"`nwt -p `"OPAM`" -d `"%cwd%`""

Now you can use the opt shortcut in Windows Explorer and on the start menu, that means you can press Windows and type opt press enter and it will also open the terminal profile. Neat!


Running Dune

Now that you've installed Dune and hopefully made a new terminal profile and completed the bonus tip we can opt into the %USERPROFILE%\Documents\GitHub\calyxium directory and run the following 2 commands in sequence.

$ dune build --profile release
$ dune install

Pretty self explanatory right? Thats it! You've completed this tutorial. You deserve a pat on the back! If you ever pull a new commit from the base repository, before you try and use Calyxium, run the following command to stop anything strange from happening (speaking from experience). Then run both commands again.

$ dune clean