+Here is an overview of what you get in the non-monadic parts of the Juli8 library for OCaml. For the monadic part, [[see here|/topics/week9_using_the_monad_library]].
+
+First, at the top level of your session --- that is, not inside any module --- you get functions `ident` and `%` that work like Haskell's `id` and `.`. That is, `f % g` is equivalent to `fun x -> f (g x)`.
+
+You also get the functions `const`, `flip`, `fix`, `swap`, `curry`, `uncurry`, `even`, and `odd` that work like their Haskell counterparts. <!-- Data.function.fix, Data.Tuple.swap -->
+
+These functions have Haskell counterparts with slightly different names: OCaml's `pair` is Haskell's `(,)`; OCaml's `sign` is Haskell's `signum`; OCaml's `pow (x : int) (n : int)` is Haskell's `x^n`; OCaml's `ignore(expr1); expr2` is like `let _ = expr1 in expr2` in Haskell (and also in OCaml). When `expr1` returns `()`, you can omit the `ignore(...)` and just say `expr1; expr2`. Because these sequences with semicolons can parse differently than you expect, it's generally a good idea to surround them with parentheses or with `begin ... end` which in OCaml is just a syntactic variant of parentheses.
+
+Note that OCaml already came with the following functions that work like their Haskell counterparts: `max`, `min`, `not`, `&&`, `||`, `succ`, `abs`, `fst`, and `snd`. OCaml's infix operators `mod` and `/` work like Haskell's `rem` and `quot`, not like Haskell's `mod` and `div`. (These behave the same when both arguments are positive.)
+
+Juli8 gives you a version of `pred` that replaces the default OCaml `pred`, and raises an error if you say `pred 0`. There's also a more tolerant variant, `pred'`, where `pred' 0` is simply `0`. If you want the standard OCaml `pred`, use `Std.pred x` or just `x-1`.
+
+Corresponding to `pred` and `pred'`, there are also `sub` and `sub'`, where `sub 8 10` raises an error but `sub' 8 10` is simply `0`.
+
+Here are some functions in OCaml/Juli8 but not in Haskell: `mid x y` finds the integer midway between `x` and `y` without overflowing; `mapfst f (x, y)` is `(f x, y)`; `mapsnd g (x, y)` is `(x, g y)`; `non f` is `fun x -> not (f x)`; `non2 f` is `fun x y -> not (f x y)`.
+
+Haskell has a function `iterate` that makes infinite lists. It's possible to make infinite (lazy) lists in OCaml, but modestly complex, and this isn't now provided by Juli8. Instead, Juli8 has a function `iterate n s z` that returns what would be the `n`th member of the infinite Haskell list `iterate s z`, that is, the `n`-fold composition of `s` applied to `z`.
+
+OCaml/Juli8 also has a function `iter_while p s z`, which keeps applying `s` to `z` until the result no longer satisfies the predicate `p`. This is like the Haskell command `until (not . p) s z`.
+
+OCaml/Juli8 has a command `forever f x` which keeps applying `f` to argument `x` forever. That is, it does `let _ = f x in let _ = f x in ...`. Not `f (f (... z))`. Haskell has a similar command, but it only applies to Monads, and Haskell's version doesn't involve `x`. That is, Haskell does `mm >> mm >> ...` for some monadic value `mm`.
+
+OCaml/Juli8 also has `factorial` and `choose n k` functions. But unlike Haskell, it doesn't (yet) have `gcd` or `lcm` functions.
+
+Haskell's ways of handling printing is rather different from OCaml's and most other languages. But if you've learned any Haskell, you've already probably become familiar with this.
+
+OCaml and Haskell's ways of handling errors is also somewhat different. OCaml has:
+
+<pre>
+raise <i><exception></i>
+failwith "msg" (* same as `raise (Failure "msg")` *)
+invalid_arg "msg" (* same as `raise (Invalid_argument "msg")` *)
+undefined () (* provided by Juli8 *)
+assert <i><bool></i> : unit
+</pre>
+
+Corresponding are the following operations in Haskell:
+
+<pre>
+Prelude.error "msg"
+Prelude.undefined
+Control.Exception.assert <i><bool> <anything></i>
+</pre>
+
+<!--
+OCaml:
+ exit <int>
+
+Haskell:
+ System.Exit.exitFailure :: IO a
+ System.Exit.exitSuccess :: IO a
+
+
+Control.Exception.throw :: Exception -> a
+Control.Exception.throwIO :: Exception -> IO a
+Control.Exception.ioError (System.IO.userError "msg") :: IO a
+
+OCaml:
+ try body with ExceptionPattern1 -> ... | ExceptionPattern2 -> ...
+From version 4.02, OCaml also has:
+ match expr with Pattern1 -> ... | exception ExceptionPattern1 -> ... | ...
+
+Haskell:
+ Control.Exception.evaluate : a -> IO a
+ Control.Exception.catch (body :: IO a) (\exn -> (handler :: IO a))
+ Control.Exception.catches (body :: IO a) [Handler (\exn -> handler), ...]
+ Control.Exception.try (body :: IO a) :: IO (Either e a) -- returns an `Either e a` if it can, but if a non-type-`e` error was thrown, propagates it
+
+OCaml/Juli8:
+ [[finally]] TODO
+
+Haskell:
+ Control.Exception.finally (body :: IO a) (final :: IO b) :: IO a
+ Control.Exception.onException (body :: IO a) (final :: IO b) :: IO a -- here finalizer is skipped on clean exit
+
+OCaml ref cells:
+ `==` and `!=`
+ `ref x` creates a new ref cell
+ `!cell` gets the contents of a ref cell
+ `cell := x'` modifies the contents of a ref cell
+ `incr cell` and `decr cell` modify the contents of a ref cell that holds an `int`
+
+Does Haskell have ref cells, you ask? Well it has `STRef`s and `IORef`s, these are pretty similar in functionality to OCaml's reference cells. If you're willing to use the Haskell function `unsafePerformIO`, you can make them more-or-less exactly the same. (Though you will then lose some of the guarantees that Haskell's type system aims to provide.) Maybe we'll write a page somewhere explaining how to get the most OCaml-like behavior out of Haskell. We won't do that here and now.
+-->
+
+### Option ###
+
+Juli8 provides an `Option` module (there's also a module `Monad.Option` that only exposes the monadic interface). This provides a number of functions that you can see by typing `#show Option` if you're running OCaml version 4.02 or above. For earlier versions of OCaml, type `module Something = Option;;` to see the same result. A few of the functions from the `Option` module are also currently exported to be available at the top level. Thus you can simply say `is_some x` instead of `Option.is_some x`. But if you're not sure which are available in this way, just play it safe and use the preferatory `Option.`.
+
+### List ###
+
+Juli8 provides a `List` module that replaces the standard OCaml `List` module, which is a bit skimpy. The official `List` module is still available at `Std.List`, but all of its functionality is present in Juli8's `List` module, albeit sometimes under slightly different names. To see what's in the `List` module that Juli8 provides, type `#show List` in OCaml version >= 4.02. Many of the functions here parallel functions from the Haskell libraries.
+
+As with the `Option` library, a few of the functions are also currently exported to be available at the top level. Also as with `Option`, there's additionally a module `Monad.List` that only exposes the monadic interface.
+
+Without trying to give an exhaustive explanation of the `List` functions, here are a few comments.
+
+Juli8's `head` and `tail`, like OCaml's official `List.hd` and `List.tl`, both raise an error if applied to an empty list. However, Juli8 also provides a `tail'` function that returns `[]` when applied to the empty list. (Compare `pred'`, described above.) There are analogous pairings between `take`,`drop`, and `split` on the one hand, and `take'`, `drop'`, and `split'` on the other.
+
+Juli8 also provides a function `opthead xs` that returns either `Some x` if `xs` has a head, else `None`.
+
+Some functions in Juli8's libraries accept OCaml's *optional labeled* arguments. Thus for example `zip xs ys` will raise an error if the lists have different lengths, but `zip ~short xs ys` will instead just stop with the shorter list. `drop_while ~rev p xs` drops elements from the *right end* of `xs` that satisfy the predicate `p`, rather than from the left end; similarly `find ~rev p xs` finds the *last* item in `xs` that satisfies the predicate. `remove ~many p xs` removes *all* the members of `xs` that satisfy predicate `p`, rather than just the first. There are many examples like this. See the comments in the source code for a full description.
+
+A few more examples worth calling attention to are that `insert ~many x xs` inserts `x` into the appropriate position in already-sorted list `xs`, but that without the `~many` flag, `insert` won't insert items that are already present in the list. Similarly, `sort ~many xs` will sort a list, retaining arguments that compare as equal in the order they originally appeared, but without the `~many` flag, `sort` will drop all duplicates after the first.
+
+
+### String ###
+
+Juli8 provides a `String` module that replaces the standard OCaml `String` module, and includes some (but not all) functionality from the standard `String`, `Str`, and `Char` modules. The official `String` module can be found at `Std.String`. To see what's in the `String` module that Juli8 provides, type `#show String` in OCaml version >= 4.02. Some of the functions here parallel functions from the Haskell libraries.
+
+### Random ###
+
+Juli8 provides a `Random` module that replaces the standard OCaml `Random` module, and includes some (but not all) functionality from the standard `Random` module, which can still be found at `Std.Random`. To see what's in the `Random` module that Juli8 provides, type `#show Random` in OCaml version >= 4.02.