Resources

Table of Contents

1 Course Systems

Here are the key online systems (besides this website!) that we’ll use in the course in rough order of how often you’re likely to use them:

PrairieLearn
Most assessments, including quizzes, assignments, and in-class exercises.
Piazza
Announcements, discussion, private communication with staff (but use e-mail if you’re uncomfortable using Piazza)
Panopto
Lecture recordings (which can also be streamed almost-live)
Department UNIX servers
The easiest way to get started with ghci (Haskell) and swipl (Prolog)
Canvas
Grades (supplementing PrairieLearn), password-protected materials, Zoom for synchronous/live online class, maybe iclicker registration
More
Let us know if there’s something else that should be here. Should we talk about learning.github.ubc.ca, replit, or some other useful resource, reference, or slice of awesomeness?

2 Technical Setup

Though we recommend setting up a development environment on your local computer, you are able to develop and run Haskell and Prolog code on the department-provided servers.

2.1 Remote Development

Log in remotely to the students.cs.ubc.ca UNIX servers. (Once you have it set up, ssh MY_CWL_ID@remote.students.cs.ubc.ca will log you in.) For Haskell, you can run ghci from the command-line. stack is also available. For Prolog, you can run swipl. (Please note that at the time of writing an older version of swipl is installed. We hope to remedy that soon.)

We have a magic Bash script that you can use on CS servers to make development easier. Add the line source ~cs-312/public/cpsc312_profile.sh to the bottom of your ~/.bash_profile. Then open a new shell (or SSH in again) and run cpsc312_init && cpsc312_update to initialize your dev environment. It will take a while to install all the utils required, so be patient or open it in a tmux session! When it finishes, you’ll find cabal, doctest, hlint, and ghcid on your path. This script puts the sandboxed ghc installations and package databases on the scratch drive, so periodically they’ll be wiped. When that happens (and you’ll know because things will act funny) just run cpsc312_reinit && cpsc312_update.

There are additional functions cpsc312_new_stack and cpsc312_new_cabal to make new projects should you need to. However, you can also just work on single files and use ghci or stack ghci or cabal repl (as in the section below on Haskell Interaction).

2.2 Local Editor

You are free to edit code however you want, but we have found that Visual Studio Code works well with some language-specific extensions like

You can install VS Code as their website suggests, or as your package manager allows (e.g. brew install visual-studio-code).

2.3 Local Haskell Installation

We are using the primary Haskell distribution, GHC. It is available for most major platforms, and installation of the compiler and related tools is now managed by a tool called ghcup. The installer will helpfully prompt you to install the latest versions of components, which you can do safely just by answering “y” or “P” a few times. However, we have found that a slightly older version of GHC is a bit better supported on most platforms. You will find the following tools (at the following versions) useful:

If you are on Apple Silicon, things are a bit trickier! You will want to use ghc 8.10.7 and not bother yet with hls. You’ll be fine without the language server - you’ll only miss some IDE features. ghcup upgrade and ghcup list will help you track newer releases that may improve compatibility on M1.

ghcup may ask you to install additional packages for your system. On Windows, you can say yes to installing msys2. On various linux distributions like Ubuntu or Fedora, it may suggest a number of packages you can install with apt or yum - things like build-essential, libtinfo, libgmp, etc. Go ahead and do that.

The versions of these tools in your package manager (apt, homebrew, etc.) are likely different from our recommended versions! Therefore, we suggest that you manage these tools with ghcup. To ensure that these particular versions are installed and configured to be the default, you can run:

$ ghcup install ghc 8.10.4 --set
$ ghcup install stack 2.7.3 --set
$ ghcup install cabal 3.4.0.0 --set
$ ghcup install hls 1.3.0 --set

Finally, you will need to ensure that the binaries for these versions are on your $PATH. The ghcup installer recommends adding source $HOME/.ghcup/env to your shell configuration (e.g. in ~/.bash_profile, ~/.bashrc, ~/.zprofile, etc). When you do that and open a new shell, you should be able to do the following:

$ which ghci
/path-to-my-user-home/.ghcup/bin/ghci
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.10.4

Getting your $PATH correct can be tricky. Remember you have to open a new shell to see configuration changes, and that the order in which directories appear matters! echo $PATH will help you understand that order, and which ghci will tell you the first directory in the list that binary comes from. (On Windows, where ghci may work, or there may be PowerShell equivalents.) If you want to manage your path manually, here’s a good incantation that includes stack- and cabal-installed programs on the path too:

