For Programmers: Free Programming Magazines  


Home > Archive > Functional > January 2008 > beginning with ML









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Pages:
Pages: [1] 2
Author beginning with ML
michele.simionato@gmail.com

2007-11-05, 4:24 am

Yesterday, while performing an Internet search for lightweight
concurrency,
I run into the Alice system, which is an implementation of the ML
language.
I knew nothing about ML, except that a functional language called ML
existed,
however skimming the tutorial I pretty much liked what I saw, so I
want to do
some experiment with ML programming, at least for educational
purposes.
If you have good pointers to resources, references, libraries, etc,
please let me know. I am especially interested in code snippets and
example of idiomatic ML (an ML cookbook or something like that). I
have already discovered that there is a "SICP in ML" resource, which I
am looking at. My first impression if that ML has been heavily
influenced
by Scheme (it looks like it has been designed as a *reaction* to
Scheme)
which I am familiar with, so a reference like "ML for Scheme
programmers"
would be fine for me. Anyway, I do most of my work in Python, so I am
especially interested in understanding how to convert Python idioms in
ML
idioms. To be concrete, I have made up a problem (which is however not
completely made up, since I had to parse files in custom formats many
times in
real life). Suppose I have a data file like the following:

$ cat example.dat
x
1.0
2.0
3.0
y
-0.5
0.5
z
2
3.0

I want to write a script taking this file as input and returning the
averages as output:

Averages:
x = 2.0
y = 0.0
z = 2.5

The script must recognize the identifiers and the numbers (possibly
converting
integers in floats) and give some error message for wrong inputs. An
idiomatic
modern Python solution could be the following:

import re

def show_averages(names_averages):
print 'Averages:'
for name, average in names_averages:
print '%s = %s' % (name, average)

def apply_(consumer, producer):
for line in producer:
consumer.send(line)
return consumer.send('*END*')

def is_valid_identifier(name):
return re.match('[_a-zA-Z][_\w\d]*', name)

def is_number(line):
try:
float(line)
except TypeError:
return False
else:
return True

def make_parser():
names = [] # valid identifiers
sums = {} # identifiers -> sums
counts = {} # identifiers -> counts
current_name = None
while True:
line = yield
if line == '*END*':
# possibly add a check for counts[n] != 0
yield [(n, sums[n]/counts[n]) for n in names]; return
elif is_valid_identifier(line):
current_name = line
sums[current_name] = 0
counts[current_name] = 0
names.append(current_name)
elif is_number(line):
assert current_name, 'No valid identifier in the input
data!'
sums[current_name] += float(line)
counts[current_name] += 1
else:
raise ValueError('Bad line %r' % line)

def test():
data = '''
x
1.0
2.0
3.0
y
-0.5
0.5
z
2
3.0
'''.split()
parser = make_parser()
parser.next() # initialize
show_averages(apply_(parser, data))

if __name__ =='__main__':
test()

How would you write an idiomatic ML solution?
Thanks in advance to everybody,

Michele Simionato

P.S. I was not sure if to post here or in comp.lang.ml, but it looks
like
there is very little traffic on comp.lang.ml. Apologies if this the
wrong
newsgroup.

Vesa Karvonen

2007-11-05, 8:08 am

michele.simionato@gmail.com <michele.simionato@gmail.com> wrote:
[...]
> If you have good pointers to [ML] resources, references, libraries,
> etc, please let me know.

[...]

The MLton wiki has several pages on SML programming techniques and
links to some resources (tutorials, books, ...):

http://mlton.org/StandardML

If you really want to learn how to program in ML, I would strongly
recommend reading a book length treatment on programming in ML. After
finishing it, you should read articles on programming techniques in ML
and other functional languages.

> I have already discovered that there is a "SICP in ML" resource,
> which I am looking at. My first impression if that ML has been
> heavily influenced by Scheme (it looks like it has been designed as
> a *reaction* to Scheme) which I am familiar with, so a reference
> like "ML for Scheme programmers" would be fine for me.


ML and Scheme were both born around the same time:

http://www.levenez.com/lang/history.html#03

The similarity is probably more due to roots in lambda calculus.

> Anyway, I do most of my work in Python, so I am especially
> interested in understanding how to convert Python idioms in ML
> idioms. To be concrete, I have made up a problem (which is however
> not completely made up, since I had to parse files in custom formats
> many times in real life). Suppose I have a data file like the
> following:

[...]
> How would you write an idiomatic ML solution?


What follows below is a similar program written in Standard ML using
no libraries beyond the Standard ML Basis library. It is by no means
the only way or the most elegant way to write such a program in ML.
It compiles with Alice ML as well as almost any SML compiler
(e.g. MLton, SML/NJ, Poly ML, MLKit, ...).

(* A few utilities - I have these in libraries *)

fun fail m = raise Fail m
datatype ('a, 'b) sum = INL of 'a | INR of 'b
fun apply f x = INR (f x) handle e => INL e
fun eval th = apply th ()
fun throw e = raise e
fun either (fA, fB) = fn INL a => fA a | INR b => fB b
fun try (th, fv, fe) = either (fe, fv) (eval th)
fun past ef x = (ef () : unit ; x)
fun after (th, ef) = try (th, past ef, throw o past ef)

fun inputFile filename = let
val ins = TextIO.openIn filename
in
after (fn () => TextIO.inputAll ins,
fn () => TextIO.closeIn ins)
end

(* Averages *)

fun isIdFirst c = #"_" = c orelse Char.isAlpha c
fun isIdRest c = isIdFirst c orelse Char.isDigit c

fun isId t =
0 < size t
andalso isIdFirst (String.sub (t, 0))
andalso CharVector.all isIdRest t

fun averagesFromList ts = let
fun loop [] = ()
| loop (t::ts) =
if isId t then let
fun printAverage n sum =
print (concat [t, " = ", Real.toString (sum / real n), "\n"])

fun sumLoop n sum =
fn [] => printAverage n sum
| t::ts =>
case Real.fromString t
of NONE => (printAverage n sum ; loop (t::ts))
| SOME r => sumLoop (n+1) (sum + r) ts
in
sumLoop 0 0.0 ts
end
else fail (concat ["Expected an identifier, but got '", t, "'."])
in
print "Averages:\n"
; loop ts
end

val averagesFromString = averagesFromList o String.tokens Char.isSpace
val averagesFromFile = averagesFromString o inputFile

(* Test *)

val () =
averagesFromString
"x\n\
\1.0\n\
\2.0\n\
\3.0\n\
\y\n\
\-0.5\n\
\0.5\n\
\z\n\
\2\n\
\3.0\n"

> P.S. I was not sure if to post here or in comp.lang.ml, but it looks
> like there is very little traffic on comp.lang.ml. Apologies if this
> the wrong newsgroup.


comp.lang.ml is a moderated newsgroup. It may sometimes take many
days before a message appears there after one has sent it. The delay
is a highly effective traffic inhibitor and wastes the time of
everyone involved. People asking questions often end up getting the
answer earlier from some other newsgroup. Often several people
provide essentially the same answer to a question, because one cannot
see the previously sent answers that are in the moderation queue.

-Vesa Karvonen
michele.simionato@gmail.com

2007-11-05, 8:08 am

On Nov 5, 11:26 am, Vesa Karvonen <vesa.karvo...@cs.helsinki.fi>
wrote:
>
> What follows below is a similar program written in Standard ML using
> no libraries beyond the Standard ML Basis library. It is by no means
> the only way or the most elegant way to write such a program in ML.
> It compiles with Alice ML as well as almost any SML compiler
> (e.g. MLton, SML/NJ, Poly ML, MLKit, ...).
> <snip>


That's interesting, thanks. It looks like loops are implemented
exactly as in Scheme.
Is there a "format" utility instead of performing string concatenation
by hand? Also,
you are mixing the formatting of the output with the generation of the
result (i.e. the
print statements are in the core routine). Suppose I want to
accumulate the result
before formatting. What's the preferred data structure? An association
list? A hash table?
What if I want to return the result lazily? Is there a "yield" concept
so that I could
return the averages one at the time?

Michele Simionato

Vesa Karvonen

2007-11-05, 8:08 am

michele.simionato@gmail.com <michele.simionato@gmail.com> wrote:
> Is there a "format" utility instead of performing string concatenation
> by hand?


If you mean something like printf in C, then here is a page that describes
how one can write something like it in SML:

http://mlton.org/Printf

I have written a slighly more advanced version (providing both printf and
scanf like functionality), but it isn't currently available from any
public repository.

There are also libraries for more general pretty printing. I (and I think
several other people independently) have ported Philip Wadler's pretty
printing combinators to SML. Here is the signature of my port:

http://mlton.org/cgi-bin/viewsvn.cg...r.sig?view=auto

I have also implemented a generic (polytypic) programming library that
contains a generic pretty printing function. Here is the signature of
the pretty printing generic:

http://mlton.org/cgi-bin/viewsvn.cg...y.sig?view=auto

Both of these libraries are for Standard ML and work with at least MLton
and SML/NJ. It should be possible to port the libraries (with a few
changes) to Alice ML as well.

> Also, you are mixing the formatting of the output with the generation of
> the result (i.e. the print statements are in the core routine). Suppose
> I want to accumulate the result before formatting. What's the preferred
> data structure? An association list? A hash table?


Well, that depends entirely on your requirements. The SML/NJ utility
library contains a hash table implementation (and other data structures)
and several SML implementations contain a port of the library.

> What if I want to return the result lazily?


Alice ML has language support for lazy evaluation:

http://www.ps.uni-sb.de/alice/manual/futures.html#lazy .

In Standard ML you can use thunks (like in Scheme)

http://mlton.org/Lazy .

There is also my port of SRFI-45 to Standard ML:

http://mlton.org/cgi-bin/viewsvn.cg...y.sig?view=auto

Using those you can implement lazy sequences.

> Is there a "yield" concept so that I could return the averages one at
> the time?


There is no yield construct as such. However, you can implement such
a construct with threads. In addition to Alice ML, at least SML/NJ
and MLton provide support for light-weight, user-level threads.
Specifically, SML/NJ provides callcc

http://www.smlnj.org/doc/SMLofNJ/pages/cont.html

and MLton provides user-level threads

http://mlton.org/MLtonThread .

You can use either of those to implement coroutines similar to what
you have in Python. (I once wrote such a thing using MLton's
user-level threads, but I don't seem to have the code anymore. Maybe
I should write it again someday.)

You can also do coroutine like programming using continuation passing
style.

-Vesa Karvonen
michele.simionato@gmail.com

2007-11-05, 7:14 pm

On Nov 5, 12:49 pm, Vesa Karvonen <vesa.karvo...@cs.helsinki.fi>
wrote:
<snip lots of useful info>

I have yet another question. Which implementation would you recommend
for a beginner?
My only constraints are that it should work both on Linux and on Intel
Mac. I would like something
reliable and with good error messages.

Michele Simionato

Vesa Karvonen

2007-11-05, 7:14 pm

michele.simionato@gmail.com <michele.simionato@gmail.com> wrote:
[...]
> I have yet another question. Which implementation would you
> recommend for a beginner? My only constraints are that it should
> work both on Linux and on Intel Mac. I would like something reliable
> and with good error messages.


Note that Alice ML is an extension of Standard ML. It provides quite a
few features (e.g. futures, higher-order functors, pickling, packages,
.... see http://www.ps.uni-sb.de/alice/) that are not included in the
definition of Standard ML (only higher-order functors are provided by a
couple of other SML implementations). So, if you want to play with those
features, then you should go with Alice ML. I can't comment on the
reliability of the implementation or the quality of the error messages,
because I don't use Alice ML on a daily basis.

Personally, I use mainly MLton and SML/NJ. Of those two, MLton is, in my
subjective experience, somewhat more reliable (although SML/NJ is also
very reliable) and gives noticeably higher quality error messages, but
this is just my personal experience. MLton also makes it trivial to
create stand-alone executables with excellent performance. However, MLton
is a whole-program compiler, compile times can be quite long (from 5
seconds to several minutes depending on program size), and does not
provide an interactive REPL. SML/NJ provides a REPL, separate
compilation, and compiles quickly. But there are many more implementation
of Standard ML, see http://mlton.org/StandardMLImplementations .

Then there is also O'Caml, which is very similar to Standard ML, but
different. Here are a few language comparisons:

http://www.cs.berkeley.edu/~adamc/mlcomp/
http://mlton.org/OCaml
http://www.mpi-sws.mpg.de/~rossberg/sml-vs-ocaml.html

Personally, I programmed for some time (for about a year) in O'Caml
before switching to Standard ML. O'Caml is a nice language, but
Standard ML is arguably simpler, cleaner, more orthogonal, specified
more rigorously (formally), and has fewer language features. These
are some of the reasons, in addition to the existence of MLton, why I
personally prefer Standard ML, but people like me are in the minority.
:-)

-Vesa Karvonen
Chris Rathman

2007-11-05, 7:14 pm

michele.simionato@gmail.com wrote:
> I have already discovered that there is a "SICP in ML" resource, which
> I am looking at. My first impression if that ML has been heavily
> influenced by Scheme (it looks like it has been designed as a
> *reaction* to Scheme) which I am familiar with, so a reference like
> "ML for Scheme programmers" would be fine for me.


The languages have many similarities and have influenced each other
(There's actually a fair amount of ML influence on Scheme). But, if
all you're looking at is my SICP translation in isolation, then the
parallels between the two is being overemphasized on purpose.
Hopefully the resource provides a quick glance (whets the appetite)
for those that are familiar with SICP or Scheme. Other resources,
such as those pointed to by Vesa, will help you get a more methodical
introduction to ML.

Chris

Jon Harrop

2007-11-05, 7:14 pm

User-Agent: KNode/0.10.4
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7Bit
X-Complaints-To: abuse@supernews.com
Lines: 13
Bytes: 1604
Xref: number1.nntp.dca.giganews.com comp.lang.functional:65195

michele.simionato@gmail.com wrote:
> I have yet another question. Which implementation would you recommend
> for a beginner?


OCaml if you're running Linux or Mac OS X and F# if you're running Windows.

While SML is a very nice language and well worth learning, its user base is
about 10x smaller than OCaml's and is split across various incompatible
compilers. So SML has fewer libraries and is less practical.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
David B. Benson

2007-11-05, 7:14 pm

On Nov 5, 6:56 am, "michele.simion...@gmail.com"
<michele.simion...@gmail.com> wrote:
....
> Which implementation would you recommend
> for a beginner?


O'Caml is somewhat different and less clean language that Standard
ML. I prefer SML and use SML/NJ exclusively because of the support
for Concurrent ML. (Book by Reppy.)

Moscow ML was designed as an implementation for beginners and does not
(or anyway, did not do so correctly) support the module features.
Nonetheless, given the intent of the design, you might wish to start
there.

MLton is a good choice as well, especially given Vesa's plug for the
quality of the error messsages.

I don't know enough about MLKit or Alice to offer you any advice
regarding those compilers's error messages.

SML/NJ has quite a good utility library. The code ought to compile in
MLton as well. In particular it offers the ListFormat structure which
is quite convenient assistant in converting list to printable
strings. The SML Basis Library has a supporting book by Reppy and
Gansner which I recommend having in book form. In particular, the
String structure offers String.concat and String.concatWith both of
which run faster that ^ when concatenating many strings. (More
convenient, often, as well.)

The best starting textbook, IMO, remains that by L.C. Paulson, "ML for
the working programmer", but if you are familiar with Scheme you may
not need it.

David B. Benson

2007-11-05, 7:14 pm

On Nov 5, 2:57 am, "michele.simion...@gmail.com"
<michele.simion...@gmail.com> wrote:
> ...
> What's the preferred data structure? An association
> list? A hash table?
> What if I want to return the result lazily? ...
>
> Michele Simionato


Lists are commonly used, being functional, but hash tables are also
used. I use the RedBlackTree implemenation in the utility library
extensively for the larger lookup data structures required.

SML/NJ implements more than just SML. It includes a very fast
implementation of callcc and also supports lazy computation:

http://www.smlnj.org/

Some of these features may also be in Alice ML, I'm not sure.

Also, there ia an on-line book by Robert Harper (Carenige-Mellon) at
his web site. It is more advanced and theoretical than Paulson's
undergraduate textbook.


Jon Harrop

2007-11-05, 10:10 pm

David B. Benson wrote:
> On Nov 5, 6:56 am, "michele.simion...@gmail.com"
> <michele.simion...@gmail.com> wrote:
>
> O'Caml is somewhat different and less clean language that Standard
> ML...


OCaml is also a far more powerful language though. Here's a list of some
really useful features added by OCaml:

.. Pattern guards
.. Or-patterns
.. Lazy stream parsing
.. Macros
.. Polymorphic variants
.. OOP
.. Labelled and optional arguments
.. Private types
.. Ad-hoc polymorphic printing (printf)
.. Array literals
.. Can export infix operator definitions from modules
.. Capitalized type constructors
.. Module hierarchy can be reflected in source directory structure
.. Conventional unary minus
.. Extensive currying in the stdlib
.. Mutable record fields
.. Structural types
.. Recursive types
.. Higher-order functors
.. "open" allowed in signatures
.. Standard integrated build tool
.. Portability of a substantial subset to .NET thanks to F#
.. Lightweight and efficient FFI with auto codegen
.. Lots of documentation
.. More libraries than SML
.. Wider use in industry
.. API browser and IDEs with type throwback
.. High-performance interactive mode
.. Actively developed
.. Polymorphic structural equality, comparison and hashing

SML adds a few features not in OCaml:

.. Equality types
.. Single notion of equality
.. First-class type constructors
.. User defined precedence and associativity of new infix operators
.. Ad-hoc polymorphic arithmetic operations
.. Immutable strings
.. Anonymous record types

The only one I value is equality types but F# has an even better solution to
the same problem.

F# also has a wide variety of features not found in SML and does an
excellent job in carrying the enormous productivity boost of using a
language like OCaml to the .NET platform.

I'm only just learning Scala but my impression is that its design diverged
much too far from core ML and, consequently, it fails to capture the
productivity boost.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-06, 4:22 am

michele.simionato@gmail.com wrote:
> Suppose I have a data file like the following:
>
> $ cat example.dat
> x
> 1.0
> 2.0
> 3.0
> y
> -0.5
> 0.5
> z
> 2
> 3.0
>
> I want to write a script taking this file as input and returning the
> averages as output:
>
> Averages:
> x = 2.0
> y = 0.0
> z = 2.5
>
> The script must recognize the identifiers and the numbers (possibly
> converting
> integers in floats) and give some error message for wrong inputs.
> ...
> How would you write an idiomatic ML solution?


How about this:

include Map.Make(String);;

let inc k dv m =
let n, v = try find k m with Not_found -> 0, 0. in
add k (n + 1, v +. dv) m;;

let read_line line =
try `Float(float_of_string line) with _ -> `String line;;

let rec read ?(k="") ?(m=empty) ch =
match try read_line(input_line ch) with End_of_file -> `None with
| `Float dv -> read ~k ~m:(inc k dv m) ch
| `String k' -> read ~k:k' ~m ch
| `None -> m;;

open Printf;;

let () =
printf "Averages:\n";
iter (fun k (n, v) -> printf "%s = %f\n" k (v /. float n)) (read stdin);;

Compiling and running "sum.ml":

$ ocamlbuild sum.byte
Finished, 3 targets (0 cached) in 00:00:00.
$ ./sum.byte <data.txt
Averages:
x = 2.000000
y = 0.000000
z = 2.500000

> P.S. I was not sure if to post here or in comp.lang.ml, but it looks
> like
> there is very little traffic on comp.lang.ml. Apologies if this the
> wrong
> newsgroup.


If you decide to learn OCaml, subscribe to the OCaml beginners list. There
is now a large and friendly community of people there who can give you all
the help and advice you need.

HTH.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Torben Ægidius Mogensen

2007-11-06, 4:22 am

"David B. Benson" <dbenson@eecs.wsu.edu> writes:

> On Nov 5, 6:56 am, "michele.simion...@gmail.com"
> <michele.simion...@gmail.com> wrote:
> ...
>
> Moscow ML was designed as an implementation for beginners and does not
> (or anyway, did not do so correctly) support the module features.
> Nonetheless, given the intent of the design, you might wish to start
> there.


I believe your information about Moscow ML's lack of support of the
module system is outdated. The Moscow ML's Owners manual states the
following: "The Moscow ML modules language is a superset of the full
Standard ML modules language".

So about the only reason for not using Moscow ML is if your programs
are very time-consuming, since Moscow ML doesn' generate as fast code
as its competitors.

Torben

rossberg@ps.uni-sb.de

2007-11-06, 8:07 am

On Nov 6, 4:27 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> OCaml is also a far more powerful language though. Here's a list of some
> really useful features added by OCaml:
>
> . Pattern guards
> . Or-patterns
> . Lazy stream parsing
> . Macros
> . Polymorphic variants
> . OOP
> . Labelled and optional arguments
> . Private types
> . Ad-hoc polymorphic printing (printf)
> . Array literals
> . Can export infix operator definitions from modules
> . Capitalized type constructors
> . Module hierarchy can be reflected in source directory structure
> . Conventional unary minus
> . Extensive currying in the stdlib
> . Mutable record fields
> . Structural types
> . Recursive types
> . Higher-order functors
> . "open" allowed in signatures
> . Standard integrated build tool
> . Portability of a substantial subset to .NET thanks to F#
> . Lightweight and efficient FFI with auto codegen
> . Lots of documentation
> . More libraries than SML
> . Wider use in industry
> . API browser and IDEs with type throwback
> . High-performance interactive mode
> . Actively developed
> . Polymorphic structural equality, comparison and hashing


While I won't argue your overall conclusion, I have to take issue with
that list. Many points apply to given SML implementaions as well. Some
are weird, e.g. "structural types", which certainly aren't exclusive
to OCaml, and arguably even less pervasive there (cf. records).
Suggesting that SML implementations are not "actively developed" and
generally don't have "high-performance interactive modes" sounds like
active FUD to me (note that - unlike OCaml - SML/NJ or Poly/ML even
compile to native code interactively).

> SML adds a few features not in OCaml:
>
> . Equality types
> . Single notion of equality
> . First-class type constructors
> . User defined precedence and associativity of new infix operators
> . Ad-hoc polymorphic arithmetic operations
> . Immutable strings
> . Anonymous record types


I would add quite a few:

- fully specified evaluation order
- uniform numeric types (esp. syntax for infinite precision ints)
- overflow checking for integers (vs. wrap-around word types)
- first-class tuple and record selectors
- datatype replication
- transparent signature ascription
- type ascriptions for polymorphic definitions
- orthogonal design
- fewer syntax gotchas
- formal definition
- machine-verified proof of soundness for complete language
- many implementations, with interesting extensions
- more textbooks

Just to balance your apparent bias...

- Andreas

Jon Harrop

2007-11-06, 7:13 pm

rossberg@ps.uni-sb.de wrote:
> While I won't argue your overall conclusion, I have to take issue with
> that list. Many points apply to given SML implementaions as well.


Yes.

> Some
> are weird, e.g. "structural types", which certainly aren't exclusive
> to OCaml, and arguably even less pervasive there (cf. records).


SML has nothing like structurally-subtyped objects and polymorphic variants.

> Suggesting that SML implementations are not "actively developed"


I was referring to the language rather than the implementations. The OCaml
language continues to evolve but SML does not.

> and
> generally don't have "high-performance interactive modes" sounds like
> active FUD to me (note that - unlike OCaml - SML/NJ or Poly/ML even
> compile to native code interactively).


No: see the natdynlink branch and compare its performance to that of any
interactive SML implementation on a modern machine. OCaml is much, much
faster.

> I would add quite a few:
> ...
> - transparent signature ascription
> - type ascriptions for polymorphic definitions


What do these two mean?

> - many implementations, with interesting extensions


The same is true of CAML, of course.

> - more textbooks


Do you mean English textbooks? There are 18 OCaml books listed here:

http://caml.inria.fr/about/books.en.html

and they don't list Practical OCaml. How many SML books are there?

> Just to balance your apparent bias...


You are certainly much more familiar with SML than I am. However, your
statement about OCaml not supporting interactive compilation to native code
is incorrect and your implication that SML's many implementations is a good
thing is completely undermined by the fact that none of them have good
support for 64-bit machines.

We have been using 64-bit machines for several years now and the lack of
support for them by all SML implementations is a serious impediment to our
use of SML.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Vesa Karvonen

2007-11-06, 7:13 pm

Jon Harrop <usenet@jdh30.plus.com> wrote:
[...]
> We have been using 64-bit machines for several years now and the lack of
> support for them by all SML implementations is a serious impediment to our
> use of SML.


MLton and Poly/ML both support 64-bit machines. Looking at commits to
the SML/NJ repository, it would seem that SML/NJ will soon support
64-bit machines.

-Vesa Karvonen
Torben Ægidius Mogensen

2007-11-06, 7:13 pm

Jon Harrop <usenet@jdh30.plus.com> writes:

> rossberg@ps.uni-sb.de wrote:


>
> I was referring to the language rather than the implementations. The OCaml
> language continues to evolve but SML does not.


Is that a good thing? I would rather program in a language that
doesn't change under my feet.

That is not to say that developmen is bad, but it should be by
infrequent introductions of standardised versions instead of
bit-by-bit feature bloat.

Some other advantages of SML over OCaml:

- Equality tests can't loop.

- Available on more different platforms.

- Doesn't support OO (yes, I believe this is an advantage).

Torben
rossberg@ps.uni-sb.de

2007-11-06, 7:13 pm

On Nov 6, 3:09 pm, Jon Harrop <use...@jdh30.plus.com> wrote:
> rossb...@ps.uni-sb.de wrote:
>
>
> SML has nothing like structurally-subtyped objects and polymorphic variants.


Except that you already have listed these as separate points, so if
you mean those it's a duplicate.

>
> I was referring to the language rather than the implementations. The OCaml
> language continues to evolve but SML does not.


OK, true. OTOH, I don't much expect any significant further evolution
for either of them. More likely, there will be a new, cleaned up,
incompatible language at some point.

>
> No: see the natdynlink branch and compare its performance to that of any
> interactive SML implementation on a modern machine. OCaml is much, much
> faster.


So you are talking about an experimental branch in the repository? And
does it really modify the standard toplevel to use native compilation
on input?

>
> What do these two mean?


The first is SML's ":" operator for signatures (as opposed to ":>",
which corresponds to OCaml's ":").

The second refers to the treatment of type variables in annotations.
In SML, when I write, say,

fun f (x : 'a) = E

then this documents and ensures that f is polymorphic in x. The
respective OCaml,

let rec f (x : 'a) = E

doesn't mean anything at all. In fact, the compiler happily accepts x
+1 for E.

>
> The same is true of CAML, of course.


Oh, come on. Not exactly.

>
> Do you mean English textbooks? There are 18 OCaml books listed here:
>
> http://caml.inria.fr/about/books.en.html


I only count two actual books in English, and one is not even about
OCaml.

> and they don't list Practical OCaml. How many SML books are there?


I believe the major (English) ones are all listed here:

http://mlton.org/StandardMLBooks
http://mlton.org/StandardMLTutorials

> However, your
> statement about OCaml not supporting interactive compilation to native code
> is incorrect


See above.

> and your implication that SML's many implementations is a good
> thing is completely undermined by the fact that none of them have good
> support for 64-bit machines.


I don't know what you count as "good", but at least MLton and Poly/ML
have decent 64 bit support.

- Andreas

Vesa Karvonen

2007-11-06, 7:13 pm

Jon Harrop <usenet@jdh30.plus.com> wrote:
[...]
> OCaml is also a far more powerful language though. Here's a list of some
> really useful features added by OCaml:


A few corrections and comments:

> . Macros


OCaml has CamlP4, which is a PreProcessor and Pretty-Printer. With
CamlP4 you can implement a parser and pretty-printer for a custom
language. I wouldn't call CamlP4 a *macro* processor as such.

> . Labelled and optional arguments


The existence of labelled arguments is one of those oblique features
of O'Caml that I abhor. With support for structural record types
(like in SML) you don't need them. Optional arguments aren't needed
when you add functional record update (currently not in SML) on top of
structural record types. There are also ways to write functions with
optional and labelled arguments in SML:
http://mlton.org/OptionalArguments .

> . Ad-hoc polymorphic printing (printf)


This can and has been implemented in SML with a reasonable interface
and better semantics. See http://mlton.org/Printf for an intro.

> . Array literals


Not necessary, in SML you just write:

Array.fromList [x1, x2, ..., xN] .

O'Caml also tends to get these things wrong. Here is an interesting
example of using string literals in O'Caml:

$ ocaml
Objective Caml version 3.09.2

# let makeAString () = "a" ;;
val makeAString : unit -> string = <fun>
# let aString = makeAString () ;;
val aString : string = "a"
# aString.[0] <- 'b' ;;
- : unit = ()
# aString ;;
- : string = "b"
# let anotherString = makeAString () ;;
val anotherString : string = "b"

> . Can export infix operator definitions from modules


So can Alice ML, for example. With MLton, one can write libraries
that provide infixed operators. OCaml has a fixed syntax for infix
operators. In SML, one can define any symbol as an infix operator
with precedence (0-9) and associativity (left/right).

> . Capitalized type constructors


Taken literally, that statement is simply false. Proof:

$ ocaml
Objective Caml version 3.09.2

# type lower_case_type_constructor = unit ;;
type lower_case_type_constructor = unit

> . Module hierarchy can be reflected in source directory structure


You can do that in SML also. SML, as such, places no restrictions on
where you store your source files.

> . Extensive currying in the stdlib


You call that a feature? ;-)

> . Mutable record fields


Again, this is one of those oblique features of OCaml that I dislike.
In SML, you just use ref cells.

> . Structural types


SML has structural record types. OCaml has generative record types,
which, I recall, was one of the first gotchas that I encountered when
programming in OCaml. (OCaml programmers learn how limp, or prefix
their record labels, like in the story of Levine the Genius Tailor:

http://lambda-the-ultimate.org/node/1014#comment-10571 .)

> . Recursive types


SML has recursive datatypes. If you are referring to the -rectypes
option, then take your own words for it "you don't want to compile
your code using rectypes":

http://groups.google.com/group/comp...6538c9672d70841

> . Higher-order functors


Several SML (based) language implementations (e.g. Alice ML, SML/NJ,
Moscow ML) also have higher-order functors.

> . Standard integrated build tool


Some SML implementations also provide build tools. For example,
SML/NJ provides the "Compilation Manager".

> . Portability of a substantial subset to .NET thanks to F#


SML.NET implements Standard ML for .NET.

> . Lightweight and efficient FFI with auto codegen


Some SML implementations (e.g. MLton, SML/NJ) provide (arguably)
lightweight and efficient FFI's.

> . API browser and IDEs with type throwback


With MLton+Emacs you can also see the inferred types of bindings
(recently developed feature, you need to patch the compiler:
http://mlton.org/pipermail/mlton/20...ber/030038.html) as well as
browse through all uses and the definition of a symbol conveniently:
http://mlton.org/EmacsDefUseMode .

> . Actively developed


In the past w or so I've written patches for 3 different (4 if you
count patches I haven't yet submitted) SML compilers and/or their
Basis library implementations and they have all been committed.

> . Polymorphic structural equality, comparison and hashing


You can implement generic versions of those in SML:

http://mlton.org/cgi-bin/viewsvn.cg...DME?view=markup

Note also that OCaml has actually two polymorphic equality predicates
neither of which works properly for all types. Not to mention that
many of OCaml's polymorphich operations loop when given cyclic data
structures. First enter the following lines to the OCaml REPL:

type trouble = {mutable die : trouble} ;;
let rec trouble = { die = trouble } ;;

Then enter either one of the following lines:

trouble = trouble ;;
trouble < trouble ;;

Don't bother waiting for the evaluation to finish - it won't.

-Vesa Karvonen
Jon Harrop

2007-11-06, 7:13 pm

Vesa Karvonen wrote:
> Jon Harrop <usenet@jdh30.plus.com> wrote:
> [...]
>
> MLton and Poly/ML both support 64-bit machines.


I was very disappointed with the 64-bit MLton. OCaml gives huge performance
on a wide variety of programs when moving to 64-bit. In contrast, MLton has
ranged from slower to only marginally faster. So MLton gives the worst of
both worlds with slow compile times and slow run times...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-06, 7:13 pm

Torben Ægidius Mogensen wrote:
> Jon Harrop <usenet@jdh30.plus.com> writes:
>
> Is that a good thing?


From my point of view, yes. In F#, for example, I tend to agree with Don's
evolution of the language and I am even willing to rewrite the code to our
commercial products (well over 250kLOC now) when he makes changes.

OCaml is evolving much more slowly than F#. In fact, I wish OCaml were
developing faster but it is very nice to have a new integrated build system
and revamped macro system this year.

> I would rather program in a language that doesn't change under my feet.


I'm quite surprised by that. I'd have thought industry would be the ones
deterred by language evolution.

> That is not to say that developmen is bad, but it should be by
> infrequent introductions of standardised versions instead of
> bit-by-bit feature bloat.


I think "standardization" is a red herring and was effectively the downfall
of SML. Assuming they wanted SML to gain traction, they should have spent
less time on formal semantics and more time on practical issues like a
consistent build system, FFI and libraries.

> Some other advantages of SML over OCaml:
>
> - Equality tests can't loop.


Conversely, OCaml allows recursive values and, in practice, hanging equality
is not a problem and recursive values are useful.

> - Available on more different platforms.


Are you sure?

> - Doesn't support OO (yes, I believe this is an advantage).


F# gets OO+FP right, IMHO.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Lauri Alanko

2007-11-06, 7:13 pm

In article <13ivoa872du71b9@corp.supernews.com>,
Jon Harrop <usenet@jdh30.plus.com> wrote:
> I'm only just learning Scala but my impression is that its design diverged
> much too far from core ML and, consequently, it fails to capture the
> productivity boost.


Are you implying that Scala is a derivative of ML? Or that being close
to core ML is a prerequisite for a language to be productive?


Lauri
namekuseijin

2007-11-06, 7:13 pm

Fairly amusing to see SMLers and OCamlers fighting it out just like
academic purity Schemers vs pragmatic usage Common Lispers.

It seems it doesn't matter which side of the fence you're in --
dynamic, static typing whatever: people disagree in so many
irrelevant details...

Vesa Karvonen

2007-11-06, 7:13 pm

namekuseijin <namekuseijin@gmail.com> wrote:
[...]
> people disagree in so many irrelevant details...


Which details do you find irrelevant?

-Vesa Karvonen
Jon Harrop

2007-11-06, 7:13 pm

rossberg@ps.uni-sb.de wrote:
>
> OK, true. OTOH, I don't much expect any significant further evolution
> for either of them. More likely, there will be a new, cleaned up,
> incompatible language at some point.


I really hope that happens. An incredible language could be born by
combining the merits of modern functional programming languages and I don't
think there would be much trouble agreeing on the good features.

I think there is a good chance the JVM will be extended to improve support
for such a language and I think it would be very interesting to pit a
cross-platform JVM-based FPL against F# on .NET. Sun are just getting their
act together about graphics with JOGL, so I think there is enormous
potential for an interactive technical computing environment with graphical
capabilities similar to Mathematica and, if such a platform existed, it
would be ideal.

>
> So you are talking about an experimental branch in the repository?


Yes.

> And does it really modify the standard toplevel to use native compilation
> on input?


Yes. I have been using it to good effect for several months. It simply
augments OCaml 3.10 with an "ocamlnat" program that provides a native-code
compiled top level. Performance is not significantly different from batch
compiled programs and latency is very low (orders of magnitude faster than
Scala, for example).

Several other people have also adopted the natdynlink branch because the
combination of high-performance and interactivity is ideal for
computationally-intensive on-line data dissection by technical users (e.g.
scientists and engineers). As it facilitates other useful things, like
run-time code generation from macros, I'm hoping it will become the main
branch.

>
> The first is SML's ":" operator for signatures (as opposed to ":>",
> which corresponds to OCaml's ":").


I'll look into that, thanks.

> The second refers to the treatment of type variables in annotations.
> In SML, when I write, say,
>
> fun f (x : 'a) = E
>
> then this documents and ensures that f is polymorphic in x. The
> respective OCaml,
>
> let rec f (x : 'a) = E
>
> doesn't mean anything at all. In fact, the compiler happily accepts x
> +1 for E.


That's interesting. F# emits a warning if the annotation is inexact and that
really annoys me because I often want to use:

'a array

where I don't care what 'a is. I'm just declaring an array type.

>
> Oh, come on. Not exactly.


Well, there's caml-light, MetaOCaml, Fresh OCaml, AtomCaml, JCaml, GCaml,
ECaml, JoCaml, HashCaml, XDuce, CDuce, Coq, F#... I assume you mean that
they share a lot of code?

From my point of view, this begs the question why ML compiler writers can't
collaborate and write not only a decent compiler but also decent
development tools, libraries, bindings and so forth.

Indeed, the uptake of SML would explode if someone wrote a decent tutorial
IDE for it.

>
> I only count two actual books in English, and one is not even about
> OCaml.


Yes. So you meant English textbooks?

OCaml is popular in France (of course!) and Japan. Also, Germany is one of
the most pioneering countries with respect to uptake of OCaml in industry.
So I expect there are many non-English OCaml texts (there are two in
Japanese, for example).

>
> I believe the major (English) ones are all listed here:
>
> http://mlton.org/StandardMLBooks
> http://mlton.org/StandardMLTutorials
>
>
> I don't know what you count as "good", but at least MLton and Poly/ML
> have decent 64 bit support.


Ray tracer:

32-bit run compile
ocamlopt: 8.20s 0.43s
mlton: 6.43s 2.99s

64-bit
ocamlopt: 3.97s 0.45s
mlton: 8.81s 9.82s

Almost all languages see a performance improvement moving to 64-bit on
floating-point intensive benchmarks like this. In contrast, MLton is
_slower_ in 64-bit! MLton takes 22x longer to compile and runs over 2.2x
slower than OCaml.

So I would not say that MLton has "decent" 64-bit support.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
Jon Harrop

2007-11-06, 7:13 pm

Lauri Alanko wrote:
> In article <13ivoa872du71b9@corp.supernews.com>,
> Jon Harrop <usenet@jdh30.plus.com> wrote:
>
> Are you implying that Scala is a derivative of ML? Or that being close
> to core ML is a prerequisite for a language to be productive?


ML is significantly more productive than Scala. I gave several specific
examples on the JVM list recently.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-06, 7:13 pm

namekuseijin wrote:
> Fairly amusing to see SMLers and OCamlers fighting it out just like
> academic purity Schemers vs pragmatic usage Common Lispers.
>
> It seems it doesn't matter which side of the fence you're in --
> dynamic, static typing whatever: people disagree in so many
> irrelevant details...


Well, SML, OCaml and F# are far more similar than different on the scale of
things. I'm sure we all agree that the common ML is a hugely productive
language. We've noted a lot of discrepancies here, which is to be expected,
but many of them are unimportant.

I really hope someone creates a new language that draws upon the current
generation of modern FPLs and combines their merits...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-06, 7:13 pm

Vesa Karvonen wrote:
> Which details do you find irrelevant?


For me:

.. Uncommon SML extensions
.. Equality looping
.. Support for obscure platforms like HPPA
.. Single notion of equality in SML
.. Anonymous record types

I do not believe these points are important and, IMHO, several of the plus
points cited for SML are trying to solve problems that don't exist.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
David B. Benson

2007-11-06, 7:13 pm

On Nov 6, 7:09 am, torb...@app-2.diku.dk (Torben =C6gidius Mogensen)
wrote:
..=2E.
> - Doesn't support OO (yes, I believe this is an advantage).
>
> Torben


I agree.


Jon Harrop

2007-11-06, 7:13 pm

David B. Benson wrote:
> On Nov 6, 7:09 am, torb...@app-2.diku.dk (Torben Ægidius Mogensen)
> wrote:
> ...
>
> I agree.


Have you tried OCaml, Scala and F#?

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-06, 7:13 pm

Vesa Karvonen wrote:
>
> OCaml has CamlP4, which is a PreProcessor and Pretty-Printer. With
> CamlP4 you can implement a parser and pretty-printer for a custom
> language. I wouldn't call CamlP4 a *macro* processor as such.


Why not? Can you elaborate?

>
> The existence of labelled arguments is one of those oblique features
> of O'Caml that I abhor. With support for structural record types
> (like in SML) you don't need them. Optional arguments aren't needed
> when you add functional record update (currently not in SML) on top of
> structural record types. There are also ways to write functions with
> optional and labelled arguments in SML:
> http://mlton.org/OptionalArguments .


If that really works then the boiler plate should be in the stdlibs of as
many SML implementations as possible.

>
> This can and has been implemented in SML with a reasonable interface
> and better semantics. See http://mlton.org/Printf for an intro.


Seriously now, you guys like SML because it is "standardized" but its
support for things like printing, compiling and interfacing is so poor that
these standard library functions (in the literal sense) are relegated to a
Wiki page? That's just crazy talk... :-)

Out of curiosity, what is the equivalent of:

include Map.Make(String)
let print_map = iter (printf "%s -> %d\n")

in SML (ignoring boiler-plate)?

>
> Not necessary, in SML you just write:
>
> Array.fromList [x1, x2, ..., xN] .


Doesn't work in patterns. Don't have active patterns, so can't add it
yourself. Can't implement active patterns because you don't have macros...

> O'Caml also tends to get these things wrong. Here is an interesting
> example of using string literals in O'Caml:
>
> $ ocaml
> Objective Caml version 3.09.2
>
> # let makeAString () = "a" ;;
> val makeAString : unit -> string = <fun>
> # let aString = makeAString () ;;
> val aString : string = "a"
> # aString.[0] <- 'b' ;;
> - : unit = ()
> # aString ;;
> - : string = "b"
> # let anotherString = makeAString () ;;
> val anotherString : string = "b"


Yes, string literals are static but array literals are not. A source of
confusion, I agree. Gives me something to fill an appendix with though. ;-)

>
> So can Alice ML, for example. With MLton, one can write libraries
> that provide infixed operators. OCaml has a fixed syntax for infix
> operators. In SML, one can define any symbol as an infix operator
> with precedence (0-9) and associativity (left/right).


Sure. Comparing exotic dialects is a whole other ball park though. If you're
going to look at dialects of fringe languages then you must consider how
mature they are.

Look at the number of Ubuntu compiler installations, for example:

ocaml-nox: 3471
smlnj: 186
mosml: 124
mlton: 55

At least on Ubuntu (which is probably representative) there are more than
twice as many people developing GUI applications in OCaml using the
liblablgtk2-ocaml-dev library than are using all SML compilers combined!

This is why I would consider OCaml, F# and maybe SML for commercial work but
certainly not any SML dialects (fringe-fringe languages, if you like). For
one thing, they are not mature enough to be relied upon. The last time I
tried MLton it kept generating code that just segfaulted. Having said that,
Alice ML seems to have come along in leaps and bounds since I last looked.

So I think it is very important to distinguish between seriously obscure
academic projects and defacto standards like OCaml and F#. This also
applies to your responses to "higher-order functors" and "build system", of
course.

>
> You can do that in SML also.


Is it automated?

>
> SML has structural record types. OCaml has generative record types,
> which, I recall, was one of the first gotchas that I encountered when
> programming in OCaml. (OCaml programmers learn how limp, or prefix
> their record labels, like in the story of Levine the Genius Tailor:


IMHO, you should either nest in modules or use structural typing (i.e.
objects).

>
> SML has recursive datatypes. If you are referring to the -rectypes
> option, then take your own words for it "you don't want to compile
> your code using rectypes":
>
> http://groups.google.com/group/comp...6538c9672d70841


My advice to a newbie is not relevant here. For non-newbies, rectypes can be
useful. See the ray tracer, for example.

>
> SML.NET implements Standard ML for .NET.


Perhaps that is one to watch but I suspect it will not be able to compete
with a Microsoft language (F#).

The JVM is wide open for equivalent work though. We have Scala and ocamljava
but both are a long way from critical mass. I'd love to see a good
implementation of a good ML on the JVM.

>
> Some SML implementations (e.g. MLton, SML/NJ) provide (arguably)
> lightweight and efficient FFI's.


Are they compatible?

>
> With MLton+Emacs you can also see the inferred types of bindings
> (recently developed feature, you need to patch the compiler:
> http://mlton.org/pipermail/mlton/20...ber/030038.html) as well as
> browse through all uses and the definition of a symbol conveniently:
> http://mlton.org/EmacsDefUseMode .


Fantastic!

>
> In the past w or so I've written patches for 3 different (4 if you
> count patches I haven't yet submitted) SML compilers and/or their
> Basis library implementations and they have all been committed.


Sorry: I was referring to the language rather than the implementations.

>
> You can implement generic versions of those in SML:
>
>

http://mlton.org/cgi-bin/viewsvn.cg...DME?view=markup

A good thing but still fringe-fringe.

> Note also that OCaml has actually two polymorphic equality predicates
> neither of which works properly for all types.


In practice, they work well. This was discussed here recently.

> Not to mention that
> many of OCaml's polymorphich operations loop when given cyclic data
> structures. First enter the following lines to the OCaml REPL:
>
> type trouble = {mutable die : trouble} ;;
> let rec trouble = { die = trouble } ;;
>
> Then enter either one of the following lines:
>
> trouble = trouble ;;
> trouble < trouble ;;
>
> Don't bother waiting for the evaluation to finish - it won't.


Sure, OCaml provides lots of functions that can go into infinite loops. In
practice, that isn't a problem.

As I say, SML solves several problems that are not of practical importance
and a few problems that are of practical importance (e.g. equality types).

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
rossberg@ps.uni-sb.de

2007-11-06, 7:13 pm

On Nov 6, 10:54 pm, Jon Harrop <use...@jdh30.plus.com> wrote:
>
>
>
>
>
> That's interesting. F# emits a warning if the annotation is inexact and that
> really annoys me because I often want to use:
>
> 'a array
>
> where I don't care what 'a is. I'm just declaring an array type.


What's wrong with saying

(_) array

for that?

>
>
>
> Well, there's caml-light, MetaOCaml, Fresh OCaml, AtomCaml, JCaml, GCaml,
> ECaml, JoCaml, HashCaml, XDuce, CDuce, Coq, F#... I assume you mean that
> they share a lot of code?


Most of these are either experimental modifications of the OCaml
system itself, or not OCaml at all. I mean, XDuce, CDuce? Coq??

The only system I could count as an alternative implementation of
OCaml is F#, and that already has /much/ less common ground with it
than any two SML implementations.

> From my point of view, this begs the question why ML compiler writers can't
> collaborate and write not only a decent compiler but also decent
> development tools, libraries, bindings and so forth.


That would indeed be nice, but unfortunately not made easy by the way
funding and crediting works for academia.

OTOH, a bit of competition is good even in research. Otherwise you'd
still do your scientific programming in Fortran.

> Indeed, the uptake of SML would explode if someone wrote a decent tutorial
> IDE for it.


What is a "tutorial" IDE? Something like DrScheme or Helium?

FWIW, for Alice ML (another SML system), we implemented a simple Gtk-
based IDE, with type throwback and an interactive data browser. It is
currently used in the local CS 101 courses. Students certainly like it
better than Emacs, but I strongly doubt that something like it - even
if much more elaborate - would impact SML uptake.

> OCaml is popular in France (of course!) and Japan. Also, Germany is one of
> the most pioneering countries with respect to uptake of OCaml in industry.
> So I expect there are many non-English OCaml texts (there are two in

Japanese, for example).

I am not aware of any German texts on OCaml, but I haven't searched.
OTOH, I know about an upcoming textbook on programming, using SML.

>
> Ray tracer:
>
> 32-bit run compile
> ocamlopt: 8.20s 0.43s
> mlton: 6.43s 2.99s
>
> 64-bit
> ocamlopt: 3.97s 0.45s
> mlton: 8.81s 9.82s


That indeed looks disappointing (although I would be careful with
blindly expecting better performance in 64 bit anyway). Did you
contact the developers about it?

> So I would not say that MLton has "decent" 64-bit support.


Have you tried Poly/ML?

Neelakantan Krishnaswami

2007-11-06, 7:13 pm

In article <<13j1qo7ndh26n85@corp.supernews.com>>,
Jon Harrop <usenet@jdh30.plus.com> wrote:
> David B. Benson wrote:
>
> Have you tried OCaml, Scala and F#?
>



--
Neel R. Krishnaswami
neelk@cs.cmu.edu
Markus E L

2007-11-06, 7:13 pm


Jon Harrop wrote:

> Lauri Alanko wrote:
>
> ML is significantly more productive than Scala. I gave several specific
> examples on the JVM list recently.


Jon,

I think we should agree, that examples don't prove or show anything,
except "in this single case it was so and so". General assertions,
which involve the majority of all possible or practical applications
need to be tested by other methods, e.g. _first_ defining a field of
relevance and then conducting a statistically well founded study of
the whole field.

Regards -- Markus

Matthias Blume

2007-11-06, 10:11 pm

Jon Harrop <usenet@jdh30.plus.com> writes:

>
> Perhaps that is one to watch but I suspect it will not be able to compete
> with a Microsoft language (F#).


You /are/ aware of the fact that the SML.NET developers are Microsoft
employees -- and colleagues of Don Syme, aren't you?
Jon Harrop

2007-11-07, 4:24 am

rossberg@ps.uni-sb.de wrote:
>
> What's wrong with saying
>
> (_) array
>
> for that?


Well I never knew that... :-)

>
> Most of these are either experimental modifications of the OCaml
> system itself, or not OCaml at all. I mean, XDuce, CDuce? Coq??


Yes. When people create something like Alice ML, do they really reimplement
the entire thing from scratch?

> The only system I could count as an alternative implementation of
> OCaml is F#, and that already has /much/ less common ground with it
> than any two SML implementations.


The main features that differ between OCaml and F# are objects, polymorphic
variants and labelled and optional arguments. None of those are even in
SML, so I would not say that OCaml and F# have less common ground than two
SML implementations at all. Quite the opposite in fact...

>
> That would indeed be nice, but unfortunately not made easy by the way
> funding and crediting works for academia.
>
> OTOH, a bit of competition is good even in research. Otherwise you'd
> still do your scientific programming in Fortran.


:-)

>
> What is a "tutorial" IDE? Something like DrScheme or Helium?


Exactly, yes.

> FWIW, for Alice ML (another SML system), we implemented a simple Gtk-
> based IDE, with type throwback and an interactive data browser. It is
> currently used in the local CS 101 courses. Students certainly like it
> better than Emacs, but I strongly doubt that something like it - even
> if much more elaborate - would impact SML uptake.
>
> Japanese, for example).
>
> I am not aware of any German texts on OCaml, but I haven't searched.
> OTOH, I know about an upcoming textbook on programming, using SML.


Tell me more! :-)

>
> That indeed looks disappointing (although I would be careful with
> blindly expecting better performance in 64 bit anyway). Did you
> contact the developers about it?


I posted a response on c.l.f to their announcement. Initially, MLton just
kept segfaulting for me but at least it now runs to completion, even if it
is slower.

>
> Have you tried Poly/ML?


No. I've heard great things about Poly/ML and would like to try it though...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 4:24 am

Neelakantan Krishnaswami wrote:
> In article <<13j1qo7ndh26n85@corp.supernews.com>>,
> Jon Harrop <usenet@jdh30.plus.com> wrote:
>
>


Is that a "no"? ;-)

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 4:24 am

Matthias Blume wrote:
> Jon Harrop <usenet@jdh30.plus.com> writes:
>
> You /are/ aware of the fact that the SML.NET developers are Microsoft
> employees -- and colleagues of Don Syme, aren't you?


Sure, but it isn't being productized. In fact, I'm not sure it is even being
developed any more (last release was over a year ago now).

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 4:24 am

Markus E L wrote:
> I think we should agree, that examples don't prove or show anything,
> except "in this single case it was so and so". General assertions,
> which involve the majority of all possible or practical applications
> need to be tested by other methods, e.g. _first_ defining a field of
> relevance and then conducting a statistically well founded study of
> the whole field.


I only gave examples to elucidate my points rather than to provide evidence.
For example, Scala does not check for exhaustiveness and redundancy of
pattern matches in general and I gave an example where it fails to detect
an obvious bug. Differences like that make it much more difficult to write
correct code in Scala than in any ML.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Alain Frisch

2007-11-07, 4:24 am

Jon Harrop , dans le message (comp.lang.functional:62206), a écrit :
> The main features that differ between OCaml and F# are objects, polymorphic
> variants and labelled and optional arguments.


Functors are also lacking in F#, if I remember correctly.

-- Alain
Torben Ægidius Mogensen

2007-11-07, 4:24 am

Jon Harrop <usenet@jdh30.plus.com> writes:

> Torben Ægidius Mogensen wrote:


>
> Conversely, OCaml allows recursive values and, in practice, hanging equality
> is not a problem and recursive values are useful.


Cyclic values (graphs) are quite possible in SML. But the standard
equality test doesn't follow pointers (it just compares them for
pointer equality), so if you compare two cyclic graphs, you don't get
an infinite loop. You can fairly easily program graph isomorphism if
you really want to compare cyclic structures for equality.

>
> Are you sure?


Fairly:

MLTon runs on 5 different processors (AMD 64, x86, PA-Risc, PowerPC,
Sparc) and many different OSs (multiple BSD flavours, Linux, Windows
under Cygwin, MacOS X, AIX, HPUX, Solaris).

Moscow ML runs under Windows (native), various Unix/Linux/BSD
flavours, .NET and older versions (still Standard ML) runs on Mac OS
(M68K, PPC) and OS/2. More platforms possible through recompilation
of sources. I know that version 1.42 was ported to RISC OS (ARM
processor).

PolyML runs on x86, Sparc and PPC under various BSD/Linux/Unix
platforms (including MacOS X).

TILT runs on Sparc (SunOS) and x86 (Linux)

The ML-kit runs under varous Unix/BSD/Linux flavours.

SML.NET (obviosly) runs on .NET

MLj runs under JVM.

Poplog SML runs on various Linux/BSD/Unix flavours on x86, AMD64,
Alpha, PA-Risc, PPC and Sparc and on Windows/x86.

Torben
rossberg@ps.uni-sb.de

2007-11-07, 8:07 am

On Nov 7, 9:19 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> Yes. When people create something like Alice ML, do they really reimplement
> the entire thing from scratch?


Usually yes. AFAICT, all of the following systems have disjoint code
bases (except maybe for parts of the library): SML/NJ, MLton, Moscow
ML, Poly/ML, SML.NET, Alice ML, HaMLet, MLWorks. They often use quite
different implementation techniques, so that there isn't really that
much to share anyway. Only parser and type checker could probably have
been reused in some cases, but these are not much work, given that SML
is a relatively simple language with a precise definition.

> The main features that differ between OCaml and F# are objects, polymorphic
> variants and labelled and optional arguments.


It particularly also lacks 3/4 of the module system (functors, general
type abstraction, full signature subtyping, include).

And you cannot ignore that it also adds enough features to the core
language to make it unlikely that any non-toy program natively written
in F# will remain valid OCaml.

Note that I am not criticising F# for that, merely pointing out that
it is a mostly different language.

> None of those are even in
> SML, so I would not say that OCaml and F# have less common ground than two
> SML implementations at all. Quite the opposite in fact...


I have no idea where you draw that conclusion from. There certainly
are some annoying incompatibilities between SML implementations, but
they are mainly related to the build system, not to the language
itself (and in one or two cases, outdated libraries). All systems
faithfully implement complete SML. I have written large SML programs
that run on as many as 8 different implementations, and it did require
almost no special care in the code. Try that with, say, C compilers. I
freely admit that the Makefile setup was a pain, though.

So, sorry, no, that is not true.

>
> Tell me more! :-)


You wanna read German? :-) Not sure it will be interesting to you
anyway, since it's rather aimed at first year CS students:

http://www.oldenbourg-wissenschafts.../1.c.1321689.de

>
> No. I've heard great things about Poly/ML and would like to try it though...


So what is keeping you? ;-)

rossberg@ps.uni-sb.de

2007-11-07, 8:07 am

On Nov 7, 9:41 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
>
> Sure, but it isn't being productized. In fact, I'm not sure it is even being
> developed any more (last release was over a year ago now).


They are currently putting quite some work into it. Whether it will
ever be commercially productized I don't know.

- Andreas

Torben Ægidius Mogensen

2007-11-07, 8:07 am

rossberg@ps.uni-sb.de writes:

> On Nov 7, 9:19 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> Usually yes. AFAICT, all of the following systems have disjoint code
> bases (except maybe for parts of the library): SML/NJ, MLton, Moscow
> ML, Poly/ML, SML.NET, Alice ML, HaMLet, MLWorks.


Add the ML kit to this list. And probably Poplog ML too.

> They often use quite different implementation techniques, so that
> there isn't really that much to share anyway. Only parser and type
> checker could probably have been reused in some cases, but these are
> not much work, given that SML is a relatively simple language with a
> precise definition.


If I were to make a new SML compiler, I would probably want to lift
the module system implementation and libraries from some other
project, but apart from that I agree. Making a non-optimising
compiler for the core language should be only a few ws work.

Torben

Jon Harrop

2007-11-07, 8:07 am

Alain Frisch wrote:
> Jon Harrop , dans le message (comp.lang.functional:62206), a écrit :
>
> Functors are also lacking in F#, if I remember correctly.


True.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Vesa Karvonen

2007-11-07, 8:07 am

Jon Harrop <usenet@jdh30.plus.com> wrote:
> Vesa Karvonen wrote:
[color=darkred]
[color=darkred]
> I was very disappointed with the 64-bit MLton.


First you claim that there are no SML implementations that support
64-bit machines. After being told that there are, you reveal that
you've already tried one of them. In fact, you've known about both
MLton and Poly/ML supporting 64-bit machines for months and here is
the proof:

http://groups.google.com/group/comp...96d059f7c823e76
http://groups.google.com/group/comp...d1b2c5e6fb74662

Jon, I think that you are a liar.

> OCaml gives huge performance on a wide variety of programs when
> moving to 64-bit. In contrast, MLton has ranged from slower to only
> marginally faster.


There were some (more or less known) performance regressions after the
introduction of 64-bit support, AFAIK, due to increased
parameterization of the runtime and elimination of some compiler
primitives for simplicity. At least one performance issue has been
identified and fixed (in the SVN) since the last release:

http://mlton.org/pipermail/mlton/20...ber/030042.html

If you'd like to help, you could try and analyze the programs where
you get lower performance than you expected and perhaps there are
optimizations that could be added to MLton.

Note that just going to 64-bits doesn't necessarily improve
performance. On a 64-bit target, MLton uses 64-bit pointers, which
can increase memory pressure significantly, causing both more cache
misses and more time spent doing GC.

