Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Curry flavored promises (lhorie.github.io)
28 points by lhorie on April 28, 2014 | hide | past | favorite | 17 comments


Hi author here.

Thanks for the feedback! Just wanted to clarify some points:

I should probably have noted that the usage of console.log is illustrative and is typically only used for debugging (the idea being that console.log could be used in Firefox, or you could wrap it in a log helper function, or use alert or whatever).

Typically, in a Mithril app, you'd either assign the promise to a variable or bind to an m.prop at the end of the chain, as per the docs on web services ( http://lhorie.github.io/mithril/web-services.html )

Regarding console.log returning undefined: Mithril does deviate from A+ promises (again, as per the docs - http://lhorie.github.io/mithril/mithril.deferred.html ). The reason for the spec deviation is precisely to allow the use case of mixing procedural impurity into a chain (whereas the undefined case covered by the spec isn't really useful, given that undefined is the lack of a value, as opposed to null, which is a value with no meaning).

@anaphor: huh, reading about currying again, you're right. Little misunderstanding on my part. Sorry about that.


That's okay, I've seen people with PhDs confuse them before, it's a common mistake, and currying gets you partial application "for free". Good article nevertheless!


>Currying is a functional programming technique that lets us pre-define arguments in a function

No it isn't, that's partial application. Currying is (lambda (a b c) ...) => (lambda (a) (lambda (b) (lambda (c) ...))) generalized to any number of parameters.


    //here's an AJAX request and a chain of promises
    m.request({method: "GET", url: "/api/projects"})
        .then(console.log) // log all projects
        .then(pastItems) // filter past projects
        .then(console.log) // log past projects only
The calls to console.log will not work.

You need to do this:

    .then(function() { console.log(arguments); })

Or this:

    .then(console.log.bind(console))


Yeah, the example couldn't work. Also, isn't this an example of partial application, not currying?


Yup.


Funny this mistake rarely goes the other direction. Probably because 'curry' is a fin word.

I propose 'parry' for "partial application", to satisfy the punsters without compromising accuracy.


this

    console.log.bind(console)
doesn't work in old IE you need to do

    Function.prototype.bind.call(console.log, console)


well, it depends on the console.log implementation :)

On firefox I get

    >>> console.log.call(undefined, "Hi")
    Hi


console.log is bound in Firefox and in Node. In all other browsers calling console.log.call(null) is a TypeError.


Do these promises work differently from most other implementations? Just sticking a `.then(console.log)` seems like it would yield `undefined` to the next function in the promise chain, no?


Maybe the code was untested or only tested in firefox or node, where `console.log` is bound (which is sane default for singletons if you ask me)


It's true that console.log is bound in FF and Node but that s not the issue here. Passing console.log to then will cause the next handler to receive the return value of the console.log call, i.e. undefined.


In mithril promises if you return undefined from then, the promise will fulfill with the previous value, I.E. it behaves like .tap in other promise libraries (because doing this in a .then like mithril does violates the spec - which is evidently surprising)

However, with unbound console.log the code doesn't work at all, this is the case in Chrome for example.


The breaks from A+ are pretty serious, both the treatment of undefined and releasing zalgo (http://blog.izs.me/post/59142742143/designing-apis-for-async...) and calling it a feature. Not on the hunt for a client side micro-framework but since I use a lot of modules that supply promises there's no way I'd use this.


agree, this sounds like a bug, console.log() returns undefined so that's what the next promise in the chain should receive.


total_sum = total.curry

sum_of_cubes = total_sum.(lambda { |x| x^3} )

sum_of_cubes.(1,2)

In ruby way




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: