[MLton] Re: [MLton-devel] cvs commit: new front end

Matthew Fluet fluet@cs.cornell.edu
Sat, 18 Oct 2003 17:44:05 -0400 (EDT)


> The idea behind the use of _ is to show exactly where the two types
> are different.  This is an if and only if.

Like Henry, I appreciate the detailed explaination of the motivation.  The
error messages make a lot more sense now.

I think part of the "problem" is that they as error messages for Standard
ML; When in "SML mode", I think of "_" as wildcard that matches anything.
And, in SML patterns, there isn't a notion of "the match for this pattern
is the same as the match for that pattern", so I automatically assume that
every _ in a type error is independent of every other.  I see that that is
the wrong way to think of the errors.

> Given this, I'd like to clarify what I think you mean by
>
> > especially when fixing the immediate type error can simply require
> > fixing another one down the line:

You inferred my thoughts correctly.

> Then we will see
>
> 	(_ * _) * _ * char
> 	(_ * _ * _) * _ * string
>
> So the _'s in the inner tuple mean that we didn't even get a chance to
> unify these types, since an outer type constructor was not unifiable,
> while the _'s in the second component of the outer tuple mean that
> these two types unified.

I think this is a little confusing, because it uses "_" for two different
meanings.

> We could reserve _ to be used for types that
> match, and always show types that we didn't get a chance to unify.
> So, we would see
>
> 	(real * real) * _ * char
> 	(real * int * bool) * _ * string

That's ok., but I can see that it would be much less useful for large
types.


> optimally  wrong.   Perhaps  one solution would be to use type abbreviations.
> I.e., if you have a node in the type tree which unifies and is `somplicated'
> just  make  up a type name for it (like a, b, c) and print out the definition
> and then the two conflicting types.

I like this, although I would suggest printing the conflicting types
first, then the definitions.  Also, I was thinking "_N" would make a good
type name, because it can't conflict with any SML type identifier, and
would look close to the current scheme.  Then, we might see something
like:

expects: (_1 * _1) * _2 * char
but got: (_1 * _2 * _3) * _2 * string
where: _1 = real
       _2 = int
       _3 = bool

Hmm.  The char and string don't quite stand out as much, which is too bad.
But, if this behaviour is controlled by a flag, I could see it being
useful for type-errors where you don't really know what's wrong.  That is,
when you need to, get the SML/NJ style behaviour where you see all the
information available.  Of course, if it's flag controlled, and you've
only run with that flag because you can't figure out what's wrong, then
we might as well inline all the _Ns.

I guess I'll just need to write some more buggy SML code to see what type
errors show up. ;-)


_______________________________________________
MLton mailing list
MLton@mlton.org
http://www.mlton.org/mailman/listinfo/mlton