-Vesa Karvonen
Jon Harrop

2007-11-07, 8:07 am

Torben Ægidius Mogensen wrote:
> Jon Harrop <usenet@jdh30.plus.com> writes:
>
> Cyclic values (graphs) are quite possible in SML.


Purely functional?

> But the standard
> equality test doesn't follow pointers (it just compares them for
> pointer equality), so if you compare two cyclic graphs, you don't get
> an infinite loop. You can fairly easily program graph isomorphism if you
> really want to compare cyclic structures for equality.


This is certainly one of the largely unimportant discrepancies but one of
the few cases I've encountered this difference is in the implementation of
recursive functions in an interpreter. For example, in the "eval" function:

| ELetRec(var, arg, body, rest) ->
let rec vars' = (var, VClosure(arg, vars', body)) :: vars in
eval vars' rest

In SML, I believe you would introduce a mutable reference and give it a
dummy value, set up the new scope and assign new scope to the dummy value
in order to obtain a cyclic data structure.

This is a minor niggle but the OCaml solution seems more elegant to me.

>
> Fairly:
>
> MLTon runs on 5 different processors (AMD 64, x86, PA-Risc, PowerPC,
> Sparc) and many different OSs (multiple BSD flavours, Linux, Windows
> under Cygwin, MacOS X, AIX, HPUX, Solaris).
>
> Moscow ML runs under Windows (native), various Unix/Linux/BSD
> flavours, .NET and older versions (still Standard ML) runs on Mac OS
> (M68K, PPC) and OS/2. More platforms possible through recompilation
> of sources. I know that version 1.42 was ported to RISC OS (ARM
> processor).
>
> PolyML runs on x86, Sparc and PPC under various BSD/Linux/Unix
> platforms (including MacOS X).
>
> TILT runs on Sparc (SunOS) and x86 (Linux)
>
> The ML-kit runs under varous Unix/BSD/Linux flavours.
>
> SML.NET (obviosly) runs on .NET
>
> MLj runs under JVM.
>
> Poplog SML runs on various Linux/BSD/Unix flavours on x86, AMD64,
> Alpha, PA-Risc, PPC and Sparc and on Windows/x86.


