fsharp / fslang-suggestions

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

Support nested type definitions #277

Open baronfel opened 8 years ago

baronfel commented 8 years ago

Submitted by Robert Nielsen on 6/22/2014 12:00:00 AM
48 votes on UserVoice prior to migration

I don't think F# supports nested type definitions yet. The idea was posted here: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2313137-inner-types-for-f Two other references on nested types: http://msdn.microsoft.com/en-us/library/ms173120.aspx http://cs.hubfs.net/topic/None/57397

Original UserVoice Submission Archived Uservoice Comments

Rickasaurus commented 7 years ago

I have never wanted/needed this and I think it would complicate the code that people coming from C# would write in the language but I guess maybe as an interop feature it's reasonable. I'd make it super painful though so people aren't temped to it for normal development.

smoothdeveloper commented 7 years ago

F# supports nested modules / types in modules, it would make sense to support the same for classes / structs as well, although there are probably many edge cases to take care of in terms of visibility of members of outer classes etc.

It is probably costly to implement that.

In terms of interop, #157 seems like a lower hanging fruit and more important for actual interop / vending OO APIs.

smoothdeveloper commented 7 years ago

Just seeing that this is a feature which is actually used a lot in type providers, those tend to define inner types (Json, Xml type providers from FSharp.Data, YamlConfig type provider, etc.).

ReedCopsey commented 5 years ago

As mentioned in #6059 - Nested class support is a requirement for supporting System.Diagnostics.Tracing.EventSource. While we can argue that the API required is foolish (and I'd be happy to agree), not properly supporting EventSource is also very limiting, as it enables the single best profiling mechanism available to .NET programs (ETW), especially if you need to profile issues arising in production.

cartermp commented 5 years ago

Just as a distinguishing note - we actually do ETW logging in the VisualFSharp codebase: https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/Logger.fs#L16

And that's fine. So it seems that there's a subtlety here where it goes awry. The 6059 issue gives an example with Service Fabric. Are there other examples?

ReedCopsey commented 5 years ago

@cartermp You can't use custom ETW keywords, opcodes, or tasks without defining nested types. You can do basic ETW tracing, but the ability to define opcode masks for enabling only part of your logs is quite powerful and very handy for profiling.

charlesroddie commented 5 years ago

This suggestion is not only valuable for interop. It has large benefits for code structure and intelligibility, allowing types to be defined in a smaller scope.

Edit: I now think there are these benefits but they are small, since this issue is about defining types inside types and not inside any expression. Defining private types above a type instead of inside it is not much worse in scoping terms.

dsyme commented 3 years ago

I'm ok with adding nested type definitions to F# at this stage in its evolution and now some other issues like namespace rec have been sorted out.

I'll mark this as approved in principle, though it's not necessarily a priority for myself.

konst-sh commented 7 months ago

Should we assume that this PR will allow type providers inside types? Would be pretty handy for things like REST API endpoints handling

abelbraaksma commented 5 months ago

@konst-sh I think this language suggestion is about type definitions in F# code itself, where you would allow nested types (like we allow nested modules).

It'll need a volunteer for an RFC though.

konst-sh commented 5 months ago

@abelbraaksma i was asking about construct like this:

type Outer() =
    type Inner= JsonProvider<""" { "name":"John", "age":94 } """>
    static member getInfo() =
        let info: string = ...
        Inner.Parse(info)
abelbraaksma commented 5 months ago

That's an interesting idea and I can see its benefits. We should address it in the RFC. And unless there's a practical reason why allowing that with nested types isn't gonna work, I think we ought to cover that.