HNHacker News
TopNewBestAskShowJobs

CrossEye

162 karma · joined January 24, 2013

submissionscomments
CrossEye··on How currying leads to elegant, readable code
A nice example. Thank you.

I just want to note that in Ramda, because of it's strong insistence on a data-last API (which makes the currying easier), this would be written in this order:

    result = filter(greater(R), map(distance(origin), array));
But it's precisely the same idea.
CrossEye··on How currying leads to elegant, readable code
I finally got a chance to watch that video, and it looks as though what you're worried about is `flip`. Ramda for one already includes a version that works much like Haskell's. I don't know if this satisfies your objection, though.
CrossEye··on How currying leads to elegant, readable code
Just to note, the copy wasn't meant to deal with mutability but to note a changed interface. The items that are emitted have only a subset of the properties of those ingested. We could as easily have added some new properties to them as well. Mutability wasn't the primary concern here (although in Javascript it's always a genuine concern.)
CrossEye··on How currying leads to elegant, readable code
I think languages that have named parameters have very different sorts of techniques for these things. I don't know if they're more powerful or not, but they take a very different approach, and offer different design choices.
CrossEye··on How currying leads to elegant, readable code
It is harder to debug points-free code. I find myself doing more debugging with `log` statements in a long pipeline than I do with other styles of code.

On the other side, I tend to work with a few well-tested functions over and over and end up with fewer problems to debug when I work in a functional paradigm, points-free or not.

On rare occasions, when I need to debug something that is difficult because it's points-free I simply add some explicit parameters, either temporarily to enable debugging or permanently.

Points-free is nice, but should never be an overriding goal.

CrossEye··on How currying leads to elegant, readable code
You can if you want:

    var jp = function(last) {
        return formatNames2('John', 'Paul', last);
    };
    var je = function(last) {
        return formatNames2('James', 'Earl', last);
    };
    var lh = function(last) {
        return formatNames2('Lee', 'Harvey', last);
    };
    var c = function(middle, last) {
        return formatNames('Clarabelle', middle, last);
    };
But I find this cleaner:

    var jp = formatNames2('John', 'Paul'};
    var je = formatNames2('James', 'Earl'};
    var lh = formatNames2('Lee', 'Harvey'};
    var c = formatNames('Clarabelle'};
CrossEye··on How currying leads to elegant, readable code
Yeah, I probably shouldn't have cribbed the example from my old "Intro to Functional Programming" talk...
CrossEye··on How currying leads to elegant, readable code
I don't think currying can reasonably be combined with optional parameters. At least I've never seen a useful way to do so.

In a previous article (http://fr.umio.us/why-ramda/) I discuss more thoroughly how I would tend to use this currying, namely to build up collections of useful functions, often in points-free style, so that major parts of the application would end up as (ideally well-named) functions, each which serve as pipelines of these smaller functions, passing data through the system.

I do find this significantly more readable, but _de gustibus non est disputandum_.

CrossEye··on How currying leads to elegant, readable code
I've done that too, then had to wave my hands about why I choose that parameter order, when I know damn well the languages isn't going to change... "But just in case...." :-)
CrossEye··on How currying leads to elegant, readable code
Yes, at first glance, that's pretty close. (You'd have to do something about `.getTime()`, as the original just did lexicographic sorting on date strings.)

The article really didn't get into the fact that these blocks of code that were listed inline would ideally represent reusable functions. That these functions would best be defined separately and only included by reference would have cluttered the article, but leaving them out does make it feel a bit like a strawman, I agree.

The breakdown of a task into these smaller functions is something I discussed more fully in the previous article: http://fr.umio.us/why-ramda/

CrossEye··on How currying leads to elegant, readable code
Have to thank/blame @buzzdecafe for that!
CrossEye··on How currying leads to elegant, readable code
Yes, freely admitted. (Author here.)

I feel that although the distinction can be very important, it's much less so for Javascript. And the implementation in Ramda can be used that way any time you choose:

    var total = reduce(add)(0);  // or 
    var sum = reduce(add)(0)(numbers)

works just as well in Ramda as

    var total = reduce(add, 0);  // or
    var sum = reduce(add, 0, numbers)
So, as I said, feel free to keep on insisting. :-)
CrossEye··on Why Ramda?
As a developer of Ramda, I can tell you that this will probably be a long wait! That's not the sort of library this is. It's not trying to be a Javascript answer to Django; Javascript already has Angular, Backbone, Knockout, Ember, and many others.

Ramda is a utility library aimed at helping you use a particular style of coding (the composition of short readable functions) against consistent data structures (arrays of JS objects are perfect, although there are others that you could use.)

CrossEye··on Introducing Ramda: A practical functional library for JavaScript developers
As the co-author of Ramda, I'm excited to finally see this thing getting out there.

Next up, algebraic data types?

CrossEye··on Prototypes Are Not Classes
I think there is a serious problem in vocabulary. Wikipedia's definition of class ([1]) is quite reasonable, which, slightly paraphrased, reads, "A class is an extensible template for creating objects, providing initial values for state and implementations of behavior." While typically we don't use prototype objects for default state in Javascript, we always can if we choose, and they are widely used for providing behavior. And both "extensible" and "template" fit well. So by this definitions, prototypes really are classes.

But almost everyone who comes to Javascript from a class-based language brings a number of additional preconceptions. I don't know the Ruby community well enough to know if your descriptions are accurate, but I know that many of those coming from Java or C# backgrounds expect classes to be (1) distinct creatures from objects (and those who know much about the reflection class Class understand that the objects of that class are objects and not the classes themselves), (2) design/development/compile-time abstractions separate from the run-time realities, (3) unchanging at runtime (which is obviously different from Ruby), and (4) the enforcers of access policies of instance methods. None of these things are true for Javascript prototypes. So to these people, it's easiest to explain that Javascript does not have classes.

I have never implemented a serious programming language. But I understand from those who have that implementing classes and implementing prototypes can be very, very similar processes. So, while I won't stop insisting to those from other languages that Javascript doens't have classes, I do recognize that I'm talking more to their preconceptions and not to the deepest truth I know.

  [1]: http://en.wikipedia.org/wiki/Class_(computer_programming)
← PreviousPage 2 of 2