export PATH="$HOME/.local/bin:$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"

If you try your best and really can’t get it to work, you can try your package manager to install ghc, stack, and cabal, even if they aren’t quite the same versions. (Try Homebrew for Mac, Chocolatey for Windows, apt/yum/dnf/pacman/etc for Linux.) The Haskell Platform has helpful instructions. (However, it’s going to be easiest on your instructors if you can use the versions we recommend; they’re the versions on the remote CS servers.)

2.4 Haskell Interaction

We will walk you through editing and exploring some simple Haskell code. Make a file called Scratch.hs with the following contents:

module Scratch where

theAnswer :: Int
theAnswer = 42

You can load this file into a REPL like so, and thereafter you can evaluate any Haskell expression:

$ ghci Scratch.hs
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Scratch          ( Scratch.hs, interpreted )
Ok, one module loaded.
*Scratch> theAnswer
42

Note that the list of loaded modules precedes the > prompt, and that you can simply refer to any member of a loaded module without error. You might try:

2.5 Haskell Projects with Stack

If your work gets large enough to split into multiple modules, or if you start needing external dependencies, then you’ll find it easier to do your work in a project. Using a package name my-project as an example, Run stack new my-project to scaffold a new project. In your current working directory you will find a new my-project directory that will contain things like:

(Again, please note that the resolver: lts-18.6 settings in stack.yaml is important if you want to use ghc 8.10.4. If you want newer releases, then the resolver it picks will work fine.)

Most of the time you’ll start editing in src/Lib.hs. If you need to add package dependencies from Stackage, add their names to the dependencies: list in package.yaml. The following commands are useful:

If you are looking for xUnit-style tests, try tasty with tasty-hunit.

You’ll have to add them to dependencies: for my-project-test: in package.yaml:

    dependencies:
    - my-project
    - tasty
    - tasty-hunit

And then you can define test cases in test/Spec.hs:

-- Import your library code
import Lib
-- Import dependencies
import Test.Tasty
import Test.Tasty.HUnit

main :: IO ()
main = defaultMain $ testGroup "Tests" $
  [ testCase "Addition works" $ do
      2 + 3 @?= 5  -- actual @?= expected
  , testCase "Multiplication works" $ do
      6 @=? 2 * 3  -- expected @=? actual
  , testCase "Bad assertion" $ do
      1 @?= 2
  , testCase "Explicit failure" $ do
      assertFailure "BOOM!"
  ]

In this example, the last two test cases will always fail. We can run the “Bad assertion” test case by itself with stack test --test-arguments='--pattern Bad'.

If you use stack new a lot, you’ll definitely want to set your name and email in your template variables.

2.6 Local Prolog Installation

We are using a common Prolog distribution, SWI-Prolog. We will use the latest stable version, 8.2.4. You can install it as they suggest, or as your package manager allows. For example, if you have Homebrew on Mac, you can do brew install swi-prolog. On Arch, you can do sudo pacman -S swi-prolog.

2.7 Prolog Interaction

We will walk you through editing and exploring some simple Prolog code. Make a file called scratch.pl with the following contents:

sunny(tuesday).
barbecue(X) :- sunny(X).

You can load this file into a REPL like so, and thereafter you can evaluate any Prolog expression:

$ swipl scratch.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.2.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- barbecue(tuesday).
true.

You might try:

2.8 Other Options

There are a number of online services that let you run snippets of code in a pinch, like

3 Haskell Resources

3.1 Readings

For Haskell, we will primarily follow the lectures from CIS 194 by Brent Yorgey this term. CIS 194 links to readings/resources itself, which you’re welcome to use. Where we have specific other assigned or referenced readings, we’ll use the Haskell WikiBook. (Contributing meaningfully to the wikibook would be a great Bonus Point activity!)

Besides CIS 194 and the Haskell WikiBook, there are lots of great (and not-so-great) Haskell resources out there. Consider these free resources:

3.2 Communities

Besides our own Piazza site, there are various communities for learning and help with Haskell, such as Reddit’s r/haskell and its surrounding subreddits.

3.3 More Readings

If you want to nerd-snipe your mind with some of the tremendous depth available in Haskell, consider:

4 Prolog Resources

The key resources for us include:

Some other valuable resources:

5 More to add!

We’re still fleshing this out. We’re going to add some notes on: