5 ms·
> If you write your promises code not to cause explicit side effects - it won't and you get pure code. The way I've seen promises used in JS is always in this
by dangoor 11y ago
> If you write your promises code not to cause explicit side effects - it won't and you get pure code.
The way I've seen promises used in JS is always in this pseudocode form:
- initiate something side effecty (making an HTTP request, for example)
- resolve the promise once the value is ready
Is there something you have in mind for how we'd write promises-based code without side effects in JS?
- inglor 11y agoThe same way you'd write "code that doesn't cause side effects" in Haskell. You cause side effects. The thing is with promises (like IO) the side effects are limited to a box you can open, process and close. So given the same input the same function will always return the same output. If you have a function that asynchronously computes a random number - it won't return different numbers and will always return a promise for a random number. It will never be observable that being called with a different input it produced a different output (as long as you don't mutate global state or anything like that). In Haskell, IO is implemented in a way that causes side effects at the platform level. If there are no side effects there is nothing going on and the program is a no op after all :) Monads like IO are about _limiting_ side effects and _controlling_ state. In Haskell, the lack of side effects is by the fact IO is provided by the platform. There is no fundamental difference between Haskell's `getLine` and the DOM's `fetch`, both return a boxed value.
- dangoor 11y agoThanks for the followup! > In Haskell, the lack of side effects is by the fact IO is provided by the platform. There is no fundamental difference between Haskell's `getLine` and the DOM's `fetch`, both return a boxed value. In his talk about "effects"[1], Chris Armstrong also talked about making testing easier in Haskell, though I paid less attention to that part, to be honest. `fetch` returns a promise, but calling fetch causes the side effect to occur immediately. I don't know if that's how `getLine` works in Haskell. If I want to test code that calls `fetch` without an HTTP request actually hitting the network, I need to put in a mock `fetch`.[2] Or, if there was another return type that put the side effect in a box that the platform handles later (or not at all, in the case of a test), that seems like a win. [1]: https://www.youtube.com/watch?v=D37dc9EoFus https://www.youtube.com/watch?v=D37dc9EoFus [2]: another option, pointed out on Twitter, is that a promise (either from the fetch or from the test) could be passed in to the code under test. That seems less pleasant but requires no new machinery.
- inglor 11y agoFetch doesn't actually make an HTTP call - that's the thing :) Fetch boxes a value so that the _platform_ can make an HTTP call. You couldn't implement `fetch` yourself without platform APIs and you certainly couldn't do it in JavaScript without the DOM. The second suggestion you pointed (from Twitter) is exactly what you'd do in Haskell (you'd pass an IO from somewhere else). You can call it "pass an effect" if you'd like but it's the same thing :)
- dangoor 11y agoIndeed, the platform is responsible for the HTTP call, so I see what you mean. The side effect is happening in the platform itself. I should watch the second part of Chris Armstrong's video to see how he approached making testing nicer in Haskell.
- danmaz74 11y agoI read the OP's comment as: you can write the "then" functions as pure functions, and they won't have any side effects; those will then be isolated inside the code that resolves the promise - code that you usually don't write yourself as it is part of some library, as with "fetch(...)" for making an HTTP request.
- dangoor 11y agoSure, the `then`s could be pure functions but the whole point of my blog post is that I'd like to be able to test code that calls `fetch`. That would be possible if the actual side effecting operation is deferred to later, and not just the result.