-
Notifications
You must be signed in to change notification settings - Fork 6
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
Function length behavior #30
Comments
We discussed the arity of curried functions in #17.
I don't like lodash's implementation of curry for exactly that reason. IMO in FP it's important to be explicit and that includes that a function has a fixed arity.
and Ramda's curry does maintain arity too.
does this really have a big impact on performance? Do you have a benchmark? // cc @tomekwi related #29 |
Theres actual a good article about arity-and-partial-function-application by raganwald. The usage of But i would like to also see benchmarks to discuss performance and i can understand a possiblity of it being an issue somewhat, however, i currently use ramda in production at work and ramda as mentioned by @stoeffel maintains arity and i have not noticed too many performance issues.. yes we know its not as fast as lodash and there are talks about improving performance but not a cost the maintaining arity. If needed I can provide the discussions from the ramda repository as well |
Arity is the number of arguments a function "expects". Consider
So what is the arity of
Now of course we can legitimately ask the question: "What is the number of additional, non-placeholder arguments that would need to be passed to A typical example of things one wants to do with arities (
But this is precisely something that we would never want to do with curried functions, since they can legitimately be called with any number of arguments. This is different from partially applied functions, where it makes perfect sense to report the arity of the result of partial application. In other words, in the following case,
it is correct to report the arity of Whether or not |
Would be cool, if we could see some benchmarks. I want have time to do that today, but maybe someone (or you) would like to create a PR and compare the current master to your performance branch. |
Good reasoning!
The decision came because of the partial application functionality that came bundled with But the more I think about it (and read your posts @rtm), the more I prefer See #29 (comment) and #29 (comment). |
The logical move would be to separate the partial application functionality to it's own module |
👍
|
There is a home for both modules now. and we can remove the functionality from |
So "thisables" is an organization? I'm a little fuzzy on how they work. Do they group repos together? What does it mean to be a member of an organization? Is your intent to make shave a separate repo? Maybe it's just me, but I'm not a big fan of micro-repositories. We already have a bunch of machinery in |
Yes grouping modules with a common functionality IMHO is a great way to make them discoverable (good way to get more contributors involved, etc) Also allows them to have separate issues/discussions and PRs.
Hmm i not sure what you mean here? if you have module A that depends on module B, module C, etc it would be pulled in automatically when requiring from npm. It would be the same if those modules were built into the core and not as separate repos.
I think Sindre Sorhus does a great job explaining his take on the subject as he a prolific developer with tons of small modules. read here Again thought I would share my thoughts... @stoeffel @tomekwi @hemanth may have different even contrasting opinions. |
I read Sindre's post. I want to make sure I'm understanding what is being proposed. Is it $ npm install @thisable/curry
$ npm install @thisable/shave import {curry} from '@thisable/curry';
import {shave} from '@thisable/shave'; or something else? Personally, I'd rather do $ npm install @thisable/curry import {curry, shave} from '@thisable/curry'; I'm not quite following your point about
Is |
I totally agree with @davidchase. Was about to link to sindre's answer as well. |
Not sure if the group is interested in discussing this further, but what is being proposed is roughly equivalent to Underscore putting each of its APIs into a separate package/repo. Sindre's rationale does not exactly apply here. He has a bunch of little semi-independent utilities. Sure, in that case publish them as separate mini-repos, rather than in one big kitchen-sink repo. We and Underscore), on the other hand, have a group of related APIs. There are two sets of "users". One is the end-users, the other the developers. From the standpoint of the end-users, AIUI in the proposed structure we will be asking them to add a separate dependency for each module they want to use, and if they want to use both From the standpoint of us developers, multiple micro-repos means we have multiple repos to run tests in, multiple repos to handle PRs against, multiple repos to publish to npm, and multiple repos to handle issues about. On the other hand, I am having trouble thinking of any downsides to a single repo. One might choose separate repos if there were management/access control issues, which I don't think exist here. A user using e.g. browserify will bring only those individual pieces he or she needs, so there are no payload size issues. What other negatives are there? |
@rtm, I used to share your opinion on this subject – but a discussion with @mathdesl led me to change my mind. It’s not as easy to read as a blog post, but it does present good arguments on both sides: mattdesl/module-best-practices#2. By the way, multiple independent packages don’t always need to be multiple repos – as babel and parametric.svg (among others) show us. The setup of a multi-module monorepo is quite complicated in itself though – it might make sense with 1-liners but I’m not convinced of the benefits here. |
I will defer to wiser minds on this topic. I assume you have seen https://blog.andyet.com/2015/01/07/modularizing-underscorejs. He has implemented quite a bit of interesting machinery to manage his micro-repositories, including ways to create consolidated documentation, update licenses across all of the one-liners, etc. I assume we also intend to do something like that eventually? |
And I also presume you have seen this: https://github.com/babel/babel/blob/745f9fb5bd9dd5600ae0264d720ef0e16cc66228/doc/design/monorepo.md. |
If multiple packages are actually dependent on one another – would be developed in parallel / should have common docs / common tests / etc. – then a monorepo has lots of benefits! I’ve done this a couple of times now and it speeds up development by an order of magnitude! But it only makes sense with a single ecosystem of packages – and not when a bunch of packages are independent on one another. If thisables should become something like 1-liners then a monorepo is definitely the way to go. Where thisables should head long-term is rather a question to @stoeffel though. |
Agreed.
I don't intend thisables to become some thing like 1-liners. Thisables should be just a container for different modules which make use of the function bind operator. btw. I created a repo for shave and partial. If any one wants to start, feel free to do so 😄 |
I note that in the lodash implementation of curry
So someone, at least, thinks that is not necessary. And I cannot really think of use cases where it is. Of course we want to be able to find the length of functions like
function add(a, b)
, but in what cases do we need to know the length ofadd::curry()(1)
?I raise this point because the
util-arity
approach introduces another layer of nested function which will have a performance impact (I don't like the wayutil-arity
is implemented, either, but that's a separate issue), it introduces extraneous elements into stack traces, and so on.Then again, the https://github.com/dominictarr/curry library does maintain arity.
Do we really need to maintain arity on the result of currying a function?
The text was updated successfully, but these errors were encountered: