Live data from Hacker News

Promises are not neutral enough

staltz.com

61–70 of 133 posts

Re: Promises are not neutral enough

#61

I think the author wants promises to represent computation, whereas they represent predetermined (i.e. single-shot) events. He mentioned C# Tasks, which do mainly represent computation, but in some cases Tasks are also used as events and this gets confusing as hell. I've worked with C# Tasks and hope that MS once cleans this up and builds the stuff on promises instead. Note that the C# language construct uses the awa…

Actually, cancellations can be useful to prevent wasting resources on useless computations. Imagine, if you have 2 threads doing some computations that will be later merged. If one thread fails, it makes no sense to continue executing other thread. That is where cancellation can help - but it should be thoroughly designed, not hacked like they usually do it in Node.JS.

I was not saying cancellations are not useful, I was saying cancellations are better handled explicitly via cancellation tokens (which compose perfectly, unlike computation based cancellation).

Re: Promises are not neutral enough

#62
This feels analogous to the problems w/ futures in Scala/Java as they were first introduced. And the solutions are provided by libraries like https://monix.io/.

So why are promises the problem instead of the lack of libraries on top of them? I understand cancellation cannot be fixed, but laziness sure can. As for synchronous execution, that's just not gonna happen in event-driven-land. It doesn't with other callback-based APIs (except AJAX which is deprecated) and I don't see the complaints there.

Re: Promises are not neutral enough

#63
post #43
post #19

I don't know. André Staltz is a great programmer, but I can't help but think what seems "opinionated" to him about promises boils down to the fact that they don't perfectly match certain quasi-ideological preferences he has about async programming, at the expense of all other concerns. As he states at the end, promises still work, you can get things done and everything is fine. But the part about them being opinionat…

This has nothing to do with it. I love promises but they are truly limiting. Here is an example of how promises limit the power of mobx https://twitter.com/spion/status/958906847385341952 Another example relevant in node is continuation-local-storage (equivalent to threadlocal storage). Implementing it on top of generators or other "chainable / thenable" abstractions is trivially easy. Implementing it on top of nativ…

MobX is horribly opinionated, a monstruous abstraction of spaghetti, and you're saying Promises limit it?

Re: Promises are not neutral enough

#64
post #16

Neither lazy nor eager is neutral. Sometimes you want one, sometimes you want the other, and you can build either out of the other. For promise cancellation, this has been talked to death, but in short, making any function preemptable at any point in its execution makes writing correct code much much harder. As an example, I've got an API that takes independently cancellable requests. Multiple requests often need to…

> A C#-style cancellation token API, orthogonal to promises, is simple, easy to build, and easy to understand.

I'm interested in learning more about this, do you happen to have any links to building such an api?

Re: Promises are not neutral enough

#65
post #19

I don't know. André Staltz is a great programmer, but I can't help but think what seems "opinionated" to him about promises boils down to the fact that they don't perfectly match certain quasi-ideological preferences he has about async programming, at the expense of all other concerns. As he states at the end, promises still work, you can get things done and everything is fine. But the part about them being opinionat…

I have to agree. This blog post comes from a place of judging what is "better" by some arbitrary abstract metrics (hint: the author's own library wins this contest). It doesn't consider what programmers use them for.

Promises are meant to semantically (and with async/await, syntactically) resemble a function call as closely as possible, while minimizing confusing errors. The author's "improvements" would ruin this.

If I need a bunch of features that a promise doesn't provide, like cancellation, I will write something to do it manually with callbacks. This is far less than 1% of async calls though.

Re: Promises are not neutral enough

#66
I don't agree. Promises are a solution to the asynchronous callback world, not a dream spec someone came up with.

1. Eager, not lazy: Why is lazy better? Sometimes I want eager, I use promises. Sometimes I want lazy, I use a promise getter. Done. What if it was the other case, how would I turn a lazy promise into an eager one without messy code?

2. No cancellation. Events that permit cancellation are rare. Situations in which you would want to cancel something are rare. If you face these, use a promise library that does permit cancellation. Bluebird does it.

3. Never synchronous. If you want synchronous, just don't use a Promise, use a function that takes another function. I don't get the point about "callbacks to sync". Callbacks are asynchronous. "Synchronous callbacks" may have this name, but they're not actually callbacks, they're functions. A function can take another function as a parameter, that doesn't automatically make it into a "callback".

Re: Promises are not neutral enough

#68

The analogies damage this article because they feel wrong. For example the "never synchronous" example is more like this: You order a burger at the cashier window, then go to the pickup window. If the burger is already made, it's already at the pickup window when you get there. The author wants a special case where if the burger is already made, they hand it to you immediately at the cashier window. This might seem m…

Exactly. If for some reason my promise is immediately fulfilled (e.g. the result was previously memoized), I don't want to provide an alternate codepath to handle the result.

Re: Promises are not neutral enough

#69
post #23

Earlier quoted context omitted.

This is a fundamental issue with multitasking, in that an independent task will have its own stack, so errors can't propagate up the stack of the function that started the task. e.g. consider this python code: def start_task(): Thread(do_task).start() What happens if do_task throws an exception? The exception can't propagate up from start_task because start_task may have returned when the exception is thrown. At some…

> otherwise there's no well defined place in your program for the exception to go. I don't see the problem with that. Unhandled exceptions can occur at any place of your program. I also don't see why the unhandled exception from the background thread cannot terminate main thread. Why not? That is how unhandled exceptions are supposed to work. Terminating the program is the optimal default behaviour for any error in m…

In Go there are two ways you can handle wrong things happening:

  - return an error
  - panic
What is the recommended, best, pretty, beautiful way? Return an error. Nobody uses panic.

Javascript Promises are equivalent to that.

If you want to stop the main program, call process.exit(). That would be the equivalent of panic.

Re: Promises are not neutral enough

#70
post #16

Neither lazy nor eager is neutral. Sometimes you want one, sometimes you want the other, and you can build either out of the other. For promise cancellation, this has been talked to death, but in short, making any function preemptable at any point in its execution makes writing correct code much much harder. As an example, I've got an API that takes independently cancellable requests. Multiple requests often need to…

> A C#-style cancellation token API, orthogonal to promises, is simple, easy to build, and easy to understand. I'm interested in learning more about this, do you happen to have any links to building such an api?

Creating a cancel token gives you two things: a token and a function. You call the function when the token should be cancelled, and the token can tell you when it has been cancelled. The simplest way to query the token is to call token.throwIfRequested(), which throws a Cancel if the token is cancelled. The token can also give you promises or callbacks of cancellation if you like, so you can do stuff like `const result = await Promise.race(token.promise, promiseOfResult);`

So you pass the token into a cancellable API, and that API calls token.throwIfRequested() in places where it is safe for it to do so (i.e. outside of critical sections).

A library implementing this in https://www.npmjs.com/package/cancel-token

Post reply on HN