Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse argument order #4

Open
tomhicks-bsf opened this issue Dec 14, 2016 · 6 comments
Open

Reverse argument order #4

tomhicks-bsf opened this issue Dec 14, 2016 · 6 comments
Milestone

Comments

@tomhicks-bsf
Copy link

This is quite a big suggestion, but in my opinion the order of the arguments is inconsistent across functions, and generally the wrong way around.

See these for details:
http://functionaltalks.org/2013/05/27/brian-lonsdorf-hey-underscore-youre-doing-it-wrong/
https://jsleao.wordpress.com/2015/02/22/curry-and-compose-why-you-should-be-using-something-like-ramda-in-your-code/

There are some cases where API is the right way around, and would allow for currying or partial application:

v.sprintf('%s costs $%.2f', 'Tea', 1.5);

Here, you take config first, data last, which is the "right way". This allows you to things like:

const logMyStuff = v.sprintf.bind(null, "%s costs $%.2f")
logMyStuff("Tea", 1.5)
logMyStuff("Coffee", 2.40)

which allows you to use this function in compose chains, for example.

You cannot do that with this function:

v.replaceAll('good morning', 'o', '*');

If the order were reversed, and currying implemented, you could do this:

const changeOsToStars = v.replaceAll("o", "*")

And now you have a function you can use over and over.

With the use of FP (and in particular partial application and currying) on the rise in JavaScript, I think this library should take a leaf from ramda's book and put config first, data last, and curry by default.

Thoughts?

@panzerdp
Copy link
Owner

panzerdp commented Dec 14, 2016

Hey @tomhicks-bsf,

Thanks for your nice suggestions!

The library is implementing a standard and the most expected behavior to put the subject of the operation as the first argument. It's clearly the same way as lodash, underscore and other libraries offer.
At this level the reordering of function arguments is not a change that I could implement.

The idea about partial application and currying is interesting. In many (but not the most) situations it brings useful benefits of reusing the configured functions (like you mention logMyStuff).
For such case a flexible solution might be to provide a set of separated functions wrapped in a way to produce immutable auto-curried iteratee-config-first data-last methods.

I like the way lodash implemented that: see more details.

Rough it may work this way:

const v = require('voca/fp');
//
const replaceAll = require('voca/fp/replaceAll');
const changeOsToStars = replaceAll("o", "*");

Such task requires quite a lot of work. But I will think about a plan.

@Jacse
Copy link

Jacse commented Dec 16, 2016

Voca is in many ways an obvious candidate to auto-curried, data-last, composable-functions. With that said, I (unfortunately) think the current implementation is what seems natural for the majority of javascript developers.

Following the lodash way is probably the best way.

@Jacse
Copy link

Jacse commented Dec 16, 2016

Maybe functions could be FP-altered in src/functions.js. Like:

// Helper func for reversing a binary function
flip = func => args => func(args[1], args[0];

[...]

export default {
    charAt: flip(charAt),
    codePointAt: flip(codePointAt)
}

Same principle with currying. But I'm not sure if this is even an acceptable way, I haven't looked through the source code properly.

Question: What would happen to functions with optional parameters? To support auto-currying they would have to be fixed to a specific arity, so would that just mean no optional parameters in the fp functions?

@panzerdp
Copy link
Owner

panzerdp commented Dec 16, 2016

Hey @Jacse,
Thanks for providing your ideas. I agree, the changes can be at the src/functions.js level.
I need some time to design what exact modifications are necessary and how the final FP API of Voca will look. And yes, the FP functions may be fixed to a specific arity.

@Jacse
Copy link

Jacse commented Dec 16, 2016

@panzerdp sounds fantastic - good luck 🍀

@panzerdp panzerdp added this to the v2.0.0 milestone Dec 20, 2016
@briancodes
Copy link

Maybe functions could be FP-altered in src/functions.js. Like:

// Helper func for reversing a binary function
flip = func => args => func(args[1], args[0];

It might be easier to use a more general flip function that works for any arity like const flip = fn => (...args) => fn.apply(null, args.reverse());

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

No branches or pull requests

4 participants