3 ms·
One thing that bothers me with these articles is how they never address the software engineering challenges of writing large complex systems in a pure functiona
by bjlkeng 11y ago
One thing that bothers me with these articles is how they never address the software engineering challenges of writing large complex systems in a pure functional style. There are some tasks where just adding a sprinkle of imperative programming can make the design of the entire system much easier to understand (a kind of "mostly functional"). An article that really crystallized this point is here:
http://prog21.dadgum.com/54.html http://prog21.dadgum.com/54.html
- TazeTSchnitzel 11y agoThat post's been on HN before. I don't know if it's really making a good point. > Imagine you've implemented a large program in a purely functional way. All the data is properly threaded in and out of functions, and there are no truly destructive updates to speak of. Now pick the two lowest-level and most isolated functions in the entire codebase. They're used all over the place, but are never called from the same modules. Now make these dependent on each other: function A behaves differently depending on the number of times function B has been called and vice-versa. This is a complaint that the programming language is preventing you from introducing a hidden dependency. This is a strange complaint, given that hidden dependencies are a problem in software maintainability. I mean, yes, it's convenient now to be able to "just" add global state here and there, but it will come back to bite you later. > [Single-assignment form] is cleaner in that you know variables won't change. They're not variables at all, but names for values. But writing [single-assignment form] directly can be awkward. Well, you don't have to write single-assignment form functional code. If you want to modify state within a function in the same way we all know and love from C, you actually can do that. In Haskell you could do this with the state monad, for example. Purely functional programming enables the composing of operations in many different ways, so you actually have a huge amount of freedom in what style you write your code. > For me, what has worked out is to go down the purely functional path as much as possible, but fall back on imperative techniques when too much code pressure has built up. Some cases of this are well-known and accepted, such as random number generation (where the seed is modified behind the scenes), and most any kind of I/O (where the position in the file is managed for you). Random number generation doesn't require threading the seed if you really don't want to. In Haskell, for example, you can also: * Generate an infinite list of random numbers * Call the IO monad function to get a new random number, which advances the generator behind-the-scenes While the author might have a point that some things are simpler in imperative code, I don't think their examples really support this. Perhaps they had not delved very deep into functional programming.
- agumonkey 11y agoI wish I could find that article again, it's just a claim in a comment at that point but that guy said his team rewrote a c++ system deemed first in class / world class (real time trading or something close) and unbeatable by its 30-years-in-the-field authors. Yet the F# (IIRC) was smaller AND faster, because they had better abstractions to describe the system, find and solve bottlenecks while the previous team members were drowning in c++ LoC and hubris.