Getting Set-up
Table of Contents
There are several things you need to set up in order to work on the assignments and projects in this course. The purpose of this document is to walk you through this process.
Important. If you're running Windows, then you are required to Set up a WSL development environment. If you're an Windows superuser you can try a native install, but we will not help you troubleshoot.
1. Course Repository
We host the 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.
1.1. Mirroring the Course Repository
- Create a GitHub account if you haven't already. You can use your personal GitHub account if you have one. Note: Some students have had issues setting using GitHub accounts with their BU email addresses, so I would generally recommend using a personal account.
- Create a personal access token. This collection of instructions assumes that you're using Git with HTTPS authentication. If you want to use SSH then you can skip this step, but we will not help you troubleshoot. Follow the GitHub Docs instructions on Creating a personal access token.
- Create a private repository on GitHub called
cs320-s26-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
cdinto the directory where you want to put your coursework for CS320, e.g., I would type something like:cd ~/Developer/RepositoriesClone the course repository:
git clone https://github.com/BU-CS320/cs320-s26.git
Mirror-push the course repository into your private repository:
git -C ./cs320-s26 push --mirror https://github.com/USERNAME/cs320-s26-private.git
replacing
USERNAMEwith your GitHub username.Clone your private repository:
git clone https://github.com/USERNAME/cs320-s26-private.git
Add the course repository as a remote for your private repository:
git -C ./cs320-s26-private remote add upstream https://github.com/BU-CS320/cs320-s26.git
Remove the clone of the course repository:
rm -rf cs320-s26
At this point you should have a directory called cs320-s26-private,
in which you'll put your solutions to assignments and projects.
1.2. Syncing with the Course Repository
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. You should 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 conflict 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.
2. OCaml
Next you need to set up your machine to be able to compile and run OCaml programs.
2.1. Installing Packages
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 # MacPorts (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-s26 5.2.1 opam switch cs320-s26 eval $(opam env)Note: Depending on the choices you made when installing opam, you may need to run
eval $(opam env)every time you open a fresh terminal.Clone the course standard library. In the same place you put
cs320-s26-private, run the following command:git clone https://github.com/nmmull/stdlib320.git
You should now have a directory with
cs320-s26-privateandstdlib320as subdirectories. There is documentation for this library linked on the course webpage. We'll grade most assignments under the assumption that you only have access to this library.Install the packages for this course. Run the following commands in the directory where your
cs320-s26-privateandstdlib320live. You can ignore any warnings associated with installing the course standard library.opam update opam install dune utop ounit2 menhir ocaml-lsp-server opam install stdlib320/.
2.2. Setting up VSCode (Optional)
If you plan on using VSCode, you should also install the OCaml Platform from the Visual Studio Marketplace. Note: Setting up VSCode is optional. We won't 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.
3. Assignment Workflow
Once everything is set up, working on an assignment will go roughly as follows.
- Sync with the course repository to get access to the assignment (see the instructions above).
- Sync the environment with the course switch
eval $(opam env)if necessary. - Fill in your solutions, make sure to commit your changes frequently.
- From within the assignment
libdirectory, rundune buildfrequently to check your code. - When you get close to completing the assignment, from within the
assignment directory, run
dune testto 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 for now come in the form of assertions. This means that if you fail an assertion, the following assertions will not be tested. You can comment out assertions in order to avoid testing them. - (Optional) Add your own assertions to the file
tests/test_assignX.ml. - Push your work to your private repository and submit your assignment. In Gradescope, you'll be prompted to choose a repository and a commit to submit. After submitting, you should see a message which says that your assignment was accepted along with information about some (but not all) of the tests that were run.
4. Dune
Dune is a build tool for OCaml which we'll be using for the entirety of this course. All assignments and projects in this course are given as dune projects. The file structure of a dune project (e.g., of assignment 1) looks something like this:
.
├── bin
│ ├── dune
│ └── main.ml
├── dune-project
├── hello_dune.opam
├── lib
│ ├── dune
│ └── assign1.ml
└── test
├── dune
└── test_assign1.ml
The bin file contains the executable associated with the project
lib directory contains the source code, and the test directory
contains the test suite. There are a handful of dune commands that
you will need to become familiar with. You should run these in the
root of the project.
dune build |
Build the project |
dune exec assign1 |
Run the executable assign1 of the project (as defined in main.ml) |
dune utop |
Open Utop in a way that is project aware |
dune test |
Run the test suite of th project |
dune clean |
delete auxiliary files created during building |
5. 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.
Note: It is more common for us to use Utop via Dune so that it runs in a project aware way. For example, if you run
dune utop
Then you should be able to refer to values you've defined in
lib/assign1.ml using, e.g.
utop # Assign1.sqrt 10
_ : int = 4
Assign1 is the name of the module defined by the file
lib/assign1.ml (module is like a namespace, it encasulates a
collection of functions, more on that later).