Hacker News new | ask | show | jobs
by hammerandtongs 3105 days ago
I've never been attracted to the idea of partial application. Without it a function is either in state 0 or 1. It's not called or it has been called.

With partial application in the mix, functions are in an almost indeterminate state (to the programmer typing at the keyboard even if some compilers know).

In functional styles, programmers are encouraged to "just pass a function".

The f(x,y,z) gets passed around in an unknown state of f(maybe needs x, maybe needs y, maybe needs z).

This would be complicated even if it was the same function with a declining arity as it was passed around. Several languages allow named arguments which just adds to the signature complexity.

It's hard to see the benefits of the complexification.

Most pedagogical examples of the use occur in tight loops where the complexity isn't obvious. Once a function is passed outside of that tight loop I wonder at it's actually utility vs the negative effects.

2 comments

Yea I totally agree, partial function application certainly complicates things. Instead of `called` vs `not called` like you said, a function can have any number of states depending on its number of arguments.

I will give you my two cents on its benefits though and let me know if you agree or disagree. I would compare it to taking a step up on the ladder of abstraction. Computers are powerful because they are programmable. If we take the example of a value like an integer, in a computer we can make it anything we want (0, 1, 2, 3, 4 etc). Functions are how we program a value. We say for example

speed(distance, time) { return distance / time; }

The value of the speed depends on these two variables (distance and time) which are programmable.

Partial function application is just a continuation of this idea. It's obvious that `values` are programmable, but why can't functions be programmable as well? After all, we gained a lot of power from letting values be programmable maybe the same will be true for functions? Using the previous example lets say we want a function to calculate the speed of runners in the 100m dash. We could write a new function for this

speedOf100YardDash(time) { return 100 / time; }

but we already have logic for calculating the speed and we don't want to reuse it. So the idea of having a `programmable` speed function starts to look a little better.

speedOf100YardDash = speed(where `distance` = 100)

Obviously, this plays into your criticism of 'pedagogical examples' being simple, but I think the idea is even more valuable with more complicated code. Why? Because with simple examples it's easy it duplicate code without much consequence. The value of speed and division are not changing anytime soon. If we have more complex functions, however, this is where we absolutely want to avoid code duplication. Because if we write a complex function multiple times it's more likely that one of those implementations will be written differently or eventually diverge from the other one.

What do you think?

I'm really into partial application when you wish to mock some data for testing, and the caller chain of that test is shallow. That is:

* function under test takes in a data as its last parameter

* partially applied version of this function is used in a test

* testing function constructs fake data

* testing function calls the partially applied version

It's also nice for code reuse in libraries, but I'm generally less inclined to use it unless I know that the thing I'm working on has dead-simple requirements and won't change much.