8

Given a class such as:

type MyClass() =
    member this.Greet(x) = printfn "Hello %s" x

is it appropriate to initialize instances using

let x = new MyClass()

or without the new?

Also, when is the use of a new constructor more useful than a do binding with parameters supplied to the type definition?

Muhammad Alkarouri
  • 23,884
  • 19
  • 66
  • 101
  • See also duplicate: http://stackoverflow.com/questions/1829665/should-i-use-new-type-or-just-type-for-calling-a-constructor – elmattic Aug 12 '10 at 17:36

2 Answers2

9

My pattern in F# for using new is to only do so when the type implements IDisposable. The compiler special cases this use and emits a warning if new is omitted.

So in your case I would not use new. But with the following I would

type OtherClass() =
  ...
  interface System.IDisposable with 
    member this.Dispose() = ...

let x = new OtherClass()
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I wonder why this came about. Wouldn't it be clear by using the `use` keyword? – ChaosPandion Aug 03 '10 at 17:17
  • 1
    @ChaosPandion, no idea really. I'm sure Brian will be along shortly to provide the full history – JaredPar Aug 03 '10 at 17:19
  • @ChaosPandion: there are circumstances where you don't want to create a new IDisposable with a use binding, like when you want it to escape the function that creates it. – Alex Humphrey Aug 03 '10 at 17:43
  • 2
    I almost always say `new`. I think if you have a function with the same name as a class, then you need `new` to disambiguate. I don't know of any style guideline here. – Brian Aug 03 '10 at 18:08
  • @Brian, why does the F# compiler chose to enforce this specific case? – JaredPar Aug 03 '10 at 18:12
  • @Brian: Interesting. The reason I am leaning towards not using `new` is precisely to have the ambiguity between class creation and having a function that returns instances (possibly as a factory). This kind of ambiguity looks to me similar in some sense to the ambiguity profitably used in a name that can be imported from multiple namespaces or modules. Is there anything wrong with that? – Muhammad Alkarouri Aug 04 '10 at 01:27
  • Sure, if you want to do `type Foo() = ...` followed by `let Foo() = new Foo()` as a protective abstraction, that's fine. – Brian Aug 04 '10 at 02:52
4

F# spec:

68 6.5.2 Object Construction Expressions An expression of the form new ty(e1 ... en) is an object construction expression and constructs a new instance of a type, usually by calling a constructor method on the type.

14.2.2 Item-Qualified Lookup The object construction ty(expr) is processed as an object constructor call as if it had been written new ty(expr).

F# compiler issues a warning if instance of type that implements IDisposable is created with Ty() syntax omitting new keyword. Spec says nothing about this fact, however I think it should definity should be mentioned.

desco
  • 16,642
  • 1
  • 45
  • 56