I fixed a bug recently [831] where I'd reorganised some code and the wrong identifier was being picked up. It would have been immediately apparent if the compiler had detected that an identifier was unreferenced so I've now added that check. In the current SVN version identifier checking is off by default but can be turned on with PolyML.Compiler.reportUnreferencedIds := true; The compiler will then report identifiers that are unreferenced as a warning.
Currently, this applies only to value identifiers, excluding value constructors. An identifier is referenced if it used anywhere, which includes a recursive use, exported as a top-level value or used in the result of a structure or functor. When used in a structure or functor an identifier must be mentioned in the signature to be considered as referenced.
Reference information isn't currently available through the IDE protocol but that can be added.
Enabling unreferenced identifier checking on the compiler itself showed up a minor bug so it's already proved useful.
David
David,
This looked like a really useful feature so I thought I'd try it out. Unfortunately, I have code that fails as in the cut-down example below:
Poly/ML 5.3 Enhanced Reporting Testing
val rec f = (fn x => ());
Error-Recursive declaration is not of the form `fn match' Found near val rec f = (fn x => ()) Static Errors
If this is intended, I presume the enhanced reporting includes a check that disallows the brackets around the right-hand side of the declaration. I note that hamlet also says that this is an error, so there is support for reading the standard that way. I suspect I will not be alone in having a fair amount of code that doesn't conform.
This looks like another place where Standard ML imposes unintuitive constraints that make it hard to write readable, maintainable code. The reason for using "val rec" rather than "fun" in the real code is that I want to give a type constraint on the function (which for no obvious reason is not allowed in a "fun" binding); the reason for the brackets is that the declaration is long and I want to be able to use bracket matching to find the end.
Regards,
Rob.
Rob, Considering then ML semantics is so carefully defined the syntax is really a mess. There are lots of informal comments which make it really quite difficult to understand exactly what is allowed and what is not.
The ML90 definition says "For each value binding pat = exp within rec, exp must be of the form fn match, possibly constrained by one or more type expressions". The ML97 definition removed the final clause so implying that type constraints were no longer allowed.
Poly/ML has always allowed type constraints on recursive bindings and also, by default, parentheses. A recent change has meant that parentheses are now included in the parse tree which is why the check failed. Because there doesn't seem to be any logical reason to exclude parentheses I've now changed the check to allow parentheses.
By the way, a type constraint is allowed on a fun binding but it applies only to the result type not to the type of the function as a whole.
Regards, David
Rob Arthan wrote:
This looked like a really useful feature so I thought I'd try it out. Unfortunately, I have code that fails as in the cut-down example below:
Poly/ML 5.3 Enhanced Reporting Testing
val rec f = (fn x => ());
Error-Recursive declaration is not of the form `fn match' Found near val rec f = (fn x => ()) Static Errors
If this is intended, I presume the enhanced reporting includes a check that disallows the brackets around the right-hand side of the declaration. I note that hamlet also says that this is an error, so there is support for reading the standard that way. I suspect I will not be alone in having a fair amount of code that doesn't conform.
This looks like another place where Standard ML imposes unintuitive constraints that make it hard to write readable, maintainable code. The reason for using "val rec" rather than "fun" in the real code is that I want to give a type constraint on the function (which for no obvious reason is not allowed in a "fun" binding); the reason for the brackets is that the declaration is long and I want to be able to use bracket matching to find the end.
On 31 Aug 2009, at 11:53, David Matthews wrote:
Rob, Considering then ML semantics is so carefully defined the syntax is really a mess. There are lots of informal comments which make it really quite difficult to understand exactly what is allowed and what is not.
The ML90 definition says "For each value binding pat = exp within rec, exp must be of the form fn match, possibly constrained by one or more type expressions". The ML97 definition removed the final clause so implying that type constraints were no longer allowed.
Poly/ML has always allowed type constraints on recursive bindings and also, by default, parentheses. A recent change has meant that parentheses are now included in the parse tree which is why the check failed. Because there doesn't seem to be any logical reason to exclude parentheses I've now changed the check to allow parentheses.
Thank you! Now I get exactly what I wanted:
Poly/ML 5.3 Enhanced Reporting Testing
PolyML.Compiler.reportUnreferencedIds := true;
val it = () : unit
val rec f = (fn x => ());
Warning-Value identifier (x) has not been referenced. val f = fn : 'a -> unit
By the way, a type constraint is allowed on a fun binding but it applies only to the result type not to the type of the function as a whole.
The problem is that you can't constrain the type of the function as a whole. So I can't use "fun" to get the equivalent of this:
type 'a property = 'a -> bool; val (even : int property) = fn i => i mod 2 = 0;
(where I want the type constraint for readability.)
Regards
Rob.
Regards, David
Rob Arthan wrote:
This looked like a really useful feature so I thought I'd try it out. Unfortunately, I have code that fails as in the cut-down example below: Poly/ML 5.3 Enhanced Reporting Testing
val rec f = (fn x => ());
Error-Recursive declaration is not of the form `fn match' Found near val rec f = (fn x => ()) Static Errors If this is intended, I presume the enhanced reporting includes a check that disallows the brackets around the right-hand side of the declaration. I note that hamlet also says that this is an error, so there is support for reading the standard that way. I suspect I will not be alone in having a fair amount of code that doesn't conform. This looks like another place where Standard ML imposes unintuitive constraints that make it hard to write readable, maintainable code. The reason for using "val rec" rather than "fun" in the real code is that I want to give a type constraint on the function (which for no obvious reason is not allowed in a "fun" binding); the reason for the brackets is that the declaration is long and I want to be able to use bracket matching to find the end.
polyml mailing list polyml@inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml