4 ms·
> Also, I don't know any F#, but is he correct when he says that the order of declarations in a file matters, and that the order of files in a project matters?
by sdevlin 14y ago
> Also, I don't know any F#, but is he correct when he says that the order of declarations in a file matters, and that the order of files in a project matters?
He is correct. (At least, this was true a couple years ago. I haven't used F# since then, but I doubt this has changed.)
I don't have enough F# experience to speak to any potential benefits of this restriction.
- thomasz 14y agoIt's a pain in the ass, and the only benefit I can think of is that it made the compiler easier to implement.
- snprbob86 14y agoMany languages require declare-before-use and co-declared recursive structures. Sometimes, they provide an escape-hatch like a forward-declaration. It also makes the compiler substantially faster and makes it far harder to accidentally introduce a layering violation in your design. If you're a Java or C# programmer, or even a C++ programmer, you're used to cyclic relationships all over the place. Your Person class has a .Adresses property and your Address class has a .Residents property so that you can conveniently person.Addresses.Filter(address => address.Residents.Count > 1) and suddenly your Address class is tightly coupled to your Person class. Do this a few dozen times and before you know it, your software is a maintenance and refactoring nightmare. Object-oriented programming encourages this design. Functional programming discourages it. Modern OOP compilers conveniently resolve circular dependencies (Java does, C++ doesn't without header games). Modern FP compilers force you to declare and contain your circular dependencies. Lastly, declare-before-use makes a lot of dynamic and live programming scenarios viable. Lisps, for example, generally have a compilation unit of a top-level form. This way the REPL and a normal source file behave more similarly, if not precisely the same.
- thomasz 14y agoI'm totally fine mandating explicit declarations for mutual dependencies, I'm just pissed that F# has no syntax for dependent modules. It's just odd. Why can I declare co-dependent functions and types, but not modules?
- snprbob86 14y agoIf they are co-dependent, then that, by definition, means that they are not independent. What value do you get by having co-dependent modules that you can't get by having a single module? If you want two public APIs with one common implementation that is co-dependent, you can have three modules where two depend on the co-dependent part. Without seeing a motivating use-case, I'm just going to assume that F# is succeeding in preventing you from making a bad design decision.