The Carp Programming Language
by Eric Shimizu Karbstein
This book is a working in progress, I will try to keep up-to-date with the language.
This version of the text assumes you're using the master branch of the language (In the future it will change to version 0.4).
Introdution
Welcome to The Carp Programming Language, an introductory book about Carp. Carp is a small programming language designed to work well for interactive and performance sensitive use cases like games, sound synthesis and visualizations. It uses a ownership system to achieve automatic and deterministic memory management similar of the Rust programming language.
Although it looks like a lisp, it is not. The runtime semantics are much closer to those of ML or Rust.
Who Carp Is For
TODO
Who This Book Is 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.
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 topic; we typically revisit the topic in a later chapter.
In most situations, we'll lead you to the correct version of any code that doesn't compile.
Getting Started
In this chapter we'll discuss 3 topics:
- Installing and setting the tooling of the language
- Writing a program that prints
Hello, World!
- How to use the compiler and the REPL
Installation
Note: This book assumes basic familiarity with the command line.
Important Note: Make sure that you have a C/C++ compiler installed, since Carp compiles to C and then it calls a C/C++ compiler to output a native binary.
Binaries
TODO: When 0.4 is released
Arch User Repository
If you use ArchLinux, you probably know what to do, but anyway for the early, still learning, users of the Linux distribution.
You will need the following:
- A internet connection
- Yay or any other AUR helper installed
Assuming you have yay
installed
$ yay -S carp-git
Then set in your shell configuration file an environment variable that tells the Carp compiler where to find the core library:
export CARP_DIR=/usr/lib/carp/
From Source
Since the language is in a early stages we'll teach how to install from the Carp Github source tree. For that you'll need:
Let's start!!
Cloning the repository:
git clone https://github.com/carp-lang/Carp
UNIX and UNIX-like
Building:
It may take a while. This will install the binaries inside $HOME/.local/bin
folder.
# Go to the Carp folder
$ cd Carp
# Build AND install command
$ stack install
Setting the core library:
# Putting in the appropriated place
$ mkdir ~/.local/lib/carp
$ cp -r core ~/.local/lib/carp
If your ~/.local/bin is not in the PATH, add it in your shell configuration file
export PATH=$PATH:~/.local/bin
Then you have to add a environment variable in your shell configuration file to tell where the core library is.
export CARP_DIR=~/.local/lib/carp/
Windows
TODO
Hello, World!
Now that you have Carp installed, lets start with the tradition of writing a
hello world program. It's a simple program that output in the terminal Hello, World!
and that is it.
Creating a Project Directory
Start by making a directory to store your Carp code. It doesn't matter where, but for this book exercises we do recommend to crate a directory in your home directory just to put all book projects.
For UNIX/UNIX-like:
$ mkdir ~/book_projects
$ cd ~/book_projects
$ mkdir hello_world
$ cd hello_world
For Windows:
> mkdir "%USERPROFILE%\book_projects"
> cd /d "%USERPROFILE%\book_projects"
> mkdir hello_world
> cd hello_world
Writing and Running a Carp Program
The next step is to create a new file called Main.carp.
Note that Carp files end with
.carp
. If you are using more than one word in your filename, write the first letter of each word as upper case, for example, use HelloWorld.carp instead of Helloworld.carp.
Now open the Main.carp file you just created and enter the code in Listing 1-1
(defn main []
(println* "Hello, World!"))
Save the file and go to the terminal window and enter the following command:
carp -x Main.carp
The -x
flag tells the compiler to compile and run the program.
Anatomy of a Carp Program
Let's understand what is going on this program.
(defn main []
)
Here we have tree things to look at. The first is the defn, it is a keyword that let us define a new function, it is followed by a function name, in this case it is main, then followed by the parameter list (the [] part), the list is empty because this function does not receive a parameter, if the parameter list was not empty it would have something inside the square brackets.
The main function is special, because it is the first part of the code that runs in every executable Carp program.
Inside of the main function we have:
(println* "Hello, World!")
This line prints text to the screen. There is some details in here:
The println* here is a Carp macro. Although it is something different than a
function, the call syntax is the same, you cannot tell the difference until you
look into the function/macro implementation. And everything between e double quotes ("
) is a string literal.
REPL and Compiler
The REPL
Let's start with the REPL, it stands for Read Eval Print Loop, it is a common feature in many languages and almost cultural in Lisp based languages, the way it works is quite simple, it reads the expression or statement given by the user, then evaluate it, print it's result and do it all over again. A REPL is great tool for testing and prototyping a idea direct from the terminal.
In Carp, you can start the REPL invoking the carp binary without parameters.
On UNIX/UNIX-Like:
$ carp
On Windows:
> carp
Inside the REPL, there is some special features that can be used and probably will be helpful when writing or debugging code.
Help: With no parameter, it displays the general help message, while giving a chapter name.
;; No parameter
(help)
;; With parameter
(help "language")
Type: It receive a symbol and it gives the type of that symbol
(def a 10)
(type a)
It should return:
a : Int
Because a is defined as 10 a Integer number.
Info: It receives a symbol and it gives the information about that symbol
(def a 10)
(info a)
In this example, it should return something like:
a : Int
Defined at line 1, column 1 in 'REPL'
Compiler
Note: Unless your project is a library, you project must have a main function.
Carp compiles to C and then call a C compiler to generate the binary. By default the generated files and binaries will be on a directory called out, but it can be changed in the project configuration.
Configuring the project
This part is quite simple, following the same pattern in the toplevel of the project:
(Project.config <setting> <value>)
To configure more than one setting, just keep adding the same pattern one more time in the next line.
Here is the setting options and what it takes as values:
"cflag"
: Takes a String: Add a flag to the C compiler."libflag"
: Takes a String: Add a library flag to the compiler."compiler"
: Takes a String: Set what compiler should be run with thebuild
command."title"
: Takes a String: Set the title of the current project (the final binary name will be this string)"prompt"
: Takes a String: Set the prompt in the REPL"search-path"
: Takes a String: Add a path where the Carp compiler will look for '*.carp' files"output-directory"
: Takes a String: Where to put build artifacts"docs-directory"
: Takes a String: Where to put generated docs"generate-only"
: Takes a Bool: Set to true if you don't want to run the C compiler when building"echo-c"
: Takes a Bool: When a form is defined using 'def' or 'defn' its C code will be printed"echo-compiler-cmd"
: Takes a Bool: When building the project the command for running the C compiler will be printed"print-ast"
: Takes a Bool: The 'info' command will print the AST for a binding
Compiler flags
-b
: Just compile the files-x
: Compile and run the files--optimize
: Compile the generated C file with-O3
optimization level--check
: Just check the files if they are valid Carp and report all errors--generate-only
: Only generate the C file.