Merge branch 'working'
[lambda.git] / juli8.mdwn
index 8b144f3..e400162 100644 (file)
@@ -4,7 +4,7 @@
 
 In addition to the fine programming language Kapulet, which doesn't yet exist in a form you can actually execute --- though the full-featured interpreter we provided [[a week or so ago|/topics/week7_untyped_evaluator]] is a good start --- I decided it would be useful to have a collection of basic libraries for our teaching (and other) purposes, that brought OCaml, Haskell, and the Scheme implementations we recommend, more onto even footing. Of course there are fundamental differences between these languages, such as the lack of types in Scheme (though both Racket and Chicken have some facility for working with types in extensions), or the default lazy evaluation strategy in Haskell. But there are also many simply accidental differences between the languages too, in that this one provides a library function doing so-and-so, but the other one doesn't, or calls it by a different name. The Juli8 collection of libraries is aimed to reduce these differences, to make it easier to move back and forth between the languages, and also to just make some of the languages generally easier to use (from my perspective). Juli8 will eventually have components that you can install into each of Haskell, OCaml, Racket, and Chicken. For the moment, OCaml is the most developed of these, and Haskell a bit, with the Scheme components deferred for another time.
 
-Juli8 tries to give OCaml more-or-less the same functionality that you have in Haskell's Maybe, List, and Monad libraries, as well as a few others. It doesn't try for an exact match, and it doesn't strictly use the same names as Haskell does. I've aimed to at least stay close to the existing OCaml naming patterns, and also the Scheme naming patterns when they are salient to me.
+Juli8 tries to give OCaml more-or-less the same functionality that you have in Haskell's `Data.Maybe`, `Data.List`, and `Control.Monad` libraries, as well as a few others. It doesn't try for an exact match, and it doesn't strictly use the same names as Haskell does. I've aimed to at least stay close to the existing OCaml naming patterns, and also the Scheme naming patterns when they are salient to me.
 
 Below, we'll give instructions on how to install Juli8 into your existing OCaml and/or Haskell setups. We'll also discuss how to use the non-monadic parts of the Juli8 libraries for OCaml. We discuss how to use the monadic parts of the Juli8 libraries for OCaml [[elsewhere|/topics/week9_using_the_monad_library]]. We'll also say a little bit about the little bit that Juli8 provides for you if you're using Haskell.
 
@@ -42,7 +42,8 @@ Below, we'll give instructions on how to install Juli8 into your existing OCaml
 
     > That should build and install the readline library in your local user directories. It will take a couple of minutes. Next, download [the source code for rlwrap](http://utopia.knoware.nl/~hlub/rlwrap/rlwrap-0.42.tar.gz). Double-click to expand and go inside the `rlwrap-0.42` folder in a Terminal, as before. Then type this command in the Terminal:
 
-    >     ./configure --prefix=$HOME && make CFLAGS="-g -O2 -I $HOME/include -L $HOME/lib" && make install
+    >     ./configure --prefix=$HOME && make CFLAGS="-g -O2 \
+    >       -I $HOME/include -L $HOME/lib" && make install
 
     If that all completes without errors, then you have gotten `rlwrap` installed. Congratulations. To use it, you just will now type `rlwrap ocaml ...` wherever before you would ordinarily type `ocaml ...` This is just to make interactive OCaml sessions nicer. To compile code with `ocamlc ...` and so on, you don't use `rlwrap` for that. (If you see error messages of the form `-bash: rlwrap: command not found`, then you should make sure that you have a `.bash_profile` or `.bashrc` in your `$HOME` directory which has a line containing something like `export PATH="$HOME/bin:$HOME/Library/Haskell/bin:$PATH"`. Then maybe start up a new Terminal.)
 
@@ -85,7 +86,8 @@ Below, we'll give instructions on how to install Juli8 into your existing OCaml
 
         #directory "+../delimcc";;
 
-        #directory "/Users/jim/.juli8/ocaml";; (* you'll have to substitute your own $HOME directory in for `/Users/jim/` *)
+        (* you'll have to substitute your own $HOME directory in for `/Users/jim/` *)
+        #directory "/Users/jim/.juli8/ocaml";;
 
         #use "juli8.ml";;
 
@@ -129,7 +131,7 @@ 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
+assert <i>&lt;bool&gt;</i> : unit
 </pre>
 
 Corresponding are the following operations in Haskell:
@@ -137,7 +139,7 @@ Corresponding are the following operations in Haskell:
 <pre>
 Prelude.error "msg"
 Prelude.undefined
-Control.Exception.assert &lt;bool&gt; &lt;anything&gt;
+Control.Exception.assert <i>&lt;bool&gt; &lt;anything&gt;</i>
 </pre>
 
 <!--
@@ -187,9 +189,9 @@ Juli8 provides an `Option` module (this same module can also be found at `Monad.
 
 ### 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.
+Juli8 provides a `List` module that can also be found at `Monad.List`, and 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.
+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.
 
@@ -197,18 +199,18 @@ Juli8's `head` and `tail`, like OCaml's official `List.hd` and `List.tl`, both r
 
 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.
+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.
+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.
+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.
 
 
 
@@ -220,7 +222,7 @@ Juli8 provides a `Random` module that replaces the standard OCaml Random module,
 
         ln -s ~/Library/Haskell/logs/world ~/.cabal/
 
-    Now I can find a link to what Cabal has done inside cabal's own folder, without needing to remember or hunt down where the hell on my disk that information has been stored. (All right, to be honest, you can skip this whole step if you want. But I recommend doing it.)
+    Now I can find a link to what Cabal has done inside Cabal's own folder, without needing to remember or hunt down where the hell on my disk that information has been stored. (All right, to be honest, you can skip this whole step if you want. But I recommend doing it.)
 
 3. Still assuming you have Cabal, type the following in a Terminal:
 
@@ -300,7 +302,7 @@ I developed these `:commands` on a Mac, and expect that some of the assumptions
 
 The command `:help` will give you the old, official help text, that doesn't show the extra commands installed by Juli8.
 
-Second, Juli8 comes with a module/library that collects together a number of elements from scattered other locations in the Haskell libraries. These include the Semigroup libraries you installed in Step 3 of the above instructions, which you should use in place of Haskell's standard Data.Monoid libraries. Note that the Semigroup library provides `First a` and `Last a` types that differ from the types of the same name in Data.Monoid. Juli8 also provides `OptFirst a` and `OptLast a` types that behave more like the `First a` and `Last a` types from Data.Monoid. It also provides analogous types `OptMax a` and `OptMin a`. (If you don't know what any of this means, don't worry about it.)
+Second, Juli8 comes with a module/library that collects together a number of elements from scattered other locations in the Haskell libraries. These include the `Semigroup` libraries you installed in Step 3 of the above instructions, which you should use in place of Haskell's standard `Data.Monoid` libraries. Note that the `Semigroup` library provides `First a` and `Last a` types that differ from the types of the same name in `Data.Monoid`. Juli8 also provides `OptFirst a` and `OptLast a` types that behave more like the `First a` and `Last a` types from `Data.Monoid`. It also provides analogous types `OptMax a` and `OptMin a`. (If you don't know what any of this means, don't worry about it.)
 
-Third, Juli8 comes with a module/library `IOPlus` that isn't loaded by default, but which you can load manually by saying `:add IOPlus`. This provides instances to make `IO a` a Monoid when `a` is, and to make `IO` act like an instance of the Alternative and MonadPlus typeclass. This has some limitations, and can't be done perfectly, which is why it isn't done in the standard libraries. There's also an `IOFirst` and an `IOLast`. This is more experimental than the rest of the stuff in Juli8 and may well change or be removed. I'll explain it and refine it another time.
+Third, Juli8 comes with a module/library `IOPlus` that isn't loaded by default, but which you can load manually by saying `:add IOPlus`. This provides instances to make `IO a` a `Monoid` when `a` is, and to make `IO` act like an instance of the `Alternative` and `MonadPlus` typeclasses. This has some limitations, and can't be done perfectly, which is why it isn't done in the standard libraries. There's also an `IOFirst` and an `IOLast`. This is more experimental than the rest of the stuff in Juli8 and may well change or be removed. I'll explain it and refine it another time.