It seemed unnecessary, yes, although I suppose there are possibly some circumstances where one might want a `first` function—for example if one were folding over a list of lists.
In most cases the "a[0]" approach works, however. The set of circumstances where you want "first" as a proper function is limited to those cases where you need to pass it into some higher order function (which is still infinite, granted, but it's not 'every time we'd want "car"').
As both a functional and a javascript programmer - I don't see the point of the curry function. I understand currying is great, I even use it a lot, but I don't see the benefit of converting a "normal" function to a curried one.
I mean, when I need currying, I just write my code like that.
Everything else looks pretty awesome!
Have you looked at underscore (http://underscorejs.org/) a lot of the functionality seems to overlap (and it's what I've been using for a long time to make functional javascript a bit more palatable)
I'm with you on the currying thing. The ability to curry functions doesn't enable you to do anything you couldn't already do better and with more flexibility by writing the full anonymous function.
// Lets curry subtract instead of add
var subtract = Udon.curry(function(a, b) {
return a - b;
});
var five_minus = subtract(5);
var minus_five = Udon.flip(subtract)(5)
Yes, although there is one subtlety here: should `flip` return a curried function, or an uncurried function? This isn't an issue in Haskell since it only has unary functions.
Yes, it does. This is true in Haskell too, of course.
subtract :: (Int, Int) -> Int
subtract (n, m) = n - m
fiveMinus = (curry subtract) 5
minusFive = ???
subtract' = \n m -> n - m
fiveMinus = \m -> 5 - m
minusFive = \m -> m - 5
To be honest, I completely agree with you. But it wouldn't be a JavaScript functional programming library if it didn't have the curry function.
I'm pretty familiar with Underscore, just wasn't happy with a couple of the design decisions, otherwise I would have just used that. Udon actually came out of various hacky functional JS libraries that I'd written over the years, and part of the motivation was to pull those together into a clean and coherent codebase.
I'm in the process of writing my a functional utility library myself, and having thought about these things for a while, I think letting everyone curry things themselves make things less intelligent.
For example:
Udon.elem(2, [1, 2, 3]) === true;
As it stands this is simply an accessor for Array.prototype.indexOf. If people know how to use that, this alias is relatively useless unless you want to compose. And even then, you could always compose around the expression, or with a method on the prototype of the result (Number in this case).
However, it's very useful to have a curried version of it so that it can be used in filters:
This maintains your current javascript indexOf usage, but allows a higher order use that I think should be the default for this function.
If you want you JavaScript to look more like Haskell, then your way makes more sense, but having to write Udon.curry everywhere sort of takes away from that cleanliness you are trying to recreate. I prefer to not mess with existing semantics too much because of it. For reference, here's my library: https://github.com/clux/interlude#usage
> having to write Udon.curry everywhere sort of takes away from that cleanliness you are trying to recreate.
This is true, and I considered your approach when writing functions like `elem`. There were two reasons for this. Firstly, I wanted to avoid introducing more closures than necessary. Secondly, I wanted to keep the source code reasonably transparent (if admittedly rather terse).
There is definitely a place for your approach, and it may even be the better one in practise. It's hard to say without writing large projects in both.
Is it standard practice in other languages / libraries to have the function argument first and the data argument second, in e.g. map and filter?
In usual PHP fashion, array_map and array_filter take arguments in different orders. From all the jQuery i write it seems more natural to put the function argument last ($.get, $().bind, etc).
The other reason things work this way in functional languages might be the way your nesting tends to work out. For example, it would be common in Clojure to write something like:
If you are interested in this you might want to check out http://gkz.github.com/prelude-ls/ - it has almost all the functions included in Udon as well as about 60 more based off of Haskell's Prelude module.
That's very cool, although you have to use another dialect of JavaScript if you want to modify the source code, with all the disadvantages that entails.
True, but taking that aside and focusing on practicality, both underscorejs and Preludejs together provide one heck of a toolbox. I really enjoy functional programming a great deal and have been using it every which place I can the last several years. I totally understand that this is your take on the subject matter and so far so good, though the docs and usage for me are strange. If you have the goal of mass adoption you'll need to convince people like me why it needs adding to the toolbox.
I don't think one can ignore that and also focus on practicality. Using these JS dialects is a practical issue. Learning them and remembering how they work imposes a certain amount of overhead, albeit a reasonably small one. Of greater concern is maintaining projects written in these dialects: what if the support around key parts of your toolchain goes away? Of course they're open source, so you can maintain them yourself—but that may be a lot of work, and will rarely be the highest priority. Ultimately it may be more effort than it's worth, even if it's a lot more enjoyable to write than vanilla JavaScript. I'm not saying that this will always be the case, but it's an issue that does need to be addressed before jumping in and using them on a major project.
Anyway, Udon was really just a personal library which I tidied up and documented in case it might be of use to somebody. I think this is generally good practise: it encourages one to write clean, maintainable code, some documentation, and a test suite with reasonable coverage. In principle one should always do these things, but somehow putting it somewhere public makes it more likely that they'll actually happen. I was actually quite surprised to see it on Hacker News today, since I first wrote it two years ago and last made any changes to the source code over a year ago.
In other words, I'm not exactly falling over myself to promote it to the wider world or make it fit people's needs other than my own. Patches to increase the functionality of the library or improve the documentation would of course be welcome, and several good suggestions have already been made on this thread. But I'm not too concerned about convincing people here or elsewhere that they should be using it. In fact, they probably shouldn't: as you and others have said, most or all of its functionality is provided by other libraries which are far more actively maintained (this is really just a corollary of my first point).
However, I would be interested in hearing what you think is strange about the documentation and usage.
It's an issue I see when things go public. Public then mainstream. As such mainstream users mean mainstream docs. So my evaluation was in those eyes. The most important thing to gain is refinement that can be learned for the next lib you may or may not start/contribute to.
If a reader knows what the words in the description mean, then presumably they know what currying is...
Wouldn't it be better to have documentation that illuminated, rather than showed off your grasp of programming terms?