The “nullary constructor feature” allows you to use a constructor name with parentheses in a match or build pattern if it has no children (i.e. is nullary). It seems this notation is from the ATerm library.

The problem with the feature is that the name spaces of constructors and term variables in Stratego overlap significantly (if not completely). So you can end up accidentally using a constructor left from the AsFix constructors which is in the standard libraries of Stratego, even though you wanted to use a variable name.

Currently the compiler issues a warning for every variable it turns into a nullary constructor (#555: Assigning to variable with a construct name should give warning, #774: Use parentheses for Nullary constructors ). #774 advises to use parentheses already, and a warning indicates preferred usage. In #555 the suggestion was already to drop support for nullary constructors, but apparently @eelcovisser disagreed at the time.

The warning is nice, but can easily get lost in the compiler output. Usually you’d expect sure a problem to be highlighted in the Stratego editor, so you may not look at the compiler output when your Stratego program surprisingly fails somewhere. For this reason and for being warned about it, I could classify this feature as a footgun that harms the language more than it helps.

My proposal is to drop this feature. If there are concerns about backward-compatibility we can put the feature behind a flag and have it off by default. I just opened a PR again the strategoxt to remove the last uses of this feature in Spoofax (according to the latest build log).

I’m willing to implement this proposal. What I want to know is if anyone has objections? Are there other large projects using Stratego that would be heavily impacted? Does this mess up the incremental compiler work?

Submitted by Jeff Smits on 22 August 2016 at 12:56

On 23 August 2016 at 03:55 Eelco Visser commented:

Fine with me; but make sure that (1) the editor gives a clear error message, (2) the Stragego/XT and Spoofax builds are not affected.

On 23 August 2016 at 09:31 Jeff Smits commented:

I’m working on (2) with my PR.
As for (1): My proposal was to drop the feature that does left := "hi" => left() := "hi", which means that left is seen as a variable instead. Which means there is no error the editor needs to give, because left will still be legal, but just be a variable instead of a reference to a nullary constructor.
Given that clarification, is it still ok to go through with it?

On 23 August 2016 at 14:01 Eelco Visser commented:

but that may break existing code, where left is a constructor, right?

The editor should at least give a warning still about this possible confusion.

On 23 August 2016 at 14:33 Jeff Smits commented:

but that may break existing code, where left is a constructor, right?

Yes, that’s why I’m building Spoofax locally and fixing all occurrences where the current warning about nullary constructors without parentheses is given. That, and an announcement about the change will hopefully be enough? I can still reuse the code in the compiler to issue a warning or notice when it finds variables that were previously considered constructors if you prefer?

The editor cannot completely warn against this thing anyway. It only takes explicit imports into account, so it wouldn’t know that left is defined in the standard library as a constructor. Currently the editor gives an error on usage of nullary constructors without parentheses when they are built (because it considers it a variable and can’t find it), but doesn’t say anything about it when they are matched against (again, because it’s a bit simple and sees it as a variable).

On 23 August 2016 at 15:38 Jeff Smits commented:

There is another way to solve this whole issue with confusion between constructors and variables: rename the legacy constructors that start with lowercase to starting with uppercase. Then we can change the language to reject constructors with lowercase starting names and warn again strategies and term variables that start with uppercase. Non-legacy (SDF-generated) constructors already start with uppercase so it’s unlikely that any constructors outside of Spoofax has lowercase constructors. We can even put the list of renamed constructors in the new release to give a special message for people using those constructors.

Log in to post comments