promises-aplus / constructor-spec

Discussion and drafts of a possible spec for creating and resolving promises
10 stars 4 forks source link

point function #24

Closed Raynos closed 11 years ago

Raynos commented 11 years ago

@pufuwozu brought up a good point with his article

http://brianmckenna.org/blog/category_theory_promisesaplus

The notion of having a point function that takes a value and returns a promise would allow for writing powerful higher order functions.

Basically prior art, a-la category theory shows that having a function that looks like point is a good thing, we should consider this.

ForbesLindesay commented 11 years ago

P.S. Link to my summary gist: https://gist.github.com/ForbesLindesay/5392612

The corresponding arguments for will need to be a bit longer and include examples as those arguments are less well understood by the promises community.

techtangents commented 11 years ago

Map can be implemented on top of then and of if we get it to flatten a single layer rather than multiple layers.

Say what?

map shouldn't do any flattening. Map should take a Promise and a function and return a Promise that runs the function over the result of the original Promise. Just like how map over an array works.

"map" comes from the Functor type. The Functor laws state that map should return a value of the same structure. So, take a Promise of x, run a function x -> y over it and get a Promise of y.

One way of thinking of "flatMap" is that it maps then flattens.

As I understand it, this bizarre "then" function would be written in terms of map and flatMap.

puffnfresh commented 11 years ago

@ForbesLindesay as for limiting Identity of Identity. How far does it go? There's actual use cases for Optional Optional values. Or Either Either values. It also ruins parametricity, as @techtangents pointed out.

techtangents commented 11 years ago

And it breaks the Monad laws.

puffnfresh commented 11 years ago

@ForbesLindesay just s/Identity/Optional/g in my comment. You need to represent Optional Optional values.

ForbesLindesay commented 11 years ago
function map(entity, fn) {
  if (typeof entity.map === 'function') {
    return entity.map(fn);
  } else if (entity.chain === 'function') {
    return entity.chain(function (val) { return entity.constructor.of(fn(val)); });
  } else if (entity.then === 'function') {// && if then only flattens one layer, not multiple
    return entity.then(function (val) { return entity.constructor.of(fn(val)); });
  }
}
ForbesLindesay commented 11 years ago

In answer to @techtangents' "say what?"

ForbesLindesay commented 11 years ago

I still find the idea of an optional optional a bit weird, it would be hugely helpful if someone had an example, but I'll accept it for now.

techtangents commented 11 years ago

That's really weird.

Return a promise which evaluates the original promise, but maps a function over it.

function map(promise, fn) {
  return promise(function(x) {
    callback(fn(x))
  });
}
techtangents commented 11 years ago

I still find the idea of an optional optional a bit weird, it would be hugely helpful if someone had an example, but I'll accept it for now.

Well, you can think of an Optional as a List of either zero or 1 elements. Now think of a List of Lists.

charleso commented 11 years ago

I still find the idea of an optional optional a bit weird, it would be hugely helpful if someone had an example

James Iry has an example of that:

You're writing a cache system (in the form of an associative map) in front of a persistent storage with nullable values. Question: how do you differentiate between "I haven't cached this value" from "I've cached the value and it was null in the database"? The answer is that you can't use "null" to mean both things, it's ambiguous.

Raynos commented 11 years ago

@ForbesLindesay https://gist.github.com/ForbesLindesay/5392612#comment-816503 A new counter argument.

ForbesLindesay commented 11 years ago

Excellent example, thanks @charleso .

@techtangents I don't get what you're not happy with, it's even mentioned as something you can do in the Fantasy Land Spec.

ForbesLindesay commented 11 years ago

@Raynos just created https://gist.github.com/ForbesLindesay/5392701 I want to gather two separate gists and make each as strong as I can. I'll start incorporating other examples/counter arguments into each.

techtangents commented 11 years ago

@techtangents I don't get what you're not happy with, it's even mentioned as something you can do in the Fantasy Land Spec.

I must have missed something. Is this a way to provide a map implementation for things that have either map, chain or then, as an interoperability thing?

ForbesLindesay commented 11 years ago

Yep, it aims to implement map for anything which has either map, (chain and of) or (then and of but where then behaves like chain and only flattens one level).

P.S. if you put a new line after the quoted bit, it won't render the whole thing as a quote, it would also be helpful if you could go back and fix the formatting of a few past posts.

ForbesLindesay commented 11 years ago

@Raynos I've attempted to incorporate your example into the gist so I've deleted your comment as I want to keep them both free of commentary. I've included your arguments (rephrased slightly) in https://gist.github.com/ForbesLindesay/5392701 There may be more to add, if so, please make suggestions in comments on that gist not the gist giving arguments against promises for promises.

ForbesLindesay commented 11 years ago

How do people feel about my previously proposed suggestion for ultimately closing this issue. I feel the discussion has gone on too long with too much back and forth repetition in this issue to expect newcomers to catch up. This is why I want to start a fresh with just a summary of the arguments for and against that were discussed in this issue.

Twisol commented 11 years ago

@ForbesLindesay: Sounds like a good proposal to me. I'm glad to hear about your moment of epiphany!

Raynos commented 11 years ago

@ForbesLindesay what we really need is two new issues in the correct place. One with an amendum to .then() to not recursively flatten. The other is an amendum to whatever to add .of() (this probably requires speccing out the semantics of of() in more detail).

ForbesLindesay commented 11 years ago

I'm happy to see that issue for of. I just think that, since we're very close to releasing a new promise spec that would forever make this a backwards incompatible change to the spec, we should focus on that for the time being.

If you ask for one, small change, and justify it, it's much more likely to get proper consideration than if you open lots of simultaneous issues asking to change everything. Lets first argue for the value behind only unwrapping a single layer, because if we have that, we can move forwards without breaking backwards compatibility. To this end, I have opened https://github.com/promises-aplus/promises-spec/issues/101 which I think should serve as the only place for discussion on this issue for the time being.

If we can agree there that we want promises for promises to be a possible thing, you're very unlikely to see any arguments regarding promise.of being specc'd in a very simple, sane, way.

techtangents commented 11 years ago

As an aside: http://www.techtangents.com/on-options-of-options/

techtangents commented 11 years ago

Also, @ForbesLindesay, you said you didn't understand liftA2. I've tried to explain this in http://www.techtangents.com/explanation-of-lifta2-in-javascript/

There are lots of other tutorials on Functors, Applicatives and Monads out there. Most of them are in Haskell or Scala, though, not JavaScript. I would highly recommend you learn Haskell as it makes it easier to understand these concepts, so you can then apply them to your coding in other languages.

briancavalier commented 11 years ago

There's a ton of good information in this thread. Thanks, everyone.

I agree with @ForbesLindesay that it has reached the point where it's best to close and direct energy toward promises-aplus/promises-spec#101, specifically noting the process that has been set forth there.