4 ms·
> You have to jump at a billion functions definitions before you can hope to understand what a program is doing On the contrary, if you assume that your functi
by epgui 3y ago
> You have to jump at a billion functions definitions before you can hope to understand what a program is doing
On the contrary, if you assume that your functions are good abstractions then you shouldn’t need to know their implementation details in order to compose them. You can tell what it does by looking at just what you have in front of you.
If that’s not the case, then you’re not looking at a good example of this concept. And we all know we can find bad examples of any idea or paradigm— what is useful is the good examples.
- AnimalMuppet 3y ago> > You have to jump at a billion functions definitions before you can hope to understand what a program is doing > On the contrary, if you assume that your functions are good abstractions then you shouldn’t need to know their implementation details in order to compose them. You can tell what it does by looking at just what you have in front of you. In maintenance, you often cannot assume that your functions are good abstractions. One of them is doing something wrong, or at least something that needs changed. Which one? You have to go into the implementation details in order to find where you have to begin to work. That's not "bad examples" of FP. That's just how software maintenance is. And maintenance is going to happen to FP programs too...
- rebeccaskinner 3y ago> One of them is doing something wrong, or at least something that needs changed. Which one? While this is as true in FP as it is anywhere, my experience is that it’s rarely true of the kind of small pure functions that tend to be composed like this. When someone is using a chain of functions like this, they usually are good abstractions that don’t change, and are short enough to be trivially correct.
- jackcviers3 3y agoPoint free when done with _andThen_ instead of _compose_ isn't that much different from reading basic statement oriented programs delimited by semicolons: ( f andThen g )(x) vs a = f(x); g(a); _andThen_ is of course just compose with the arguments flipped such that you can compose from left to right instead of right to left. In FP languages, and languages that use FP combinators, it is usually more efficient to use composed functions with combinators that do iteration and copying like _map(list, f):List_, because the iteration and copying happens during each map application: map(map(l, f), g) and map(l, f andThen g) produce equivalent results, but the second is faster and has fewer allocations. For determining the arguments to f and g and map, typed fp languages usually have ide features which can show you the inferred type of each expression, or you can jump to the definition and see it, usually by hovering or key chord while the cursor is over it. map[A, B]( fa: List[A], f: A => B ): List[B] and etc. This allows you to read things easily and avoid cluttering the code with types where they can be easily inferred. Point-free style is important to make the usage of such combinators acceptable but experienced devs do extract and name a composition when it becomes difficult to understand. Of course, the treatment of functions as effect-free black box transformers for equational reasoning also makes these refactoring extractions to variables safe to do. You get a feeling for what is too much over time, and settle on when to use point free style and when not to. On efficiency - good compilers can often identify nested/chained map applications and rewrite them as a single map application during compilation, but map fusion isn't guaranteed by all compilers or all _map_ instances. The evaluation strategy (lazy/eager) of the language and/data structure also plays a role in whether or not map fusion with point-free style is more efficient or optimisable.