Allow all declarations to be mutually referential and the compiler takes files in any order
With F# becoming more and more multi-editor and cross-platform, it is becoming increasingly difficult to teach all build/edit tools about F#'s file order. The F# community are currently struggling to "update" each new build/edit tool to understand that F# actually needs a file order.
Part of the problem is that there is no standard textual way to specify this file order except as command line arguments, and these are not stored in an editable form. There is no standard way to specify the F# file order. We need an (optional) solution to this problem that is closer to home and doesn't involve modifying build/edit tools.
This proposal is one of three alternatives to deal with this problem in the F# language/compiler itself.
The specific proposal covered by this UV entry is to just change F# to use no file order at all, allowing all declarations in an assembly to be mutually referential with other declarations.
Related alternative: Keep a file order, but infer it from #load/#require declarations. This is covered by https://fslang.uservoice.com/forums/245727-f-language/suggestions/6323146-syntactically-describe-dependencies-between-files
Related alternative: Keep a file order, but optionally have it specified by a fileorder.fsx or fileorder.txt or fileorder.json: https://fslang.uservoice.com/forums/245727-f-language/suggestions/13394442-optionally-specify-file-order-by-a-fileorder-fsx
Alex Yakunin commented
There were many points saying that explicit file order is one of core F# features, and it's crucial. It lets you immediately see the order of dependencies, and thus it prevents possible issues with circular / spaghetti dependencies.
I am fully disagree with this:
a) Dependencies aren't simply chained in most of projects -- usually there is a good amount of flexibility in how to order them. And it's not fully clear why a specific order is preferable over others.
b) This also means that actually order doesn't show the dependencies: on contrary, it shows which dependencies do not exist. The only relationship it exposes is: "if A is above B, A definitely does not depend on B". Though the same doesn't mean "B definitely depends on A".
c) Finally, dependency graph is a graph, not a sequence. So I don't understand why it's good to force developers to model it as a sequence. Especially assuming that almost any modern compiler is smart enough to figure out both dependencies and compilation sequence.
d) Nevertheless, I see a value in having an ability to display the dependencies of your F# files. But "display" is not what compilers do -- this is what IDEs and other tools do. So I totally support to have this feature in IDE, but I don't see a single reason to have it baked into the compiler -- at least in such a way.
Moreover, if I'd be building a feature allowing me to see these dependencies, I'd prefer to show differently -- one of good ways is to show it as a tree listing the most independent files on the first level, their dependencies -- on the second, and so on. The opposite order (from the mostly dependent components to their deepest dependencies) is totally valid too. Any profiler is capable of showing a similar structure for your call tree.
And I don't think I'd prefer this dependency graph to be shown simply as an ordered sequence.
Please consider all these arguments before downvoting this feature.
Loic Denuziere commented
100% agree with Gauthier. It would be quite good if the compiler could figure out the order of the files, but total circular dependency is way too error-prone.
Gauthier Segay commented
It is unfortunate that this suggestion mixes 2 concerns:
* declarations to be mutually referential (which most people don't want as seen in comments)
* have the compiler figure out the order rather than have to specify it manually
I think the later point would be a great thing for end-users, and that doesn't circumvent at all file ordering being there and necessary, only it would be figured out by the compiler.
Jason Ritchie commented
Downvote. Having circular dependencies be impossible helps me fall into a 'pit of success' in my designs.
Stefano Pian commented
Downvote. The compilation order has been a huge blessing for me whenever I need to pick up a moderate-sized or bigger F# project.
I agree that the F# compilation should become editor-agnostic, but either of the related alternatives would solve the problem without sacrificing F#'s excellent enforced code structure.
Kurren Nischal commented
Downvote. The ability to open a project and immediately see the dependency hierarchy is a major reason why we use F#.
Don Syme commented
Jus to mention that I don't see anything fundamentally "non-F#" about optionally describing file dependencies explicitly within files - indeed we already do this for F# scripting using ``#load``. The file ordering would still exist.
Don Syme commented
#load "Helpers.fs" (which already describes dependencies in scripts)
Note that F# scripts already have syntactic description of non-cyclic dependencies through #load. So a file ordering inferred from syntax is already part of the F# programming model, at least for scripting.
Harald Steinlechner commented
Another downvote. although it seems nice, we'd increase complexity in f# libraries, .e.g. see http://fsharpforfunandprofit.com/posts/cycles-and-modularity-in-the-wild/
Semantic file order and lack of cyclic dependencies makes it so much easier to figure out what's going on in a project. Consider this a downvote.
Siro Mateos commented
Add another "downvote", for NOT doing this.
Semyon Grigorev commented
Bad idea. Fixed compilation order is a good feature.
Please don't do this.
Bent Tranberg commented
I'd also like to go on record as not wanting this. Colin Bull and others has already explained why it should stay the way it is.
If I could spend votes to down vote this suggestion I would.
This is a feature not a bug. It's a small bit of pain to start with that improves the overall quality / understandability later.
Shawn Martin commented
Since there's no downvote button, I guess I'll pile on with many of the other commenters. I like the existing enforcement of an explicit, user-specified order.
I'd also like to go on record as not wanting this as a feature; I say this dispite having written build scripts that *do* use #load statements in fsx files to feed the compiler source in the correct order.
It works, but it's ugly and it's not an improvement; optionally moving this information out of fsproj files might be helpful, but I'd rather see a dedicated file for this (like fsi files for signature information).
As already commented on Twitter: Please don't break compilation order. It's what makes my code sane.
Do this in external tooling to sort your files in the solution, and not in the compiler! As it is, its a great feature for keeping the architecture clean.
Daniel Robinson commented
Kevin, would the files in Solution Explorer re-order automatically based on #load's?