8

I'm not sure why F# seems to allow the definition of a class without any constructors. I mean, it would be impossible to instantiate an object of the class. Shouldn't the language spec treat this as illegal behavior?

For example, I can define the class

type myClass =
    class
        member this.x = 0
    end

myClass seems to have the type

type myClass =
    member x: int

But it would not be instantiable.

William Barbosa
  • 4,936
  • 2
  • 19
  • 37
Shuheng Zheng
  • 267
  • 1
  • 10

3 Answers3

9

In my experience, the object-oriented features of F# can sometimes be less elegant than what C# enables you to express. The above question could be one example; another example is automatically implemented mutable properties.

Most people (including me) seem not to care, because we rarely use those features. The object-oriented features of F# mainly exist in order to enable interoperation with other .NET code, so while they can be useful, they aren't the important parts of the language. My guess is that no one thought of implementing that compiler check because it wouldn't provide much value. As soon as you'd attempt to use myClass, you'd notice that something was wrong.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
3

When you create a class with no constructors (in other words, a class that can't be instantiated) you are basically creating an static class*.

In C# you can use the static keyword to allow the compiler to check if you have instance members or not. In F# you don't have such check in compile time.

* Sort of. The proper definition of a static class is one that can't be instantiated or inherited and only has static methods.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
William Barbosa
  • 4,936
  • 2
  • 19
  • 37
  • To define a class that is represented as "static class" in the object browser, write `[] type C = class end`. However, even in this case, F# currently allows you to add instance members to the class... – Marc Sigrist Oct 09 '15 at 11:34
0

It's been a while, but I'll add that sometimes, "a class that can't be instantiated" is exactly what you want for one reason or another. In my use case, by using a type that can't be instantiated, I can ensure that the only way to get a valid object of that type is within the scope of a lambda -- it's a way of implementing lambda type-checking in domain-specific languages.

linkhyrule5
  • 871
  • 13
  • 29