Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated README

  • Loading branch information...
commit ddf71f1463522612f5493583c5d0e069d1252c75 1 parent f0dbf3c
@mmottl mmottl authored
Showing with 48 additions and 91 deletions.
  1. +8 −0 ACKNOWLEDGMENTS
  2. +40 −91 README.txt
View
8 ACKNOWLEDGMENTS
@@ -0,0 +1,8 @@
+Thanks to Arthur Charguéraud <arthur@chargueraud.org> and Roberto di Cosmo
+<roberto@dicosmo.org> for their helpful comments on specifying lazily
+evaluated datastructures. They have used the automated theorem prover
+"Coq" to prove many of Okasaki's datastructures correct, including their
+computational complexity. An earlier implementation of streams in this
+library differed slightly from theirs, and it was not clear whether this
+could break their complexity guarantees. The new representation is based
+on Arthur's and Rboerto's recommendations and should be sound.
View
131 README.txt
@@ -1,4 +1,4 @@
-These files contain an SML-to-OCAML translation of source examples taken
+These files contain an SML-to-OCaml translation of source examples taken
from the following book:
Purely Functional Data Structures
@@ -9,134 +9,83 @@ from the following book:
Some short notes regarding my port:
-I have tried to stick as close as possible to the original code, but
-sometimes this cannot be done.
+I have tried to stick as close as possible to the original code, but sometimes
+this cannot be done.
-The first nine chapters are translated now. Although there are two further
-chapters, I will not translate them anymore, because of restrictions
-that exist not only in SML but also in OCAML:
-
-The basic idea of chapter 10 and 11 is the application of techniques
-called "structural decomposition" and "structural abstraction" (10)
-+ their combination and generalization with ideas in chapter 9 (lazy
-redundant binary numbers) in a framework called "implicit recursive
-slowdown" (11).
-
-Structural decomposition and abstraction require socalled "polymorphic
-recursion". Type inference is unfortunately undecidable in the presence
-of the latter, so neither OCAML nor SML support it.
-
-Thus, the author presents two versions for his examples in these chapters:
-one which does not pass the type checker because of polymorphic recursion
-(for demonstration purposes only), anotherone for showing how to work
-around this restriction.
-
-In a question posted to the OCAML-list, I learnt from the OCAML-developers
-that they are actively researching ways to circumvent the problem of
-polymorphic recursion (e.g. with "forward"-definitions that allow the
-user to restrict the type of a polymorphically recursive definition). In
-the not unlikely case that they succeed, I will continue to translate
-the remaining chapters.
-
-If someone wants to translate the "workaround"-solutions, I will be glad
-to include them in this distribution. In the meanwhile I will wait and
-see what happens in future OCAML-releases.
+The first nine chapters are translated now. There are two further chapters,
+whose implementation requires polymorphic recursion. This feature was not
+available in OCaml for a while, which is why they have not been translated yet.
+Feel free to contribute them!
Notes on efficiency:
Because the data structures are purely functional, they profit a lot from
-garbage collector settings. In case you find that some of them are not
-efficient enough, you might want to raise the memory overhead parameter
-of the garbage collector. See "http://caml.inria.fr/ocaml/speed.html"
-for more details. Performance is in general excellent.
+garbage collector settings. In case you find that some of them are not
+efficient enough, you might want to raise the memory overhead parameter of
+the garbage collector. Performance is in general excellent.
The following rules / differences to the original sources exist:
* No base module
-Since there is hardly anything really necessary in the base module,
-I copied the few relevant declarations into the modules. This allows
-easier testing, because the modules do not depend on others.
+Since there is hardly anything indispensable in the base module, I copied the
+few relevant declarations into each module. This allows for easier testing,
+because the modules do not depend on others.
* Syntax
Names are created by the following rules:
- * Module types are written in capitals. If they consist of more than
- a word, an underscore ('_') is placed between the words.
+ * Module types are written in capitals. If they consist of more than a
+ word, an underscore ('_') is placed between the words.
* Names of exceptions follow the same rule as modules types.
- * Module implementations have to start with a capital letter, the
- rest of the name is lowercase - except if it consists of more than
- one word. In this case the first letter of the following word is
- uppercase. There is no underscore between words.
+ * Module implementations have to start with a capital letter, the rest of
+ the name is lowercase - except if it consists of more than one word.
+ In this case the first letter of the following word is uppercase.
+ There is no underscore between words.
* Currying of function parameters
-Currying is not used anywhere in the original source. I have tried to
-curry parameters, where it makes sense. Tuples that represent a named type
-(e.g. some data structure) are *not* curried in functions that are hidden
-by a signature restriction -> more comprehensible. Functions offered
-via the module interface (signature) do not reveal such implementation
-details (concrete type) anyway, of course.
+Currying is not used anywhere in the original source. I have tried to
+curry parameters where it makes sense. Tuples that represent a named type
+(e.g. some data structure) are *not* curried in functions that are hidden by
+a signature restriction. This seems to aid comprehension. Functions offered
+via the module interface (signature) do not reveal such implementation details
+(i.e. the concrete type) anyway.
* Superfluous bindings
-If a parameter is never used in a following expression, it is not bound
-to any name, but '_' will hold its place.
+If a parameter is never used in a following expression, it is not bound to
+any name. '_' will hold its place.
* Lazy evaluation
-Lazy evaluation is neither an integral part of SML nor of OCAML.
-The original author uses an experimental syntax for describing data
-structures that have to be evaluated lazily. To give people a hint,
-how lazy behaviour can be done, I have used the "Lazy"-module found in
-the standard distribution of OCAML.
-
-To make the syntax at least a bit more similar to the original, I
-have introduced the prefix operator '!$', which stands for 'force" -
-it forces evaluation of a lazy expression. To make an expression lazy,
-the expression 'lazy' is used.
-
-There is a test function at the end of the translation of chapter 4,
-the chapter in which lazy evaluation and streams (= lazy lists) are
-introduced. Uncomment it to try out, how lazy evaluation behaves.
-
-
-* Interface QUEUE
-
-Due to the impossibility to safely generalize expressions in modules
-when parameterized types are used together with "Lazy.t", I had to change
-the interface (most convenient workaround):
-
-Instead of the value
-
- val empty : 'a queue
-
-the function
-
- val empty : unit -> 'a queue
-
-is used now. This guarantees that the empty value can be generated
-without anomalies.
-
-For details see:
+The syntax for lazy evaluation used to implement the datastructures
+and algorithms that require them is quite different from the original.
+The "lazy" type is used to specify datastructures that need lazy evaluation.
+Since recently, OCaml now also supports pattern matching on lazy values,
+which is used throughout.
- http://caml.inria.fr/FAQ/FAQ_EXPERT-eng.html#variables_de_types_faibles
+To make the syntax at least a bit more similar to the original, I have also
+introduced the prefix operator '!$', which stands for 'force" - it forces
+evaluation of a lazy expression. To make an expression lazy, the expression
+'lazy' is used.
-This change allowed e.g. the translation of "PhysicstsQueue". Of course,
-you have to use "empty ()" to get the empty value of queues now.
+There is a test function at the end of the translation of chapter 4, the
+chapter in which lazy evaluation and streams (= lazy lists) are introduced.
+Uncomment it to see how lazy evaluation works.
---------------------------------------------------------------------------
Enjoy the data structures!
-Vienna, April 9, 1999
+Rutherford, March 28, 2012
Markus Mottl (markus.mottl@gmail.com)
Please sign in to comment.
Something went wrong with that request. Please try again.