fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Multiple Constructors require different syntax

Open ChrSteinert opened this issue 7 years ago • 2 comments

Originally from here: https://github.com/fsharp/fsharp/issues/827

When adding constructors to to an F# class the required syntax changes, e.g. is different for the last constructor (for single parameter .ctors).

Repro steps

While the following code is valid…

type A (a : int option, b : string option) =
    new a = A (a, None)
    member __.X = ""

… adding another .ctor with one parameter in a similar fashion does not validate anymore:

type A (a : int option, b : string option) =
    new a = A (a, None)
    new b = A (None, b)
    member __.X = ""

The error on the = on the third line is: error FS0010: Unexpected symbol '=' in expression

Known workarounds

Parameters of the not-last .ctor must be wrapped in braces. For a yet bigger example this gives:

type A (a : int option, b : string option, c : float option) =
    new (a) = A (a, None, None)
    new (b) = A (None, b, None)
    new c = A (None, None, c)
    member __.X = ""

(Also omitting the first brace (in new (a)) does break the thing.)

Related information

Observed on Win 10 in VS and Ionide with latest releases installed.

Severity is most probably low.

ChrSteinert avatar Apr 09 '18 07:04 ChrSteinert

Out of curiosity I wanted to know whether this happened in VS2015 as well. The error is a bit clearer (i.e., not on the equal-sign, but on the whole constructor), however still not very helpful:

image

Btw, I cannot repro the "unexpected symbol" error, I receive this (15.7 Update 2):

image

abelbraaksma avatar Apr 09 '18 11:04 abelbraaksma

The correct thing is always to use new (arg) = .... Parentheses are required here.

My reply on fsharp/fsharp:

@ChrSteinert This is a parser thing where it is thinking new c is an expression, e.g. new Object(). In the first line it is not seen as ambiguous because there is no possibility of an expression at that point in the syntax (it's one of the only points where that's not possible).

We could give a warning since I can see how you could hit this. The warning would ask the user to write new (arg1, ... argN) in constructor definitions, always using parentheses.

dsyme avatar Apr 12 '18 13:04 dsyme