How to organize F# source of large project (>300 c

2019-01-13 18:52发布

问题:

In C# you can put files in folders corresponding to their namespaces and view them in the Solution explorer.

In F# it seems I have to put everything in plain specifically ordered list for compilation. When I get to scale of ~300 of classes it gets a bit confusing and disorganized and I start to envy C# and think that probably it is the price for type inference.

Are there better options than splitting to several assemblies?

Judging by F# compiler source its the route they have taken but I have pretty large system of interconnected components (Controller - ViewModel - View, > 300 classes) I want to be in one assembly because of circular dependencies even at level of interfaces.

Should I forget about one file - one class and create some huge files? (e.g. in F# compiler you have several source files in 100kb to 300kb range and some auto generated around 1Mb!)

What is your experience with large F# projects?

回答1:

You mention "circular dependencies", to be clear, F# will never let you spread circular dependencies across files. If type Foo refers to type Bar and type Bar refers to type Foo, then Foo and Bar must both be defined in the same file in the same type ... and ... group in F#.

The issue here is one of organization and navigation, that is mostly about the tooling. The VS solution explorer displays a list of files; folders enable you to 'collapse' groups of files which can make it easier to organize your thoughts or navigate across 'great distances' of many files. However for navigation there are various other tools (Go To Definition, search for text in the current project, ...) to let you navigate to e.g. a particular class definition. (Hopefully these tools will continue to improve for F# in particular, as well as VS in general, in future releases.)

In any case, I firmly believe that a "pretty large system of interconnected components (Controller - ViewModel - View, > 300 classes)" is a code smell. If you can't untangle these to have an archetectural layering such that there are portions that do not depend on other portions (and thus could be defined 'first' in a prior file in F#), then you have bigger problems than just "how to organize your F# code". My opinionated view is perhaps best-expressed here.

EDIT (2018): meanwhile, the tools have improved, among many other things, go-to-definition, find-all-references, global renaming of identifiers, folder support, file reorganization etc have been added in the past few years. For solutions that require mutual references between classes, namespace rec and module rec have been introduced to limit the need for type ... and ....



回答2:

You can have folders in F# projects, too. It's a bit cumbersome, but it works.

I think putting multiple classes into one file is perfectly okay and idiomatic in F# if the classes are closely related to each other.

I have not yet worked with really large F# projects, but I'm also interested in the experience of others.