add explanations of Juli8 for OCaml
authorjim <jim@web>
Sun, 5 Apr 2015 02:36:48 +0000 (22:36 -0400)
committerLinux User <ikiwiki@localhost.members.linode.com>
Sun, 5 Apr 2015 02:36:48 +0000 (22:36 -0400)
juli8.mdwn

index a87464b..8b144f3 100644 (file)
@@ -96,9 +96,120 @@ Below, we'll give instructions on how to install Juli8 into your existing OCaml
 
 ## Using the Juli8 libraries with OCaml ##
 
 
 ## Using the Juli8 libraries with OCaml ##
 
-Will add here some guidance on using the non-monadic parts of the Juli8 library. For the monadic part, [[see here|/topics/week9_using_the_monad_library]].
+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).
+
+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>&lt;exception&gt;</i>
+failwith "msg"  (* same as `raise (Failure "msg")` *)
+invalid_arg "msg"  (* same as `raise (Invalid_argument "msg")` *)
+undefined ()  (* provided by Juli8 *)
+assert &lt;bool&gt; : unit
+</pre>
+
+Corresponding are the following operations in Haskell:
+
+<pre>
+Prelude.error "msg"
+Prelude.undefined
+Control.Exception.assert &lt;bool&gt; &lt;anything&gt;
+</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 (this same module can also be found at `Monad.Option`). This provides a number of functions that you can see by typing `#show Monad.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 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.
+
+Without trying to give an exhaustive explanation of these 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` frop 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.
 
 
-TODO
 
 
 ## Setting up Haskell for use with Juli8 ##
 
 
 ## Setting up Haskell for use with Juli8 ##
@@ -176,6 +287,8 @@ If everything works, then when you start up GHCi, you should see a prompt like t
 
     Prelude Juli8>
 
 
     Prelude Juli8>
 
+Note that the GHCi command line already by default accepts the special keycommands described under item 2 in the Setting up OCaml section above. Additionally, if you type just the start of a command and then press `Tab`, GHCi will attempt to figure out what you started to type and finish the word for you.
+
 
 ## What do I get from Juli8 for Haskell? ##
 
 
 ## What do I get from Juli8 for Haskell? ##