23

In all examples of F# classes and records I see that records an classes are instantiated/created via new keyword or simply by the type name.

So for example if I have this record:

type MyRecord = {field1: int; field2:int}
let myvar = {new MyRecord with field1 = 3 and field2 = 3}
let myvar2 = {MyRecord with field1 = 1 and field2 = 2}
let myvar3 = {field1 = 34; field2 = 23}

They seem to be all the same. It is the same for this example too:

type MyClass(x: int) =
   let mutable xx = x
let myvar = MyClass(12)
let myvar2 = new MyClassw(234)

Well what is new for?? Thnkyou

Ah... I know that there are answers for the question of new regarding classes, but there is no mention for records. Furthermore, I do not understand why new should be an optional and abosultely indifferent keywork when constructing classes? Is it possible that using new or not using it for classes does change nothing?

Andry
  • 16,172
  • 27
  • 138
  • 246

1 Answers1

28

The new keyword is typically not used to instantiate F# records. The first example is the OCaml-ish syntax for record declarations:

let myvar = {new MyRecord with field1 = 3 and field2 = 3}
// Normal F#: let myvar = { MyRecord.field1 = 3; field2 = 3}

The second example doesn't compile any more:

// Not F#: let myvar2 = {MyRecord with field1 = 1 and field2 = 2}

For classes, you can always omit new. However, you get a compiler warning if you instantiate an IDisposable class without using the new keyword.

// These two are the same
let myvar = MyClass(12)
let myvar2 = new MyClass(234)

// Compiler warning
let f = FileStream("hello.txt", FileMode.Open)

// No warning
use f = new FileStream("hello.txt", FileMode.Open)

Edit: In response to your comment -

isn't there a rule or s rationale why new is so "flexible"? Why is it the same using or not using new for classes

new is optional - I'm not aware of a rationale for making it flexible; it would be nice if there was some guidance one way or the other. (My preference is to never use new, except in response to the compiler warning.)

why do I get a compiler warning when implementing IDisposable

Since I never use new normally, I take this to be the compiler's way of reminding me to write use or using when I allocate an IDisposable.

and why records do not use the second syntax I wrote before?

{ new MyRecord with ... } is the Haskell syntax. It may have been valid in one of the F# compiler betas, but it doesn't parse on F# 2.0. (Why do you think this ought to be valid?)

I'm trying to find a general logic rule/guideline rather than learning byheart a bunch or scattered syntax rules...

I know how you feel -- F# is a little like this, particularly when you come from a language like C#, where there's a right way and a wrong way to do something. My advice is to pick one of the alternatives and stick to it.

This may help: the F# Component Design guidelines [PDF] from Microsoft. It's a set of advice -- dos and don'ts -- for your F# code.

prosseek
  • 182,215
  • 215
  • 566
  • 871
Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
  • Ah. ok, but isn't there a rule or s rationale why new is so "flexible"? Why is it the same using or not using new for classes and why do I get a compiler warning when implementing IDisposable and why records do not use the second syntax I wrote before? I'm trying to find a general logic rule/guideline rather than learning byheart a bunch or scattered syntax rules... However thank you for your answer... – Andry Dec 23 '10 at 16:52
  • 2
    This is a guess. I think F# is trying to be as succinct as possible. If you look at the type system; You don't have to write any types unless there is some ambiguity. If you transfer this to the `new` keyword, it is possible to omit it if it can be inferred from the context. `IDisposable` can be used with both `new` and `use`, thus the warning. – Markus Jarderot Dec 24 '10 at 00:13
  • +1 Are you sure the warnings in your code about the absence of a `use` on an `IDisposable` are not just that. i.e. you don't say that `use x = File.OpenRead("hello.txt")` gives the warning – Ruben Bartelink Jul 23 '13 at 21:38