Skip to content

Conversation

@webNeat
Copy link
Contributor

@webNeat webNeat commented Jun 28, 2016

Hello, I added a new feature which is argument placeholder. inspired from Ramdajs. This will allow doing things like:

$minus = C\curry(function ($x, $y) { return $x - $y; });
$decrement = $minus(C\__(), 1);
$this->assertEquals(9, $decrement(10));

@matteosister
Copy link
Owner

Hi @webNeat, thanks for your contribution...

I'm not so sure that I want to add this, because its about partial application and not currying functions. There are many libraries that do partial application, for example this one.

I'm open to change my idea....what do you think?

@webNeat
Copy link
Contributor Author

webNeat commented Jul 4, 2016

Hello,

Currying and Partial Application are very close concepts. Let's take the definitions from this article

  • Partial Application: The process of applying a function to some of its arguments. The partially applied function gets returned for later use. In other words, a function that takes a function with multiple parameters and returns a function with fewer parameters. Partial application fixes (partially applies the function to) one or more arguments inside the returned function, and the returned function takes the remaining parameters as arguments in order to complete the function application.
  • Curry: A function that takes a function with multiple parameters as input and returns a function with exactly one parameter.

According to these definitions and this quote from the README

Currying a function means the ability to pass a subset of arguments to a function, and receive back another function that accept the rest of the arguments.

Your library does Partial Application more then Currying. Because the result of curry() is not an unary function !

What about the Placeholder ?

Let's take this function

function add ($x, $y, $z) {
    return $x + $y + $z;
}

Which can be represented with

add :: (Number $x, Number $y, Number $z) -> Number ($x + $y + $z)

A real curried version of it would be

function curriedAdd ($x) {
    return function ($y) use ($x) {
        return function ($z) use ($x, $y) {
            return $x + $y + $z;
        }
    }
}

Which similarly can be represented with

curriedAdd :: Number $x -> (Number $y -> (Number $z -> Number ($x + $y + $z)))

We generaly get ride of ()s and simply write

curriedAdd :: Number $x -> Number $y -> Number $z -> Number ($x + $y + $z)

So doing

$addTwo = curriedAdd(2);

gives

$addTwo :: Number $y -> Number $z -> Number ($x + $y + $z)

$addTwo is a function that takes 1 argument ($y) and returns another function

We can also say that $addTwo is somehow a partial application, because we can no longer change the value of the parameter $x which was already 'applied' with the value 2.

But doing

$newCurried = curriedAdd(__())

Results something like this

$newCurried :: Number $y -> Number $z -> Number $x -> Number ($x + $y + $z)

This function has the same arity as curriedAdd, the only difference is that
curriedAdd takes $x then $y then $z, while this one takes $y then $z then $x.

This proccess is not partial application because the resulting function has exactly the same arity of the input function.

Summary:

  • This library is more about Partial Application then Currying
  • The Placeholder concept is more related to Currying then Partial Application

Sorry for the long comment. I hope this clarifies the things a little bit

Feel free to correct me if I am wrong 😄

@matteosister
Copy link
Owner

matteosister commented Jul 5, 2016

I know all the theory, thanks anyway for the head up 😄
Currying, sticking to the theory, is simply not possible in php. It should be done at a higher level. Haskell, for example is curried by default. And that is something that feels just right.

In elixir, the language I'm using the most right now, there is no default currying, but a thing called pipeline, that, in my opinion, bring the concept of partial/currying to a higher level. Where expressiveness and terseness wins upon theory.

Back to the sad php (that funcionally speaking really sucks) you could only mimic the behaviour.

When you apply two arguments to a function with an arity of 3, you are mimicing the fact that a curried language will return a one argument function for every step. In my opinion a placeholder do not fit with this concept. In haskell there is not a thing like that. You simply supply argument in the way they are specified in the original curried function.

Having said that, I'm happy to accept your pull request! Because you are really passionate about the argument, and the PR is really well done...many thanks!

@matteosister matteosister merged commit 9c5b3da into matteosister:master Jul 5, 2016
@matteosister
Copy link
Owner

@webNeat
Copy link
Contributor Author

webNeat commented Jul 7, 2016

Thank you for accepting my PR. The thing is that I needed this feature in a library I am building https://github.com/tarsana/functional . And by the way, feel free to give me feedbacks about this one 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants