On 27 Mar 2012, at 22:41, Phil Clayton wrote:
For example, given
infix & datatype t = &
Poly/ML (5.4) reports:
Warning-(&) has infix status but was not preceded by op.
So Poly/ML seems to prefer the use of 'op' in a datatype declaration. However, if 'op' is present, i.e.
datatype t = op &
SML/NJ (110.73) reports:
stdIn:2.14-2.16 Warning: unnecessary `op'
Generally, it is a good principle to avoid warnings but, in this particular respect, that isn't possible for code that is shared between Poly/ML and SML/NJ. Note that MLton (20100608) doesn't warn either way.
Does the Standard provide any guidance about the use of op here?
All it says is "The only required use of op is in prefixing a non-infixed occurrence of an identifier vid which has infix status; elsewhere op, where permitted, has no effect". vid here is the syntactic category of value identifiers. Then at various points in the syntax an optional op appears (written <op>). The relevant point in the syntax here is in the production for conbind, the thing to the right of the equals signs in a data type declaration. It looks like this:
conbind = <op> vid < of ty> < | conbind>
It is a bit odd to allow op here if it is never necessary, so I can see the Poly/ML point of view, suggesting that it is good style to put it in. On the other hand, there is nothing else other than a vid that can appear immediately after the equauls signs in datatype declaration, so I can see the SML/NJ point of view too. However, SML/NJ isn't consistent. What I have just said about the equals sign in a data type declaration is equally try of a value declaration. If you try:
val x = &;
or (after starting again and reentering the infix declaration)
val & = 99;
Poly/ML will give you a warning, while SML/NJ will reject these both as errors, which I think is wrong.
Can anything be done to align the warnings from Poly/ML and SML/NJ in this respect?
The standard is unclear, since it fails to define what "non-infixed occurrence" means. It looks like SML/NJ is taking it to mean an occurrence where a pattern or an expression is expected, while Poly/ML is taking it to mean an occurrence where it would be possible to parse the vid as infix, but the non-infix construal is wanted. However Poly/ML is not completely consistent about this as shown in the following transcript.
infix &;
fun &(x,y) = x + y + 1;
Warning-(&) has infix status but was not preceded by op. val & = fn: int * int -> int
&(1,2);
Warning-(&) has infix status but was not preceded by op. val it = 4: int
exception &;
exception &;
fun f _ = ();
val f = fn: 'a -> unit
f(&);
Warning-(&) has infix status but was not preceded by op. val it = (): unit
(f &);
Error-<identifier> expected but ) was found
I would have expected Poly/ML to give a warning on the exception binding. I also can't explain why it doesn't allow (f &). Maybe David can give a more accurate explanation of when Poly/ML requires op.
Regards,
Rob.