-
Notifications
You must be signed in to change notification settings - Fork 30
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
Version 1.0 mission statement, increasing focus #27
Comments
As well as depreciating functionality explicitly for handling connections there is functionality for handling functions that might be missing. fn.times(3, function(){ console.log('hello'); })
// => 'hello'
// => 'hello'
// => 'hello' |
Change log for pending changes effecting 0.9 release. |
Why drop methods that exist in ES5 because they have the same functionality? The point of having a different implementation is to introduce composability of methods, which cannot elegantly be done without state with native methods. I think this move would also kill pointfree style. |
So the main reason I have for dropping them is to separate fn.js from being a general utilities library. With the possible merger of underscore and lodash they are fulfilling that role. With map/reduce/filter gone fn.js is only a function utilities library. For fn.js to work as a source of collection utilities it needs several more such as first etc. |
The problem with underscore/lodash is that it's own core methods are not composable, notably because they don't follow the function-first/data-last paradigm. |
I don't understand this proposal at all. Functional programming is many things, but there are some common themes, and you've certainly hit on a few of them with your list. Immutability and referential transparency would be high on any list, and while a JS library is not going to enforce either idea, it can promote them, and can at least ensure that it doesn't mutate user objects or provide referentially opaque functions. It can avoid side effects, and can generally avoid providing functions whose main purpose have to do with side-effects. Your other two points, 1 and 4, are a little different. #1, a collection of functions on a data structure is not simply nice to have; it's essential. While your underlying data structure does not have to be lists, functional programming involves building up systems from functions that operate on your data. (The well-known Alan Perlis quote comes to mind: "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.") The basic functions involved definitely belong in a library. There is plenty of room to discuss what should and what shouldn't be included, but providing nothing at all, and only providing functions to modify other functions makes no sense to me. It sounds like recursion without a base case. #4 on your list discusses "working with first-class functions." Given that functions in JS already are first-class, this really just means, "working with functions." This is all well and good. But what are those functions you're working with themselves working with? At some point, you need to start with something. And if that something involves lambdas you're going to lose a lot of expressiveness. The same is true with Underscore/Lodash. They are designed for a different paradigm. Given this (please forgive the Ramda usage; I don't know fn's API that well): const square = n => n * n; It's the difference between const sum = R.reduce(R.add, 0);
const addSquares = R.compose(sum, R.map(square)); and const sum = ns => ns.reduce(R.add, 0);
const addSquares = R.compose(sum, ns => ns.map(square)); I believe the latter is significantly less readable and clear. And it will get significantly less clear as more lambdas are used. To me, this would be the death of the library. I would suggest that if you want to do this, fork the library with a different name, and leave fn.js to work more like it has. I don't know what sort of user-base fn.js has, but I can't see that this could do them any good. |
@eliperelman in this case ramda would have been a better example of a project that overlaps with fn.js @CrossEye I see you points but I would just like to see if I can convince you with a few counter points.
It's certainly possible that this project can die by a) not having a maintain or b) not having any reason to exist as all of its functionality is available in ramda.
The most interesting viewpoint in this discussion would be from someone who sometimes uses ramda sometimes fn.js and could provide insight to what the reasons for using each are. |
@CrowdHailer agreed, but just because 2 libraries do the similar things doesn't mean they can't co-exist. fn.js doesn't autocurry and also sacrificies performance for the sake of internal purity as much as possible. Not that this was a good idea, but maybe it's important to someone. Take underscore/lodash for example. They both do they same thing with an identical API, and yet they both thrive.
I can't disagree with one thing that @CrossEye has said. |
My thoughts are at this point: if you want to fundamentally shift the purpose and functionality of the library, then it is no longer fn.js. I'd agree with @CrossEye and say to fork and publish with a new name. |
I'm having a difficult time disentangling two strands of thought in how I want to respond. The first is how this change would make me feel about the library personally: it would become a library I'm not interested in using. The second is what the change means for whoever does use it, and for the wider community; I believe it removes one of the few truly practical Javascript libraries designed on a certain set of simple principles. As to the details, yes fn.js does not now auto-curry, but it sounded as though #20 is back in play, and I would hope that its functions will soon be curried. I used Ramda as an example because although I've been watching fn.js almost since its start, I really haven't been a user. I've been too busy on Ramda to do much more than watch the other libraries that interested me. But fn.js is one of the ones I've watched with greatest interest. It and FKit, and more recently fnuc, were the only ones that seemed to have the same principles. FKit stalled entirely some time ago, and while fnuc is quite interesting, it seems that fn is closer in spirit to Ramda. I suppose that some might be happy to have their library gain major popularity, and wouldn't be sad to see competing libraries fade away, but @buzzdecafe and I did not set off to create a popular library. Ramda was a learning experience. I'd long promoted functional programming in JS, but it was a fairly anemic set of FP ideas I was concerned about until @buzzdecafe and I both read the first edition of @raganwald's JavaScript Allongé. I started a repo to play around with these ideas, and asked @buzzdecafe to join me almost immediately. It was our own playground for well over a year, known to us and a few friends, but not used anywhere, until we both were in a class taught by @DrBoolean and @begriffs where they had chosen Ramda as the library. At that point, we decided that if these guys thought it worth using, maybe we could talk about it. So we wrote some blog posts, and the library took off. We had to learn how to foster a FOSS community, which was not a goal we'd ever had. But it's been a fun ride. Still, although I've enjoyed it all, I've wanted Ramda to do well only insofar as it's promoting good FP practices in the JS community. I'm thrilled that it's just had its millionth download, but I would stop using it immediately if there was a better tool for the type of coding I want to do. (Of course I might also try to improve Ramda to match, but that's not the point.) Ramda is currently struggling with a difficult problem, one that might affect other similar libraries, an issue of dealing with the desire to use certain native optimizations when there would be no differences between value equality and reference equality, something that would substantially speed up our versions of functions such as I was not hoping for fn.js to necessarily be that alternative tool that we looked to, but to me having a good marketplace of related, but substantially different, tools, makes everyone better. The trouble here is not that this would be different; that's great. The problem is that this would shift off far enough that I would no longer find fn.js interesting enough to bother with. Perhaps I'm wrong. Maybe a library of plain function decorators with no data manipulation tools would be interesting on its own, but I don't see it. Back to specifics, we discussed const map = fn.curry((f, list) => list.map(f)); or this: const map = fn.curry((f, list) => _.map(list, f)); and similar things for many other core functions. So, as always, I'm way too verbose, and I apologize. I was so excited to see that fn.js was going to continue, and this change has got me crashing back to Earth. This of course is your decision. I do hope you will consult with Eli. But I do understand that in shepherding a library, there are difficult decisions to make, and you won't be able to please everyone, not even cantankerous maintainers of competing libraries. So best of luck with it. |
@CrossEye the verbosity is very helpful. Thanks for taking the time to reply. It was certainly never my intention to be quite so controversial in my suggestions. I honestly thought the prime use for the functions above was in implementing the more interesting functions such as throttle. This would allow fn.js be an onramp to functional programming in JS. It is also not my expectation that users use In this system each looks like the following function each(fn, collection){
var partial = function(collection){
collection.forEach(fn);
}
return collection === void 0 ? partial : partial(collection);
} This enumerable library obviously doesn't have functions like throttle etc hence I use fn.js. Also why I consider handling collections and handling functions to be two separate concerns. I am taking on board all that's said and am really grateful for the time that has been spent on expressing your position. I still think that a library, 'to make functional programming good' dooms fn.js to growth. However if I will see how much sense I think there is in including just the functions mentioned. If the consensus is that I am still taking fn.js too far from its roots. I will start my own project. |
Proposal
Currently
Proposed change
Rational
There are several pieces that need to come together to encourage functional programming. These include some of the following.
fn.js Does not try to tackle points 2 or 3 and nor should it. At the moment it tries to solve some of point 1 and all of point 4. fn.js does not tackle point 1 as well as alternatives, it is missing functionality like head, fist, last, tail, union, zip etc.
This proposal is to have fn.js NOT tackle point 1 and focus solely providing utilities for manipulating functions(i.e. point 4).
Repercussions
The text was updated successfully, but these errors were encountered: