[MLton] can mlbasis rename the top-level?
Matthew Fluet
fluet@cs.cornell.edu
Tue, 6 Sep 2005 21:28:19 -0400 (EDT)
> Quoting Stephen Weeks <sweeks@sweeks.com>:
>>> Or take "}>}" as the closing delimiter.
>>
>> :-). Yes, that definitely is easiest, for all tools involved. I'm
>> fine with that if others are.
>
> I'm not convinced that implementation difficulty should be the most
> important concern.
It's not just work on the developers part. The more complicated the
implementation, the harder it is to get it right. And, particularly with
lexing/parsing, it is quite easy to get it wrong in ways that aren't
particularly illuminating to the end user.
> I'd rather have a coherent language than one that
> is the easiest to parse.
That's a fair point, but I don't think that symbolic delimiters breaks the
coherence in an unacceptable way. I look at it from this point of view:
the ML Basis System is there to provide a mechanism for programming in the
very large, where you need a way to organize potentially conflicting
name-spaces in libraries. It is not there to be your default programming
environment. So, you pay a small cost (in this case, the visual
delimiter) to use it for a secondary purpose.
> The MLB syntax already uses mostly keywords
> as delimiters. If symbolic delimiters are preferred, then is it really
> that much more difficult to use plain parentheses, ( and ), as
> delimiters like ML-Yacc does (but recognizing string literals and
> comments)?
>From the implementation point of view, no it isn't any more difficult.
But, think of it from the user's point of view. Suppose I have:
local
$(SML_LIB)/basis/basis.mlb
$(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb
in
(
structure IntOptionRedBlackMap =
RedBlackMapFn(type ord_key = int option
val compare = fn (x, y) =>
(case (x, y) of
(NONE, NONE) => EQUAL
| (NONE, SOME y) => LESS
| (SOME x, NONE) => GREATER
| (SOME x, SOME y) => Int.compare (x, y))
)
end
Did you catch the unclosed parethesis? If so, then you are a better
reader than I. (And, yes, emacs would give a hint as well.) But, suppose
you sent this to mlton. What's likely to happen is that you completely
throw the parser off. Worse, if you had an extra close parenthesis in the
middle of the SML code (i.e., ending the embedded SML early), then you're
likely to have a horribly opaque MLB parse error pointing into the middle
of what is manifestly SML code.
On the other hand, it's very easy to verify that {<{ and }>} properly
delimit the SML code. Concerns about those tokens appearing in the
embedded SML in comments or string constants notwithstanding, it's really
easy to lex the contents into string and let the SML parser have its way.
Similarly, if you try counting {local,let,sig,struct}...end blocks, an SML
parse error might manifest itself as an inexplicable MLB parse error.
Yes, these would go away if you merged the grammars, but its not clear to
me that you can even merge the grammars in a reasonable manner that
handles the extra MLB keywords.