Yeah technically it's not point free. But technically nothing can truly be point free just like nothing can ever be truly purely functional.
In purely functional programming your IO and state has to live somewhere just like how your points in point free programming still have to exist on the function call.
A function that takes multiple arguments introduces extra points to your program similar to introducing extra IO calls to your purely functional program. These points are inevitable additions to your program. The philosophy remains point free however.
Another way to think about it is that every parameter in a point free program is tied to a point somewhere up the pipeline. If you introduce a function with multiple arguments, that extra argument will still need to be tied to a point either right now or up some other pipeline.
So either you curry in a point into that extra parameter or you curry in the result of another pipeline.
A good way to think of the point free style is a series of pipes flowing in one direction, from left to right. All pipes segments must be eventually connected to a source and eventually flow to an output.
A function with 2 parameters is a T junction within this system with 2 inflows and one outflow. No matter how you configure your network of pipes; points need to live to the at the source and output of this network either as IO or actual state. There is no "point" in creating a network of pipes that isn't connected to a source and an output.
When you introduce a new T junction into this network of pipes, you will inevitably need to connect these inflows to points at the source of the pipe network. There's no way around it.
> piping multiple statements together into a single chain of processing[] without having to explicitly declare variables to hold the temporary inputs
This is known as point-free style. I think point-free style implies functional programming (at least locally; i.e., a point-free function will by definition be functional, although it can call imperative functions) but functional certainly does not imply point-free.
Please tell me you know of a functional language that does not incorporate "point-free style", as you put it. I would love to look at such a language as a way to redefine how I view functional languages in general. No sarcasm involved, I am genuinely interested.
I didn't know what "point-free style programming" was so:
> Tacit programming (point-free programming) is a programming paradigm in which a function definition does not include information regarding its arguments, using combinators and function composition [...] instead of variables.
Ah, well... point-free style is going to be more-or-less possible in any decent functional language; it (or rather, functional composition) is one of those things like "while loops" in imperative languages which, if absent, would cause you to consider a functional language kind of rubbish. Functional programming would be far too verbose to be comprehensible otherwise.
That said, Scheme is probably a good example. Lisps in general are a funny case for functional programming: historically they were described as "functional" but the word had a different meaning we would now call "procedural"; I think Lisp may have predated Algol so the concept of having functions at all was fairly notable. However, Lisps generally support functional programming and Scheme has embraced it more fully than the others. Note, for example, that Scheme doesn't actually have loops as a fundamental concept in the language; it emulates them with obligatory TCO and convenience macros.
For people without a functional language background, it makes sense to think of point-free style with an example they understand: Unix pipes.
The controlled producer-consumer flow in pipes is a subset of the declarative combinatorics of values in a point-free function composition. Approaching it as an ongoing process that generates values and consumes them at the same pace can make it easier to understand.
You will note that you and many other FP programmers have gotten away with FP programming without doing a single line of actual function composition yet still yielding much of the same design benefits from the point free style.
This happens because the isomorphism between applicative and composition is really really close. I advocate the point free style for educational purposes, but for practical purposes either style is fine.
Cool! Glad I was able to convince you. Just note that a lot of people find the functional style kind of unnecessarily mind bending. Like the functional style primarily uses recursion instead of loops for iteration which is harder to reason about (and less performant). I actually agree with them, but I feel that these people got lost in the details and missed the big picture about the benefits of functional programming from the perspective of modules, design and program organization.
I recommend you try building something complex with the point free style using Haskell. It will be a bit mind bending at first but if you get it then you'll see how FP is basically the same thing as using legos to build data pipelines... exactly the style used with unix pipes.
Immutability may be a buzzword, but if you stick with immutable data, that does give you functional programming. The possible exception to this is that you could have certain kinds of real-world side effects in a language which only had immutable data.
FP used to mean just "no side effects". (Barbara Liskov mentions this old understanding of FP here: https://www.youtube.com/watch?v=qAKrMdUycb8). That is a desideratum for the even bigger buzz-phrases "referential transparency" and "equational reasoning", which are the goals of the FP research programme and have yet to really materialize.
As a counterpoint to your claim that understanding point-free style is a fundamental part of understanding functional programming, how about this 1998 paper by Andrew Appel, "SSA is Functional Programming" http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.3... which locates the essence of functional programming in the fact of immutable data (equivalent to imperative Single Static Assignment code).
Functional programming isn't about eliminating state. You can't write programs without state. Functional programming is about eliminating hidden state changes.
State changes are fine! They just aren't allowed to be hidden.
Despite all that - I agree that move semantics are weird. He's got a point there.
The point of functional programming (or any good programming style, really) is to eliminate unneccesary dependencies (by which process the necessary dependencies are clarified) not to remove necessary dependencies (which by definition is impossible).
But I think that the point of functional programming is to provide a layer of programming that exposes a clean API. You know: now side effects, no global variables etc..
> There is a reason that research into functional languages is limited to an old or new functional language. Without syntax and compiler support you don't gain any power to offset the limitations
I don't understand what this means.
> If you start dealing with a Fixed_Point objects, and Mobile_Point object, you now have bloat with little gain
Why would you not have a single point class implementing multiple interfaces? Surely if they do the same thing, you wouldn't bother. Good design would dictate that if they do similar things (but not the same), they should probably share an abstract parent class anyway.
> It's far better to have a "Final" flag on your point, so it will toss an error when you try to change it
And check this at runtime for every access!?! Why on earth would that be more efficient than static checking at compile time?
I think what you're missing is that functional programming is about referential transparency. There should be no need for an instruction pointer in your mental model.
In purely functional programming your IO and state has to live somewhere just like how your points in point free programming still have to exist on the function call.
A function that takes multiple arguments introduces extra points to your program similar to introducing extra IO calls to your purely functional program. These points are inevitable additions to your program. The philosophy remains point free however.
Another way to think about it is that every parameter in a point free program is tied to a point somewhere up the pipeline. If you introduce a function with multiple arguments, that extra argument will still need to be tied to a point either right now or up some other pipeline.
So either you curry in a point into that extra parameter or you curry in the result of another pipeline.
A good way to think of the point free style is a series of pipes flowing in one direction, from left to right. All pipes segments must be eventually connected to a source and eventually flow to an output.
A function with 2 parameters is a T junction within this system with 2 inflows and one outflow. No matter how you configure your network of pipes; points need to live to the at the source and output of this network either as IO or actual state. There is no "point" in creating a network of pipes that isn't connected to a source and an output.
When you introduce a new T junction into this network of pipes, you will inevitably need to connect these inflows to points at the source of the pipe network. There's no way around it.
reply