LiP students are expected to fork the repository and push solutions to the exercises on their fork.
Invitation to the Discord server: https://discord.gg/JKPWbpXBf4
Before diving into the course, let's take care of a few technicalities.
This set up process is quite involved and may seem overwhelming at first, but bear with it for now. It will pay off in the subsequent lessons. Arguably, the technologies we introduce here will very likely serve the purposes of other courses and even of your future projects.
The first thing to do is to fork this repository. Forking will create a new repository that shares the same files and history of this repository, except it's owned by you and you can freely edit it.
You can find the "Fork" action at the top right of the page, next to "Star" button. Select it, then keep the default options and hit "Create fork".
By now you should be reading this guide from your fork's webpage.
Important
The teachers and tutors will update the upstream repository with new content from time to time.
To reflect these changes to your fork, you have to synchronize your fork regularly.
The sync action is easily accessible from your fork's main page via the button:
or in the GitHub CLI via the command gh repo sync
.
Next, we'll configure your local OS for containerized development.
- If you're on Windows, install the WSL 2 back-end. Follow the official instructions.
- Install Docker Desktop.
- Lastly, install Visual Studio Code.
Skip this section if you don't use Windows.
-
Hit the keys
Win + S
and search for "WSL" or "Ubuntu". Clicking the first result should open a pitch-black window with white text on it.Read it carefully, and make sure you understand it as you go through the initialization procedure. It will eventually ask you to enter a username and a password for your account. Note these down.
Everytime you start WSL, you should be logged in to your user account. This is made clear by the shell prompt ending with a
$
sign. If something still isn't quite right, refer to this Microsoft Learn guide for a proper setup. -
On Docker Desktop, make sure WSL 2 integration is enabled. To do so, perform the actions shown in this gif:
From now on we will be working solely on the command line of a Linux shell. If you're on Windows, that means you're going to be typing commands within a WSL shell running Ubuntu. Otherwise, as a Linux or macOS user, you're going to be using your OS's native shell.
Many commercial Linux distributions, including the one shipped with WSL, already come with git
preinstalled, but it doesn't hurt to check:
git --version
If that command fails, then you must install git
for your distro. For Ubuntu and WSL it boils down to the two commands:
sudo apt update
sudo apt install git
Next, we want the GitHub CLI. The GitHub CLI is a useful tool to manage your online repositories from the comfort of the command line. We just need it to perform git
commands as an authenticated user.
To install the GitHub CLI, follow the installation instructions for Linux. Then check it's installed with:
gh --version
First, authenticate to your GitHub account from the GitHub CLI. Run:
gh auth login
and follow the on-screen procedure carefully.
Next, we need to let git
know about your GitHub profile.
Run the following commands, being sure to use the username and the email of your GitHub account.
git config --global user.name <YOUR-USERNAME>
git config --global user.email <[email protected]>
From now on git
will sign your commits with the given credentials and will act on the behalf of your GitHub account whenever you push to a remote repository, such as your fork.
Run the following command from your home folder, replacing YOUR-USERNAME
with your GitHub username:
git clone https://github.com/YOUR-USERNAME/lip
This downloads a local copy of your fork in a new directory called lip
.
We will now invoke VS Code's command-line interface code
to launch VS Code inside the lip
folder:
code lip
Briefly after the VS Code window shows up, you should see a notification like the one in the image:
Click on the blue button and wait for a while. If everything goes well, VS Code will have opened the repo's container set up for OCaml development.
Try it out the Dev Container by opening the integrated terminal (Ctrl + J
, then click on the "+" icon) and enter the command utop
. Play with some OCaml expressions, then exit utop
by pressing Ctrl + D
.
Congrats! You are now ready to write and test OCaml code.
Note
The Dev Container you've just opened transforms your VS Code into a fully integrated OCaml IDE. It comprises the OCaml Platform extension and an installation of the OCaml compiler enriched with many useful libraries. In particular, this installation includes:
- dune, a build system for OCaml projects, similar to make;
- utop, a REPL interface for OCaml;
- Menhir, a parser generator;
- ppx_inline_test, a tool for writing in-line tests in OCaml.
To check that everything is installed correctly, we set up a first project (see here for more detailed instructions).
Navigate to lip/basics
folder.
Then, create a new project called helloworld
using dune. Below, the lines starting with >
contain the expected output of the given shell commands:
dune init project helloworld
> Success: initialized project component named helloworld
This command creates a directory helloworld
with the following file structure:
helloworld/
├── dune-project
├── bin
│ └── dune
│ └── main.ml
├── lib
│ └── dune
├── test
│ ├── dune
│ └── helloworld.ml
└── helloworld.opam
To check that the OCaml installation was successful, try to build the project from the helloworld
directory:
cd helloworld
dune build
If there are no errors, the output should be empty. Run the project as follows:
dune exec helloworld
> Hello, World!
We will discuss the project structure in detail in the next exercise. For the moment, note that the _build
directory contains the output of the dune build
command. This includes the main.exe
executable inside the _build/default/bin/
subdirectory.
Note
In this very first project, all the source code is in ./bin/main.ml
. For more complex projects, we will mainly write our source code in the lib
directory.
We won't do much else in this first project, so let's see how to record our changes to the fork.
Assuming you're still under the basics/helloworld
directory, run the following command:
git add .
Let's break it down. We're invoking git
with two arguments. The first one, add
, is a git subcommand that lets you add new or modified files to the set of changes that should be recorded in the next commit (i.e. the index). The second argument, .
, stands for the current directory (basics/helloworld
).
Tip
The command git status
lets you review the changes you've staged for a commit.
If you wish to unstage a change from the index, invoke git restore --staged
on the changed files.
Next, we commit the contents of the helloworld
folder. A commit must be supplemented with a commit message describing the changes.
git commit -m "Create first dune project in basics/helloworld"
As before, commit
is a subcommand of git. It accepts an optional argument, introduced by -m
, that lets us specify the commit message as a string.
The changes are still stored on our local file system. To update the remote fork repository with your commit, issue the command:
git push
The dual action of pushing is pulling. You'll only need to pull some commits to your local fork when the teachers update the upstream repository and you have synced your fork as previously noted. The command to pull is, you guessed it:
git pull
This might not work if you have some pending changes not yet committed to your working tree. In this case you can temporarily store away the modified files with:
git stash
and restore them later on top of the newer commits using:
git stash apply
Tip
You can always append the --help
option to any of the above git subcommands to fully explore their functionality.
We've shown just a few basic git commands here. Refer to the Git Cheat Sheet for more important commands.
You made it to the end of Getting Started tutorial! You and your system should now be ready to take on the more theoretical stuff.
Here's a final diagram to help you understand the lab workflow.
Now proceed to refresh your OCaml knowledge with these warm-up exercises:
- A minimal language of boolean expressions
- Boolean expressions with not, and, or
- Typed arithmetic expressions with dynamic type checking
- Typed arithmetic expressions with static type checking
- OCaml Programming: Correct + Efficient + Beautiful
- OCaml from the very beginning
- B. Pierce. Types and Programming Languages. MIT Press, 2002