evilsoft / crocks

A collection of well known Algebraic Data Types for your utter enjoyment.
https://crocks.dev
ISC License
1.59k stars 102 forks source link

Expose a length property for curried functions #477

Closed JamieDixon closed 4 years ago

JamieDixon commented 4 years ago

While working through a first-pass on what Async.fromNode might look like with its incoming parameter curried (see #478), I noticed that I was unable to check for a length on incoming curried functions.

With this change in place the code for allowing curried functions with Async.fromNode passes the tests.

What do you think about this change to curry where we expose the length on curried of the original fn that was passed in?

coveralls commented 4 years ago

Coverage Status

Coverage remained the same at 100.0% when pulling 0b7c7d749e3c08dd59290f03d3b09e88a003d4a2 on JamieDixon:curried-expose-length into ce8f9393435067b2ce0ab24a0f620b4cce82c650 on evilsoft:master.

evilsoft commented 4 years ago

What do you think about this change to curry where we expose the length on curried of the original fn that was passed in?

This will only be for the "last" fn passed in yeah? For instance this would report as (1), even though it is really (2)

// fn :: String -> Array -> Array
const fn = curry(
  compose(map, objOf)
)
JamieDixon commented 4 years ago

@evilsoft Hmmm, that's an interesting one. The length of a function with implicit parameters (arguments or ...args) would be 0 I believe?

If my thinking is on track, the arity of the fn returned by compose is 0 because it's essentially infinite?

JamieDixon commented 4 years ago

There would be a similar discrepancy with functions that employ default values, since the length property only indicates parameters up to the first with a default value.

This number excludes the rest parameter and only includes parameters before the first one with a default value.

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length

That is to say, I believe this implementation is consistent with expectations as per the spec. What do you think?

JamieDixon commented 4 years ago

In addition to this, I wonder whether we could fix the arity of composed functions to the arity of the right-most function in the composition? Just a thought.

evilsoft commented 4 years ago

In addition to this, I wonder whether we could fix the arity of composed functions to the arity of the right-most function in the composition? Just a thought.

So this will open up a can of worms, especially if we use this for determining argument application. Because we currently allow an n-ary interface (uncurried) of the right-most function that above function will not be applied properly. When curried, if it reports a length of (2) it will apply it to objOf, passing an Object to map.

We are currently debating limiting arguments to compose/pipe functions to unary for a number of reasons including this behavior. Also it makes functions easier to reason about when composing.

evilsoft commented 4 years ago

If my thinking is on track, the arity of the fn returned by compose is 0 because it's essentially infinite?

Yep totes! Good call!

evilsoft commented 4 years ago

That is to say, I believe this implementation is consistent with expectations as per the spec. What do you think?

It is 💯, I am just saying that when using this property, we should be aware that this does not pertain to the overall function as a whole, just the current "frame" of the curry stack. So if we are gathering and applying arguments before running a side-effect or something, we cannot use this length as the sole indication that we now have all of our arguments and are ready to apply them.

JamieDixon commented 4 years ago

That is to say, I believe this implementation is consistent with expectations as per the spec. What do you think?

It is 💯, I am just saying that when using this property, we should be aware that this does not pertain to the overall function as a whole, just the current "frame" of the curry stack. So if we are gathering and applying arguments before running a side-effect or something, we cannot use this length as the sole indication that we now have all of our arguments and are ready to apply them.

Oh yes! Absolutely.