Improve imperative side of F#
It would be nice to have break, continue and do-while loops build into the language. It would ease porting existing imperative code to F# or just code fine metal tuning.
8 comments
-
Rickasaurus
commented
I haven't yet run into a case where an algorithm couldn't be implemented as one or more tail-recursive functions. If you've run into such a case, I'd love to see the code.
-
Stringer
commented
The reason I wished to have those keywords is because I've developed a runtime for heterogeneous programming in order to target GPGPU/Multicore CPUs (see: https://www.youtube.com/watch?v=6Sr7Cx4j7qk). The lack of them echoes also in ReflectedDefinition. That means my back end generates a bit less optimized code than OpenCL/DirectCompute handcrafted counterpart code which have them (you can even "goto" in C99 OpenCL kernels).
-
Stephan Tolksdorf
commented
After I just had a particularly frustrating experience with expressing loops in F#: Not only is the imperative implementation of a loop sometimes more efficient, it can also be more concise and easier to read. Most importantly, a recursive implementation with nested if-else-checks often entails some code duplication, while in an imperative implementation this can usually be avoided using break and continue.
-
Stephan Tolksdorf
commented
I'm aware that this suggestion has zero chance to be actually implemented, since the purists don't want to have their elegant language mutilated ;-) , but I'll add my voice anyway:
Due to the lack of "break" and "continue" (and to a lesser extend "return" and "goto") certain low-level loops can currently not be efficiently implemented in F#. (With "efficient" I mean performance within a few percent of the the equivalent C# code.) In particular, loops over arrays that work with more than one state variable and multiple separated stopping conditions are sometimes hard to express efficiently in F#.
If you implement loops as local recursive functions, you always have to pay the overhead of at least one additional function call (at least with the current F# and JIT compilers). And if you need to get more than one value out of the loop, you also also have to pay for the allocation of a tuple (at least if you want to write idiomatic code).
Loops implemented with a custom workflows with break and continue involve several times more overhead than a loop expressed as a simple recursive function.
-
Yusuf Motara
commented
Not sure this is a good idea. I LIKE having a single point of exit from constructs that is easily identifiable, and break/continue would mess up that control flow. As would do/while, which would seem to imply waiting for a condition to change, which would imply more mutability, which would mean I'd have to go back to figuring out variable values rather than basing logic on data structure, which would ruin my day ;).
Question is, if you want to do this, F# is designed to integrate well with C#. So why not do it in C#?
-
Johann Deneux
commented
Break/continue in a custom workflow won't be as efficient as their basic imperative counter-parts. Using workflows has a performance cost, namely the creation of lots of closures.
-
Ryan Riley
commented
See Tomas' article http://tomasp.net/blog/imperative-ii-break.aspx
-
Dan Fitch
commented
Not hard to make your own workflow that implements imperative constructs like these, though.