[MLton] sequenceNonUnit

Vesa Karvonen vesa.karvonen@cs.helsinki.fi
Fri, 29 Jul 2005 01:22:32 +0300

Implementing sequenceNonUnit seems to be a bit more complicated than I
initially thought. The current implementation of sequenceUnit (not
sequenceNonUnit) simply unifies the type of the "ignored expression"
with unit. While it is a simple technique, it has at least an undesirable
consequence. Namely, type errors may point to the wrong place. Consider
the following simple program:

  fun latentError dummy = while false do dummy (* dummy = "ignored expression" *)
  val () = latentError 1

MLton currently gives the following error (with 'sequenceUnit true'):

  Error: sequence-non-unit.sml 2.10.
    Function applied to incorrect argument.
      expects: [unit]
      but got: [int]
      in: latentError 1
  compilation aborted: parseAndElaborate reported errors

Considering the Wiki explanation

  "sequenceUnit {false|true} 

      If true, then in the sequence expression (e1; e2), it is a type
      error if e1 is not of type unit. This can be helpful in detecting
      curried applications that are mistakenly not fully applied. To
      silence spurious errors, you can use ignore e1. "

it seems to me that either the current implementation of 'sequenceUnit
true' does not capture the actual intention or the Wiki explanation gives
a (somewhat) wrong impression of the intended semantics.

Anyway, similar use of unify to implement 'sequenceNonUnit
{ignore|warn|error}' or, in particular, to implement 'sequenceNonUnit
warn', would not work.

Thinking about it briefly, I came up with the following implementation
scheme. During the recursive type inference step, the inferred type (which
may be a variable) of the "ignored expression" is saved to a list (along
with the necessary info to give proper diagnostics). After type inference,
a diagnostic would be given for each non-unit type in the list. This way
the diagnostic given for the latentError example above, and other similar
cases, would (properly) point to the "ignored expression".

Would this work and capture the intention of sequenceNonUnit?