There are quite a few things we need to set up in order to work on the assignments and projects in this course. The purpose of this lab it to walk through the installation process.
Important. If you're running Windows, then you are required to Set up a WSL development environment. If you're an advanced Windows user (and a bit brave) you can try a native install, but we will not help you troubleshoot.
We host out course repository on GitHub. You'll need to host a private mirror of this repository, in which you'll include your solutions to assignments and projects. This means you'll need a GitHub account. We'll assume familiarity with Git; see the git tutorial if you need a refresher.
When we release any course material (e.g., lecture slides, starter code) it will be made available in the course repository, which you'll then be able to merge into your private mirror.
Create a GitHub account if you haven't already. You can use your personal GitHub account if you have one.
Note. Some students have in the past had issues with setting using a GitHub account attached to their BU email address, so I would generally recommend using a personal account.
cs320-spring-2025-private
. This repository must be private because it will contain your solutions to assignments and projects. If you've never created a repository on GitHub, follow the GitHub Docs tutorial on Creating a new repository.Mirror-push the course repository.
Open a terminal and cd
into the directory where you want to put your coursework for CS320, e.g., I would type something like:
cd ~/Developer/Repositories
Clone the course repository:
git clone https://github.com/BU-CS320/cs320-spring-2025.git
Mirror-push the course repository into your private repository:
git -C ./cs320-spring-2025 push --mirror https://github.com/USERNAME/cs320-spring-2025-private.git
replacing USERNAME
with your GitHub username.
Clone your private repository:
git clone https://github.com/USERNAME/cs320-spring-2025-private.git
Add the course repository as a remote for your private repository:
git -C ./cs320-spring-2025-private remote add upstream https://github.com/USERNAME/cs320-spring-2025-private.git
Remove the clone of the course repository:
rm -rf cs320-spring-2025
At this point you should have a directory called cs320-spring-2025-private
, in which you'll put your solutions to assignments and projects.
The import of the above setup is that, when materials are added to the course repository, you can easily merge them into your private repository. You should get in the habit of doing this frequently.
cd
to the directory for your private repository. Make sure to first commit any uncommitted changes. Then run the following commands.
git fetch upstream
git merge upstream/main main
git push
This will merge the updates to the course repository into your private repository both locally and on GitHub. You should almost never need to resolve a merge after doing this, but if you do, take a look at the GitHub Docs instructions on Addressing merge conflicts for a refresher on how to do this.
Next you need to set up your machine to be able to compile and run OCaml programs.
Install opam. opam is a package manager for OCaml. Follow the opam documentation instructions on How to install opam for your OS. In short, use one of the following commands:
# Homebrew (macOS)
brew install opam
# MacPort (macOS)
port install opam
# Ubuntu
apt install opam
# Debian
apt-get install opam
# Arch Linux
pacman -S opam
and follow the associated instructions, e.g., make sure to run
opam init
after opam is installed.
Create a switch. A switch keeps track of a particular set of packages you've installed. We'll make a global switch intended to be used for this course.
opam switch create cs320-s25 5.2.1
opam switch cs320-s25
eval $(opam env)
Note. You'll need to run eval $(opam env)
every time you open a fresh terminal.
Install the packages for this course. You can ignore all the warnings associated with installing the course standard library. We include documentation for this library on the course webpage. We'll grade most assignments under the assumption that you only have access to this library.
opam update
opam install dune utop ounit2 menhir ocaml-lsp-server
opam install stdlib320/.
If you plan on using VSCode, you should also install the OCaml Platform from the Visual Studio Marketplace. The link in the previous sentence includes instructions on how to use OCaml with VSCode.
Note. Setting up VSCode is optional. We will, for example, not always use VSCode in live-coding demos. We'll do our best to troubleshoot any issues you run into, but it won't be a priority.
Once everything is set up, working on an assignment will go roughly as follows.
eval $(opam env)
.Fill in your solutions, make sure to commit your changes frequently.
Note. You'll often have to create your own files which satisfy the specification of the assignment. You can verify that you've set everything up correctly if dune build
doesn't show any errors when run in assigns/assignX
.
From within the assignment lib
directory, run dune build
frequently to check your code.
Note. Per the instructions on using OCaml on VSCode, you can also use
dune build --watch --terminal-persistence=clear-on-rebuild
to rebuild every time you make a change to a file. You may want to have this going in the built-in terminal of VSCode as you work.
When you get close to completing the assignment, from within the assignment directory, run dune test
to test your code against a small test suite we've provided. This collection of tests will include some (but not all) tests used for grading.
Note. The tests come in the form of assertions. This means that if you fail an assertion, the following assertions will not be tested. If you can comment out assertions in order to avoid testing them.
tests/test_assignX.ml
.Dune is a build tool for OCaml which we'll be using for the entirety of this course. To finish off the lab, we'll create a simple project using dune. This will primarily be in order to verify that everything is set up correctly.
Initialize a project. Open up a terminal and cd
to a place where you want to create a dummy project. Then run
eval $(opam env)
dune init project hello_dune
This will create a directory called hello_dune
, a skeleton project with the following file structure:
.
├── bin
│ ├── dune
│ └── main.ml
├── dune-project
├── hello_dune.opam
├── lib
│ └── dune
└── test
├── dune
└── test_hello_dune.ml
You can ignore most of these files for now. We'll only update the file bin/main.ml
.
Verify things work. cd
into the project you just made and run:
dune build
You should see no output (you may see a progress bar). Building a project verifies that there are no type errors in your code.
Next, run:
dune clean
Building a project creates a lot of auxiliary files, and dune clean
just deletes them all.
Tip. If you find that your project is not building and you think it should, run dune clean
and then dune build
again, particularly if you change a dune
file or the dune-project
file (we'll talk more about this later).
Write a program. Open the file bin/main.ml
in your favorite editor. You should see the following:
let () = print_endline "Hello, World!"
Like with Python, there is no special "main" function for OCaml. Everything in main.ml
(or any file that you've told dune is executable) is run.
Replace the contents of bin/main.ml
with
let hello_message = "TODO"
let () = print_endline hello_message
making TODO
into a phrase of your choosing. Here we are making the message printed by the program into a variable. Finally, go back to the terminal and type:
dune exec hello_dune
You should see the message that you put in your program.
Use Utop. Utop is an interface for OCaml's toplevel, like Python's REPL. It's a standalone program, you can type in your terminal:
utop
and from there you can type in any OCaml expression followed by two semicolons ;;
, which Utop will evaluate, e.g.:
utop # 2 + 2;;
- : int = 4
When you're done, type #quit
to leave Utop.
It's will be more common for us to use Utop via Dune so that it runs in a project aware way. Let's start by creating a file called lib/hello_dune.ml
and in it write the line:
let welcome = "TODO"
replacing TODO
with a welcome message of your choosing. Then in your terminal (within the directory hello_dune
) type:
dune utop
This will open Utop, but it will also make available any code that you've written in the lib
directory. You can type:
Hello_dune.welcome;;
within Utop, and Utop will evaluate it to be the message you wrote. Note the capital 'H' here. Hello_dune
is a module which is defined in the file lib/hello_dune.ml
and in which the value welcome
is defined.
The last thing we'll do is use this value in our executable program. Go back to bin/main.ml
and replace its content with:
let () = print_endline Hello_dune.welcome
The point: the code in bin/main.ml
can refer to the Hello_dune
module. This is how most of our dune projects will be structured; we'll put library code in the lib
directory and executable code in the bin
directory (hence, the names).
And that's it for now, you've created a dune project. For most assignments, the dune project will be given to you. As we get further into the course, we'll look at more of the files that were generated above.