3 ms·
Some of the complaints in the article are certainly valid (why would there be early-return in the context of computation expressions, but not in ordinary functi
by Smaug123 3y ago
Some of the complaints in the article are certainly valid (why would there be early-return in the context of computation expressions, but not in ordinary functions?), but some I claim are actually features, and some are false.
* Linearly ordered files. Several times in F# I have tracked down an issue simply by bisecting the codebase, which is impossible in C# because there's no meaningful way to halve the code. I think I've only once ever had a problem with the linear ordering that wasn't solved simply by reordering some files.
* Explicit type conversions. I've only ever found this awkward when interfacing with C# code that is designed around C#'s extreme laxity. Explicit is better than implicit!
* "No struct tuples" is false - that's what the `struct` keyword is for. (It may have been true when the article was written.)
* Dot notation for indexing is now no longer necessary.
It's certainly true that OO idioms are often clunky and feel strangely like they were constructed by Frankenstein, but then I almost never find myself trying to use them anyway. You don't notice oddities in features which you never think of using! Similarly, the number of times I use `<-` is so low that I don't think of it as being incongruously odd - why shouldn't there be a baroque syntax to indicate the place in your code that's likely to have a 50% higher chance of bugs?
- deleted 3y ago[deleted]
- WorldMaker 3y ago> "No struct tuples" is false - that's what the `struct` keyword is for. (It may have been true when the article was written.) Quite probably. The underlying CLR ValueTuple type is a relatively recent .NET addition (and partly only exists because C# asked for it). (It was added in Fx 4.7 / Core 1.0, whereas the reference type Tuple was added way back in Fx 4.0.)
- Smaug123 3y agoI have been informed that computation expressions do not have early return. For example, `async` does allow you to express what appears to be an early return, but only of the `unit` type, and in fact it doesn't return early; it simply proceeds straight past the `return` keyword. Raised https://github.com/dotnet/fsharp/issues/15759 https://github.com/dotnet/fsharp/issues/15759 .
- eyegor 3y agoYou can create true "early return" behavior by writing a lazy computation builder [0]. It feels esoteric but taking the time to craft a domain specific computation builder can drastically simplify the rest of your code base. I don't know if there's a more modern (more ergonomic) way to do this since this has been around since ~2012 or so. Alternatively you can take the more functional approach and rewrite your function logic to use `if x then (value) else` throughout instead of `return (value)` or `yield (value)`. Early return isn't really a thing in f# but if-else is. [0] https://fsharpforfunandprofit.com/posts/computation-expressions-builder-part5/ https://fsharpforfunandprofit.com/posts/computation-expressi...
- pharmakom 3y agomost of the time early return can be replaced by function calls. what bites is that f# has no way to force TCO so sometimes it's safer to write a loop with a mutable flag.