It's been a very long age since I wrote any F#, really enjoyed it at the time and it was for fun stuff, I wasn't trying to deal with errors, just things like process a prefix trie in a cool way, but does
Result<'T, 'TError>
really have no upper type bounds on TError?
I'm assuming that's the case from the fact that he's arguing for a basic interface (Does F# support structural typing, or do you need to say that AtlasError implements IError or whatevs?), and I'm really surprised there isn't one.
Huh, would love to know why leaving it unbounded was decided upon. Might be I don't quite grok the culture of F#.
This reminds me of a very common and awful Python pattern, where, as there's no `message` attribute on the base error/exception classes, despite every nearly every exception or error having one, this is the normal pattern to access it:
message = ex.args[0]
It gets really fun when you get an IndexError because one exception had no message provided when instantiated, so then you find code like:
* community pressure so that F# libraries could standardise on better things that Choice1Of2 = Ok and Choice2Of2 = Error, or using a bare tuple (which is very not clean for APIs)
* F# ought to remain flexible in terms of not pretending of totally abstracting away the fact that most of the dotnet base class library or the overall dotnet ecosystem, uses exceptions, it is not like Result type was created to abstract runtime exceptions away.
For all other needs, one is just one wrapper / or abstraction (for library that don't "meet our standards" in terms of exception safety) away, along with a bit of adhoc tooling around leveraging FSharp.Compiler.Service for sake of adding static analysis, for architecture astronauts, dealing with behemoth or safety critical codebases, requiring even more screws turned, but even there, F# (and so many other languages) may not meet the bar if those are the critical properties for a project involving code.
Overall, F# is just pragmatic for the 99.99%, and not trying too hard beside the steady core language idioms, and how the organic community wants it over time, to satisfy hypothetical and intellectual pursuits of the highest abstraction and safety.
The culture of F# is mostly about throwing productivity parties and being done with it (while not suffering so many of the wrong choices done by C, C++, Java and it's famed sibbling, C#), rather than the higher conceptual type theory perfection that (sometimes ?) lead to code that is not less kludgy, or easier to maintain, in the grand scheme, for the masses of developers, that are not yet expert in Haskell, Scala, etc.
It is probably not too dissimilar to OCaml culture, while embracing some aspects that are familiar to more people, due to relationship with dotnet ecosystem.
(There are languages more similar to C# than Java and vice versa, and of course the underlying type system differences between JVM and .NET also add to this rift, C# was intended as a successor to C++ just as much as it was to Java)
I'm assuming that's the case from the fact that he's arguing for a basic interface (Does F# support structural typing, or do you need to say that AtlasError implements IError or whatevs?), and I'm really surprised there isn't one.
Huh, would love to know why leaving it unbounded was decided upon. Might be I don't quite grok the culture of F#.
This reminds me of a very common and awful Python pattern, where, as there's no `message` attribute on the base error/exception classes, despite every nearly every exception or error having one, this is the normal pattern to access it:
It gets really fun when you get an IndexError because one exception had no message provided when instantiated, so then you find code like: Yech.