Live data from Hacker News

Promises are not neutral enough

staltz.com

121–130 of 133 posts

Re: Promises are not neutral enough

#121

I have a feeling the author doesn't understand Promises well. In my opinion, they are in fact designed poorly, but I don't see any problems with points the author describes. He doesn't like that the callback is called immediately - but Promises just represent a result that will be available later and do not guarantee (and should not) when the function will be called. If you want to delay some function call, do it exp…

Isn't throwing exception in promise same as calling reject?

The receiver of the promise is the one who should handle rejection. Not the one creating the promise.

If the receiver doesn't handle it you can register global error handler and log all unhandled errors.

Re: Promises are not neutral enough

#122
post #120

Earlier quoted context omitted.

Why use react when you can use Surplus which is based on S.js? Surplus is the fastest among all of the JS frameworks and supports JSX. "Slightly confusing" == I'm not familiar with it. Not really an objection. "No structural comparison": don't know what this is supposed to mean. Re: laziness, actually redundant recomputations are not performed. Not sure where you go that impression.

I don't want to use surplus because e.g. I want to use well developed UI components or toolkits like blueprintjs, which is implemented on top of React. Slightly confusing is a real objection. MobX strives to implement transparent reactive programming, where the way you access, update and transform values works exactly like it would with regular objects. S.js has a worse learning curve. Redundant computations are comp…

> MobX strives to implement transparent reactive programming, where the way you access, update and transform values works exactly like it would with regular objects. S.js has a worse learning curve.

Hardly: reactive values are get/set functions, and you create new ones with S(() => ...). That's it.

MobX's attempt at transparency yields inescapable and surprising corner cases.

> Redundant computations are computed; [...] even though the completed() computed isn't used anywhere, the reduction is still being recomputed every time todo state changes

Incorrect. The todos binding is an SArray not a regular array [1]. See my modified version where I log the events to the console [2].

[1] https://github.com/adamhaile/S-array

[2] https://codepen.io/anon/pen/KQyOyZ

Re: Promises are not neutral enough

#123
post #70

Earlier quoted context omitted.

> 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 resu…

Oh I like this. It's pretty simple, both code and conceptually, that it seems obvious in retrospect.

It allows a function to be cancelled from the outside, but only on its own terms, and gives the function a chance to clean up after itself.

I'm going to use this

Re: Promises are not neutral enough

#124
post #120

Earlier quoted context omitted.

I don't want to use surplus because e.g. I want to use well developed UI components or toolkits like blueprintjs, which is implemented on top of React. Slightly confusing is a real objection. MobX strives to implement transparent reactive programming, where the way you access, update and transform values works exactly like it would with regular objects. S.js has a worse learning curve. Redundant computations are comp…

> MobX strives to implement transparent reactive programming, where the way you access, update and transform values works exactly like it would with regular objects. S.js has a worse learning curve. Hardly: reactive values are get/set functions, and you create new ones with S(() => ...). That's it. MobX's attempt at transparency yields inescapable and surprising corner cases. > Redundant computations are computed; [.…

The number of tricky corner cases in MobX are very few. Also, once the implementation switches to proxies the vast majority will disappear.

I'm willing to accept a few corner cases as long as there is a large common subset of functionality that works both with and without a small number of decorators. This can be utilised to write models that can be used in both a reactive and a non-reactive context with a different set of decorators injected in. S.js looks too invasive to do this.

Your codepen has no completed todo count. Why are the recomputations logged every time here?

https://codepen.io/anon/pen/vdWomE?editors=0010

> That's it.

What about the poorly named "S.freeze"

Re: Promises are not neutral enough

#125
post #118

Earlier quoted context omitted.

Slightly confusing api, no structural comparison, no adapters for popular frameworks (e.g. S.js-react or S.js-preact), no laziness (computations are recomputed even if they're not requested by reactions).

Why use react when you can use Surplus which is based on S.js? Surplus is the fastest among all of the JS frameworks and supports JSX. "Slightly confusing" == I'm not familiar with it. Not really an objection. "No structural comparison": don't know what this is supposed to mean. Re: laziness, actually redundant recomputations are not performed. Not sure where you go that impression.

No structural comparison:

MobX will stop dependant recomputation if the new value of an intermediate recomputation is equal to the previous value.

You also have the option of using structural equality instead of reference equality (and also you can use any custom equality comparison function)

https://mobx.js.org/refguide/computed-decorator.html#options...

Re: Promises are not neutral enough

#126
post #87
post #79

Earlier quoted context omitted.

Promises don‘t swallow errors (sorry to be pedantic but there’s no concept of Exception in JS). They just propagate it to the rejection channel. What was your precise experience?

If there’s no logic to catch the rejection it will be silently ignored, which is effectively the same as “swallowing exceptions” – your distinction is correct but it’s academic at best. In practice, this behavior causes very real problems and in node land they made the sane decision to kill the process whenever an unhandled promise rejection comes about. I don’t know if this has landed yet, but you’ll see a warning a…

Uncatched rejections are deprecated in Node.js. In a future version, an uncaught rejection will crash Node.js

Re: Promises are not neutral enough

#127
post #124

Earlier quoted context omitted.

> MobX strives to implement transparent reactive programming, where the way you access, update and transform values works exactly like it would with regular objects. S.js has a worse learning curve. Hardly: reactive values are get/set functions, and you create new ones with S(() => ...). That's it. MobX's attempt at transparency yields inescapable and surprising corner cases. > Redundant computations are computed; [.…

The number of tricky corner cases in MobX are very few. Also, once the implementation switches to proxies the vast majority will disappear. I'm willing to accept a few corner cases as long as there is a large common subset of functionality that works both with and without a small number of decorators. This can be utilised to write models that can be used in both a reactive and a non-reactive context with a different…

> Your codepen has no completed todo count. Why are the recomputations logged every time here?

Because you can't apply reduce any other way. It's a computation defined over a whole collection. To incrementalize it, you'd need to be able to invert whatever function you're trying to apply in order to arbitrarily undo and redo the operation as elements are added/removed. This is literally impossible in general as not all functions have inverses.

You should also use the SArray methods directly rather than embedding within S(): https://codepen.io/anon/pen/NyXqjB

Edit: you can see a semi-incremental version exploiting map's semantics here: https://codepen.io/anon/pen/KQZddK

If you look at the docs for SArray, you see they describe that map avoids recomputation.

> What about the poorly named "S.freeze"

What would you call it? S.atomic? I don't see how the existing name is particularly unsuitable.

Re: Promises are not neutral enough

#128
I seem to be in a minority, but rarely do I want to use the `new Promise()` mechanism for creating a promise, and I get the distinct impression that having it be the 'default' is a bad idea -- the amount of times I've seen people wrapping up all their promise-related code inside the constructor, finishing off with `.then(function (x) {resolve(x)})` is disappointing :(.

async/await solves much of this, of course, but where that's not available I much prefer to keep all my async functionality actually async, and start off by using `Promise.resolve()`. Save the constructor for when you need to encapsulate some non-promise async code.

Re: Promises are not neutral enough

#129
post #124

Earlier quoted context omitted.

The number of tricky corner cases in MobX are very few. Also, once the implementation switches to proxies the vast majority will disappear. I'm willing to accept a few corner cases as long as there is a large common subset of functionality that works both with and without a small number of decorators. This can be utilised to write models that can be used in both a reactive and a non-reactive context with a different…

> Your codepen has no completed todo count. Why are the recomputations logged every time here? Because you can't apply reduce any other way. It's a computation defined over a whole collection. To incrementalize it, you'd need to be able to invert whatever function you're trying to apply in order to arbitrarily undo and redo the operation as elements are added/removed. This is literally impossible in general as not al…

> Because you can't apply reduce any other way.

In mobx, an unused computed will not run or recompute until its requested by a side effect (an autorun reaction, an observer component etc).

Example:

https://jsfiddle.net/ycufg9d3/

We use this to great extent in our application, by only rendering components that are visible in the viewport at the moment.

You can also keep its cached value alive, but not recompute it until needed by implementing a reaction that observes a computed but doesn't request its value. This will keep the entire computation graph cached but idle and partially dirty until the value is requested, at which point only stale dependencies will be recomputed. This can be extremely powerful: for example you can implement a state tree undo/redo by implementing serialize, then observing the serialize computed for the root item without requesting its value (keeping things cached) and only requesting recomputations when certain sufficient number of mutations are made. (with the vast number of reused values being structurally shared between undo/redo states)

> What would you call it? S.atomic? I don't see how the existing name is particularly unsuitable.

Yes atomic would be an improvement. Freeze only makes sense if you are thinking in terms of FRP signals in time, and its unclear whether the abstraction tries to hide its signal underpinnings or expose them (its somewhere inbetween)

Re: Promises are not neutral enough

#130
He actually missed my least favorite thing about the promise API, which is that they fail silently. I'd argue that by default, an unhandled rejection should throw an exception at the end of an event loop, with an opt-in for the current behavior per-promise.
Post reply on HN