[MLton] (no subject)
Henry Cejtin
henry@sourcelight.com
Mon, 9 Feb 2004 01:10:36 -0600
I'm sorry that I haven't had any time to input more useful descriptions of my
points in the MLton User Guide, but here is some text covering the earlier
ones.
Ok, here are my comments on the MLton User Guide. I will describe positions
on the 20040106 Postscript version.
Over full copyright line on title page should be on multiple lines.
In the `Installation section on page 3 the missing leading `/' in the file
names is confusing. I know that this is to indicate that it is relative
to where you install MLton, but it isn't clear. Also the statement that
it installs `in root' is confusing. It installs things under root, but
not at the top level.
The example on page 3 of -link-opt is bad because unless you change
/etc/ld.so.conf, /usr/lib is looked in by default.
The `supports the full SML 97 language' paragraph at the top of page 5 should
mention (or at least refer) to the known deviations of MLton, like
fun f 0 y =
case y of
3 => "one"
| _ => "two"
| f x y = "three"
In the `complete basis library' I think that it is worth mentioning that we
track the new spec and that we include many optional things like IntInf.
(Perhaps just my prejudice.)
In the `excellent running times' section on page 5, I don't think that the
shootout web page is alive any more.
In the `unboxed native arrays' section on page 5, it might be worth
mentioning here that monomorphic arrays are just arrays in MLton.
In the `runtime system supports large arrays' on page 5, can we really handle
arrays (of 1, 8 or 16 bit objects I assume) up to 2^31 - 1 now?
Excellent.
In the `standalone executables' section on page 5, you want to say:
You don't need any thing except the a.out and `standard' shared libraries
by default. (Here standard means not coming from MLton and already
on most systems.)
You can get away with just the a.out because MLton can generate
statically linked executables if desired.
In the `signal handlers' section on page 6, the use of the word `thread' is
confusing. It isn't something like a POSIX thread, but a MLton
construction. I don't know what exactly to say, but as is it makes it
seem that MLton has `real' threads, which it does not.
In the first paragraph of `Compile-time options' on page 8, what about .a and
.so files?
In the `-cc-opt option' section on page 8, doesn't the option also get used
for .c (and .s) files even in the native mode?
In the `-export-header' section on page 8 you should mention that setting it
to true not only outputs a C header file, it also stops compilation after
doing so. I.e., it does NOT do the compile. Actually that choice seems
a bit strange since if compile time is huge then you have to do it twice
(although I assume that the true case is quicker).
In the `-inline' section on page 8 you have to at least say something about
the units, even if it is only that they are arbitrary. At the moment it
doesn't even say that the threshold is a size threshold, or an very rough
estimate of that.
In the `-runtime' section on page 9, you don't mention in discussing multiple
uses that it is the LAST value of any parameter which dominates. Also
you have to say that command line arguments (via @MLton) are processed
AFTER -runtime ones so that the result of -runtime can be overridden.
Speaking of these multiple things, it is completely wrong and bad that
you can use multiple
@MLton ... --
in a single run. (Discussed on page 10 in section 4.2 `Runtime system
options'.) That means that it is absolutely impossible to call a MLton
executable with a first argument of `@MLton' and a later argument of
`--'. In particular, it is not possible to pass arguments to a MLton
executable unless you KNOW that they are NOT going to contain `@MLton'.
If you only allow 0 or 2 `@MLton's then I can wrap a MLton executable in
a shell script:
exec mlton-executable @MLton -- "$@"
which will guarantee that any command line arguments are simply passed to
the actual ML code and not eaten by the runtime system.
I know that it is pedantic, but I think that this is actually an
important point. It is almost an argument for additionally having
another flag which says that the `@MLton' processing of the runtime
should NOT be done. This is unneeded, but requires using a shell
trampoline as above to get the effect. With the current multiple
`@MLton's being allowed, it is unachievable at all.
I would say that the way to do it is to have
@MLton ... --
to mean NO MORE runtime arguments, while
@MLton ... ++
to mean that the first argument after the ++ will also be examined, and
if it is @MLton then those are runtime args.
In the `-show-basis' and `show-basis-used' section on page 9, change
`displays' to `prints to standard output' to be more clear and in sync
with -export-header. Also it is rather confusing because -show-basis
causes the types to be displayed (but NOT the basis library itself) while
-show-basis-used just lists the things used, but not their types.
In connection with this, I would love to have an option which caused
MLton to write out the types for my code (like -show-basis does for the
basis). It would be a very convenient place to get a summary of some
code.
Note, for both of these options and also -export-header, it might make
more sense to have them accept a file name instead of the true/false.
This would allow them to be combined. Right now it seems that if you
turn both -show-basis and -show-basis-used on then only the latter is
done with no error message.
In the `-no-load-world' section on page 11 it is worth mentioning that the
reason for this is just for set-uid programs.
In the `-ram-slop' section on page 11 it is worth mentioning that x should
probably be no more than 1 and that making it strictly less than 1 is to
account for space used by the OS and other programs running at the same
time.
The fact that _import and _export introduce phrases which are expressions
makes the choice of a trailing semicolon very bad. This must mean that,
for example, in
val z = _import "foo": real * char -> int;
the semicolon is part of the expression, right? Yes, an experiment
reveals that the following is rejected by MLton:
_import "foo": real * char -> int;
with a syntax error at EOF, while
_import "foo": real * char -> int;;
is legal.
I understand the need to have a terminator for these expressions because
they would otherwise end with a type which would make parsing tricky, but
it seems that some other item would be much better. How about
_import "foo": [real * char -> int]
or use `{' and `}' or a trailing `end'.
All of this really became apparent in the example in the `Calling from C
to SML' section on page 12:
_export "foo": real * char -> int;
(fn (x, c) => 13 + Real.floor x + Char.ord c)
Yikes.