OCaml runs on all of those architectures and also MIPS. OCaml runs on all of
those platforms and XBox, native Windows, MinGW Windows, Tru64 and IRIX but
not OS/2. There is an unofficial port to AIX.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Vesa Karvonen

2007-11-07, 8:07 am

Torben Ægidius Mogensen <torbenm@app-3.diku.dk> wrote:
[...]
> MLTon runs on 5 different processors (AMD 64, x86, PA-Risc, PowerPC,
> Sparc) and many different OSs (multiple BSD flavours, Linux, Windows
> under Cygwin, MacOS X, AIX, HPUX, Solaris).


Note that porting MLton to a platform that has a working gcc is not
very difficult due to the C (gcc) backend. So, the above list is by
no means any sort of limit. A colleague of mine ported MLton to a few
platforms with, I think it is fair to say, novice level SML
programming experience (though he has extensive *nix and programming
experience in several other languages).

-Vesa Karvonen
Jon Harrop

2007-11-07, 7:10 pm

rossberg@ps.uni-sb.de wrote:
> On Nov 7, 9:41 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> They are currently putting quite some work into it. Whether it will
> ever be commercially productized I don't know.


Hmm, I couldn't sworn I read a post by Nick Benton saying it had been
shelved. I can't find it now though...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 7:10 pm

Vesa Karvonen wrote:
> Note that just going to 64-bits doesn't necessarily improve
> performance. On a 64-bit target, MLton uses 64-bit pointers, which
> can increase memory pressure significantly, causing both more cache
> misses and more time spent doing GC.


That problem would equally afflict OCaml.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 7:10 pm

Jon Harrop wrote:
> Here's a list of some really useful features added by OCaml:
>
> . Pattern guards


Some more practical ones as defacto-standard functionality from the stdlib:

.. Pretty printing (Format module)
.. Regular expressions
.. Hash tables with structural hashing
.. Marshalling (albeit type unsafe)
.. GUI API (LablTk)

> SML adds a few features not in OCaml:
>
> . Equality types
> ...


.. Arbitrary-precision integer literals
.. Immutable strings
.. More data structures (IIRC)

Does SML provide regular expressions in its stdlib?

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Jon Harrop

2007-11-07, 7:10 pm

rossberg@ps.uni-sb.de wrote:
> On Nov 7, 9:19 am, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> Usually yes. AFAICT, all of the following systems have disjoint code
> bases (except maybe for parts of the library): SML/NJ, MLton, Moscow
> ML, Poly/ML, SML.NET, Alice ML, HaMLet, MLWorks. They often use quite
> different implementation techniques, so that there isn't really that
> much to share anyway. Only parser and type checker could probably have
> been reused in some cases, but these are not much work, given that SML
> is a relatively simple language with a precise definition.


