fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
345 stars 21 forks source link

Allow object expression without overrides #632

Open dmitry-a-morozov opened 6 years ago

dmitry-a-morozov commented 6 years ago

Described here

https://stackoverflow.com/questions/8154730/object-expression-for-abstract-class-without-abstract-members

I propose we allow it because it's necessary when base class has protected constructor.

The existing way of approaching this problem in F# is ...

Define top level class that only invokes base constructor.

Pros and Cons

The advantages of making this adjustment to F# are ... Better inter-op with existing NET libraries.

The disadvantages of making this adjustment to F# are ... Extra work.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): No idea.

Affidavit (please submit!)

Please tick this by placing a cross in the box:

Please tick all that apply:

dsyme commented 6 years ago

This makes total sense, there is no reason why we shouldn't allow this. Marking as approved-in-principle

7sharp9 commented 6 years ago

Does this need an RFC?

dmitry-a-morozov commented 6 years ago

@7sharp9 It probably does. Can you please create one?

edgarfgp commented 1 month ago

Im looking into writing the RFC but I think it should be possible to remove this limitation for abstract classes and not abstract classes as it already possible for interfaces. cc @dsyme @vzarytovskii

See WIP implementation https://github.com/dotnet/fsharp/pull/17387

type IFoo = interface end

type Class() =
    do printfn "Hello"
    member this.Method() = ()

let a = { new Class() with member this.ToString() = ""  } // We are force to override ToString to make it work
let b = { new Class() interface IFoo } // Or implement a marker interface

[<AbstractClass>]
type AbstractClass() =
    do printfn "Hello"

let c = { new AbstractClass() with member this.ToString() = "" } // We are force to override ToString to make it work
let d = { new AbstractClass() interface IFoo } // Or implement a marker interface

// It should be possible to remove this limitation for abstract classes and not abstract classes as it already possible for interfaces

let e = { new IFoo }
vzarytovskii commented 1 month ago

I am fine with it, as long as @dsyme is (he may have specific reason why it is explicitly disallowed currently), but it feels more uniform (however confusing, as it's "do the same thing in two different ways").

dotnet fsi

Microsoft (R) F# Interactive version 12.8.400.0 for F# 8.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> type ClassEnd() = class end
- ;;
type ClassEnd =
  new: unit -> ClassEnd

> { new ClassEnd() };;

  { new ClassEnd() };;
  ^^^^^^^^^^^^^^^^^^

/Users/u/code/fsharp/stdin(6,1): error FS0738: Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces.
edgarfgp commented 3 weeks ago

This can be closed. I implemented it in https://github.com/dotnet/fsharp/pull/17387