Resources
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. Workspaces in which you can run Haskell and Prolog
- Piazza
- Announcements, discussion, private communication with staff (but use e-mail if you’re uncomfortable using Piazza)
- Agora
- In-class participation. (Attendance, hand-raising, and a cool system for calling on people that will hopefully let more of us get heard!) Agora requires a “join code”, which is coming soon on Piazza
- Panopto
- Lecture recordings (which can also be streamed almost-live)
- Department UNIX servers
- Another way (besides PrairieLearn workspaces) to get started with
ghci
(Haskell) andswipl
(Prolog) - Canvas
- Grades (supplementing PrairieLearn), password-protected materials, Zoom in case we have to shift any in-person events online
- More
- Let us know if there’s something else that should be here!
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 or in the workspaces we provide in PrairieLearn.
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. cabal
(AKA cabal-install
) and stack
are also available. For Prolog, you can run swipl
. (Please note that at the time of writing, swipl
is not installed on the machine we tried. We’ve reach out to help@cs
.)
In a previous term, we built a magic Bash script that you could use on CS servers to make development easier. This is not currently supported, but you can give it a shot! To do so: 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.
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 with results similar to these:
$ which ghci
/path-to-my-user-home/.ghcup/bin/ghci
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 9.4.8
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
. We also urge you to see the haskell.org
get started instructions.
In the end, graded work besides the project will always use the Haskell and Prolog versions and installation available in PrairieLearn.
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 9.4.8: 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:
import Data.List
- Import the module into scope:type find
- Show the type offind
fromData.List
:doc find
- Show docs forfind
:set prompt >
- Change the prompt to something else (good when you have too many modules listed):reload
- Reload all modules (good for when you edit and saveScratch.hs
):help
- Show everything you can do in GHCI
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:
.stack-work/
- A directory of artifacts you should git-ignore.package.yaml
- The project definition file. You can set the project name, your name, etc.stack.yaml
- High-level configuration that determines which version of GHC to use and much more.app/Main.hs
- Contains your appmain
function. Can build withstack build
and run withstack exec my-project-exe
.src/Lib.hs
- Contains library code for your app. This can be imported fromapp/Main.hs
ortest/Spec.hs
. Can build withstack build
. You can rename this to something else,src/MyProject.hs
for example, but you’ll need to change the header frommodule Lib ...
tomodule MyProject ...
.test/Spec.hs
- Contains your testmain
function. Can build withstack build
and and run withstack test
.
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:
stack build
- Builds all targetsstack test
- Builds and runs all tests (defined intest/Spec.hs
)stack exec my-project-exe
- Runs the executable defined in theexecutables:
list inpackage.yaml
that is defined inapp/Main.hs
stack ghci
- Enters a REPL with project code and dependencies loadedstack haddock --open
- Opens combined documentation for project and dependencies in your web browser
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'
.
2.6 Local Prolog Installation
We are using a common Prolog distribution, SWI-Prolog. We will use the latest stable version. You can install it as they suggest, or as your package manager allows.
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 9.2.6)
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:
make.
- Reloads imports (good for when you edit and savescratch.pl
)help.
- See what the REPL can do
2.8 Other Options
There are a number of online services that let you run snippets of code in a pinch, like
- Try Haskell - This is a great place to learn the basics of Haskell and to try simple expressions
- Code World - Like
Try Haskell
but with some extra functionality to draw pictures - SWISH - A sandbox for SWI-Prolog
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:
- Hoogle: not a text/tutorial, but the search engine for Haskell docs
- Real World Haskell: thorough, practical book introducing Haskell
- Learn You a Haskell for Great Good!: whimsical Haskell intro; caution: I find some of the humour off-putting/insulting
- The Haskell documentation includes all the resources above and much more
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:
- The Typeclassopedia: an fascinating and challenging tour (by CIS 194’s Brent Yorgey) of Haskell’s powerful type classes, especially those surrounding the infamous Monad.
- Monads and their surroundings in pictures rather than words, code, formulas, and exercises.
- Hakyll: static websites you can debug in Haskell! (Like this one.)
- I’m a nerd, but I cannot get enough of language specifications! Can you? Here’s the Haskell 2010 Language Report.
4 Prolog Resources
The key resources for us include:
SWI-Prolog is both our prolog implementation and an excellent resource to the documentation, tutorials, and communities available for Prolog
If you’re looking for project ideas, the SWI Prolog site has a lot of starting points. For example:
- chapters in the manual beginning with tabling,
- its package list (and if you poke around, a less-endorsed and larger list)
- or even the FAQ!
Learn Prolog Now! is an online textbook for Prolog filled with exercises. The site can be occasionally buggy, and the exercises occasionally very challenging, but it is still a great intro! (And has embedded SWISH Prolog IDEs.)
UBC’s David Poole and Alan Mackworth introduce you to symbolic AI via Prolog in AI:FCA, particularly Chapter 5, Chapter 15, and Chapter 16.
Some other valuable resources:
- Awesome Prolog Resources list lists useful Prolog references, including much of what is here
- Learn Prolog by building a classic text adventure game
- List of free Books to Learn Prolog
- A short tutorial on Prolog with some small examples.
- Coding Guidelines for Prolog (Covington, et al.)
- GNU Prolog, an alternate Prolog implementation
- The ECLiPSe Constraint Programming System and a book: A Gentle Guide to Constraint Logic Programming via ECLiPSe