I must concede that there are more separate SML implementations then.

>
> It particularly also lacks 3/4 of the module system (functors, general
> type abstraction, full signature subtyping, include).


True. I actually miss sigs and abstract types more than functors...

> And you cannot ignore that it also adds enough features to the core
> language to make it unlikely that any non-toy program natively written
> in F# will remain valid OCaml.


That I'm not so sure about. Almost all of F#'s extensions to CAML are
for .NET interop. If you use .NET interop then of course your program will
be difficult to port to OCaml. However, the intersection of the two
languages is very capable and many practical programs will be quite
portable.

> Note that I am not criticising F# for that, merely pointing out that
> it is a mostly different language.


Sure. Microsoft will certainly want to embrace and extend OCaml. They've
already taken most of the good points (I'd like a lot more support for
structural typing though).

>
> I have no idea where you draw that conclusion from. There certainly
> are some annoying incompatibilities between SML implementations, but
> they are mainly related to the build system, not to the language
> itself (and in one or two cases, outdated libraries). All systems
> faithfully implement complete SML. I have written large SML programs
> that run on as many as 8 different implementations, and it did require
> almost no special care in the code. Try that with, say, C compilers. I
> freely admit that the Makefile setup was a pain, though.


Absolutely.

> So, sorry, no, that is not true.


We are talking at cross purposes. I think you are saying that SML
implementations like SML/NJ and MLton have a proportionately huge overlap
in the languages they can compile because the vast majority is ordinary
SML.

I was saying that, in absolute terms, the common language between OCaml and
F# is larger than the SML language because it includes features like
or-patterns, guarded patterns, polymorphic structural equality, comparison
and hashing, printf, array literals and patterns, regular expressions and
so on. The differences are also bigger but I was focusing on the
similarities.

>
> You wanna read German? :-) Not sure it will be interesting to you
> anyway, since it's rather aimed at first year CS students:
>
> http://www.oldenbourg-wissenschafts.../1.c.1321689.de


Bloody hell that's expensive. ;-)

>
> So what is keeping you? ;-)


So I just tried PolyML (see new thread). Not good...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
Chris Rathman

2007-11-07, 7:10 pm

On Nov 7, 5:39 am, rossb...@ps.uni-sb.de wrote:
> You wanna read German? :-) Not sure it will be interesting to you
> anyway, since it's rather aimed at first year CS students:
>
> http://www.oldenbourg-wissenschafts.../1.c.1321689.de


Given my perpetual status as an ML newbie, my affinity for translating
introductory texts and my respect for this particular author... I
might just have to learn German. (Spent a couple of ws there some
25 years ago, but learning how to attain a beer is about as far as I
got). :-)

Grinding the chapter index through babelfish, I get:

- Bases
- high-level procedures
- lists and stringers
- sorting
- constructor and exceptions
- trees
- set theory
- mathematical procedures
- inductive correctness proofs
- running time of recursive procedures
- static and dynamic semantics
- concrete syntax
- data structures
- memory and variable objects
- stacking machines and translators

Only one that I'm not sure about is the last chapter (Stapelmaschinen
und =DCbersetzer). What exactly is the subject?

Chris

Jon Harrop

2007-11-07, 7:10 pm

Torben Ægidius Mogensen wrote:
> If I were to make a new SML compiler, I would probably want to lift
> the module system implementation and libraries from some other
> project, but apart from that I agree. Making a non-optimising
> compiler for the core language should be only a few ws work.


I was really thinking of an optimizing native-code backend being a lot of
work and worth stealing. I assume MLton and SML/NJ have independent
backends. In fact, an interest in this led me to the C-- mailing list some
time ago but the consensus seems to be that it is not going places. The JVM
and .NET are the next best things but they are a long way from being
efficient for functional code. At least for .NET, that might change thanks
to the productization of F# and Sun have hinted at improving the JVM for
more exotic languages in the future.

I really would like to see the brains that created the current generation of
ML variants and implementations collaborate on the implementation of a
newer, practical language that borrows all of the best features currently
available.

MLton and SML/NJ were very impressive on x86 and OCaml is also impressive on
AMD64. So I'm not sure it is worth building upon the JVM or .NET for a
general-purpose language if you can achieve much better performance from a
stand-alone FPL.

Perhaps such a project is unfeasible without industrial intervention...

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
rossberg@ps.uni-sb.de

2007-11-07, 7:10 pm

On Nov 7, 4:51 pm, Chris Rathman <Chris.Rath...@tx.rr.com> wrote:
>
> Grinding the chapter index through babelfish, I get:
>
> - Bases


basics

> - high-level procedures


higher-order procedures

> - lists and stringers


lists and strings

> - sorting
> - constructor and exceptions
> - trees
> - set theory
> - mathematical procedures
> - inductive correctness proofs
> - running time of recursive procedures


time complexity of recursive procedures

> - static and dynamic semantics
> - concrete syntax
> - data structures
> - memory and variable objects


memory and mutable objects

> - stacking machines and translators


stack machines and compilers

;-)

rossberg@ps.uni-sb.de

2007-11-07, 7:10 pm

On Nov 7, 4:21 pm, Jon Harrop <use...@jdh30.plus.com> wrote:
>
>
> That I'm not so sure about. Almost all of F#'s extensions to CAML are
> for .NET interop.


Above all, F#'s new lightweight syntax might be a major bummer
(although I kind of like it).

> I was saying that, in absolute terms, the common language between OCaml and
> F# is larger than the SML language because it includes features like
> or-patterns, guarded patterns, polymorphic structural equality, comparison
> and hashing, printf, array literals and patterns, regular expressions and
> so on. The differences are also bigger but I was focusing on the
> similarities.


Frankly, I consider that a dubious measurement, qualitatively as well
as quantitatively.

>
> Bloody hell that's expensive. ;-)


You mean, compared to the bargain of a related book directed at
scientists? ;-)

> So I just tried PolyML (see new thread). Not good...


Yeah, that's a disappointment. Hopefully, it will improve.

Jon Harrop

2007-11-07, 7:10 pm

rossberg@ps.uni-sb.de wrote:
> On Nov 7, 4:21 pm, Jon Harrop <use...@jdh30.plus.com> wrote:
>
> Above all, F#'s new lightweight syntax might be a major bummer
> (although I kind of like it).


Very true. The problem there is that F#'s development environment is geared
up for #light. Also, there is no way to de#light your code.

>
> Frankly, I consider that a dubious measurement, qualitatively as well
> as quantitatively.


Speaking from experience, porting substantial amounts of code between OCaml
and F# is easy going. The only major surprises I've had were library
related.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
David B. Benson

2007-11-07, 7:10 pm

I replied yesterday, the site claimed the post was successful, but it
never appeared. Is this common here?

Anyway, regarding so-called objects, instead I use light weight
concurrency and a style called raveling in a paper that Carl Hauser
and I wrote.

I am currently committed to SML/NJ for the support it gives to
Concurrent ML. Since my applications run adequately fast on a 0.5 GHz
Pentium III, I have no incentive to try anything else just now.

Eventually I hope to write a front-end to SML/NJ which provides some
of the 'successor ML' features, the way Alice ML does.

Neelakantan Krishnaswami

2007-11-07, 7:10 pm

In article <<13j2ts4nrc92kc2@corp.supernews.com>>,
Jon Harrop <usenet@jdh30.plus.com> wrote:
> Neelakantan Krishnaswami wrote:
>
> Is that a "no"? ;-)


No, it was pushing the wrong key on my newsreader.


To keep this from being a wasted post, here's a trick for when you
program in OCaml and miss views from F# -- it turns out that views are
very easy to implement in plain OCaml.

I'll use a collection as an example. Let's suppose that we want to let
an arbitrary sequence implementation support a nil-and-cons style
pattern matching interface.

Since we're ML programmers, let's start by giving a signature
describing what a nil-and-cons interface is:

module type SEQUENCE_VIEW =
sig
type 'a t

type ('a, 'b) view = Nil | Cons of 'a * 'b
val view : 'a t -> ('a, 'a t) view
val unview : ('a, 'a t) view -> 'a t
val map : ('b -> 'c) -> ('a, 'b) t -> ('a, 'c) t
end

Now, if you have a module that implements a sequence, it just needs to
have an implementation of this signature as a submodule. I'll use
join lists as an example:

module type JOIN_LIST =
sig
type 'a jlist

val empty : 'a jlist
val one : 'a -> 'a jlist
val join : 'a jlist -> 'a jlist -> 'a jlist

module View : SEQUENCE_VIEW with type 'a t = 'a jlist
end

module JList : JOIN_LIST = ...

Now, whenever you use a join list, you can write functions that
iterate over it as if it were a cons list, using the view interface:

module Test =
struct
open JList
open View

let x = join (one "foo") (one "bar")
let y = join x x
let z = join y y

let rec concat js =
match map view (view js) with
| Nil -> ""
| Cons(s, Nil) -> s
| Cons(s, rest) -> s ^ ", " ^ (concat (unview rest))
end

The concat function takes a join list of strings, and returns a
comma-sep