Poly/ML correctly allows the following binding:
val op :: (h, t) = [1, 2, 3, 4];
However it also allows brackets around the constructor:
val (op ::) (h, t) = [1, 2, 3, 4];
My reading of the syntax in the definition of Standard ML is that the latter form should not be allowed. Am I right?
Regards,
Rob.
I am pretty sure that the definition states somewhere that any syntactic phrase may be enclosed in parentheses. It is paradoxical to have the semantics of the language defined so carefully when the syntax definition is not up to the standards of the 1960s. Larry
On 10 May 2008, at 14:04, Rob Arthan wrote:
Poly/ML correctly allows the following binding:
val op :: (h, t) = [1, 2, 3, 4];
However it also allows brackets around the constructor:
val (op ::) (h, t) = [1, 2, 3, 4];
My reading of the syntax in the definition of Standard ML is that the latter form should not be allowed. Am I right?
Rob,
On Saturday 10 May 2008 15:04, Rob Arthan wrote:
However it also allows brackets around the constructor:
val (op ::) (h, t) = [1, 2, 3, 4];
My reading of the syntax in the definition of Standard ML is that the latter form should not be allowed. Am I right?
I don't have a copy of the language definition on my desk (how about making that available on the Internet, by the way?), but the syntax charts in Paulson's "ML for the Working Programmer" (on page 417f.) allow the derivation
Pattern -> Atomic Pattern -> ( Pattern )
(if only to allow a tuple of patterns, e.g. "val (a, b) = ...").
On a side note, I noticed earlier that different SML implementations treat (op *) differently, as *) could also mark the end of a comment. I'm not sure what the standard says about this either.
Tjark
Rob,
On Tuesday 13 May 2008 13:45, Tjark Weber wrote:
On Saturday 10 May 2008 15:04, Rob Arthan wrote:
val (op ::) (h, t) = [1, 2, 3, 4];
My reading of the syntax in the definition of Standard ML is that the latter form should not be allowed. Am I right?
I don't have a copy of the language definition on my desk (how about making that available on the Internet, by the way?), but the syntax charts in Paulson's "ML for the Working Programmer" (on page 417f.) allow the derivation
Pattern -> Atomic Pattern -> ( Pattern )
to prevent misunderstandings, I should add that this is of course not sufficient to derive "(op ::)" in the above context. So, according to a literal reading of those syntax charts, you're right.
But then again, these charts might just not be very precise about optional parentheses.
Tjark
Tjark Weber wrote:
On Saturday 10 May 2008 15:04, Rob Arthan wrote:
However it also allows brackets around the constructor:
val (op ::) (h, t) = [1, 2, 3, 4];
My reading of the syntax in the definition of Standard ML is that the latter form should not be allowed. Am I right?
I don't have a copy of the language definition on my desk (how about making that available on the Internet, by the way?), but the syntax charts in Paulson's "ML for the Working Programmer" (on page 417f.) allow the derivation
Pattern -> Atomic Pattern -> ( Pattern )
(if only to allow a tuple of patterns, e.g. "val (a, b) = ...").
I think the defining document, which is presumably the one Rob's using, is The Definition of Standard ML (Revised) from 1997. It would be nice to see this on the web but since it's published by MIT Press it will be up to the publishers and authors to decide if it should be made available.
The relevant syntactic constructs, omitting other options, are: atpat ::= <op> longvid (pat1, ..., patn) (pat)
pat ::= atpat <op>longvid atpat pat1 vid pat2
That seems to suggest that while <op> longvid can be parenthesised it can only then be a nullary constructor. So val (op nil) = [] val (op :: (h,t)) = [1,2,3] are valid but val (op ::) (h,t) = [1,2,3] is not.
On a side note, I noticed earlier that different SML implementations treat (op *) differently, as *) could also mark the end of a comment. I'm not sure what the standard says about this either.
To be honest, I'm not sure either. The original 1990 Definition of Standard ML says, "An unmatched comment bracket should be detected by the compiler." The Commentary on Standard ML (1991) expands this and says, "Even an unmatched *) should be detected by the compiler. Thus the expression (op *) is illegal." The 1997 version though, says, "An unmatched (* should be detected by the compiler." This seems to imply that in ML 97 '(op *)' is legal and that's the interpretation that Poly/ML takes.
David.
On Tuesday 13 May 2008 1:44 pm, David Matthews wrote:
Tjark Weber wrote: ...
The relevant syntactic constructs, omitting other options, are: atpat ::= <op> longvid (pat1, ..., patn) (pat)
pat ::= atpat <op>longvid atpat pat1 vid pat2
That seems to suggest that while <op> longvid can be parenthesised it can only then be a nullary constructor. So val (op nil) = [] val (op :: (h,t)) = [1,2,3] are valid but val (op ::) (h,t) = [1,2,3] is not.
I agree. Pace Larry, I can't find anything in the definition of Standard ML to suggest that parentheses should be allowed here. Moscow ML, MLton and Standard ML of New Jersey all reject this syntax.
On a side note, I noticed earlier that different SML implementations treat (op *) differently, as *) could also mark the end of a comment. I'm not sure what the standard says about this either.
To be honest, I'm not sure either. The original 1990 Definition of Standard ML says, "An unmatched comment bracket should be detected by the compiler." The Commentary on Standard ML (1991) expands this and says, "Even an unmatched *) should be detected by the compiler. Thus the expression (op *) is illegal." The 1997 version though, says, "An unmatched (* should be detected by the compiler." This seems to imply that in ML 97 '(op *)' is legal and that's the interpretation that Poly/ML takes.
The wording there is indeed very vague. For the record MLton agrees with Poly/ML in allowing (op *) while Moscow ML and Standard ML of New Jersey disallow (op *).
Regards,
Rob.