Open baronfel opened 8 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.
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.
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.).
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.
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?
@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.
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.
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.
Should we assume that this PR will allow type providers inside types? Would be pretty handy for things like REST API endpoints handling
@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.
@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)
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.
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