I am Software Developer, currently interested in static type languages (TypeScript, Elm, ReScript) mostly in the frontend land, but working actively in Python also. I am available for mentoring.
I think when you say "imperative" you mean "statement based", and when you say "functional" you mean "expression based". Promises are imperative how you will use them do not change it, async/await makes promises composition more like steps, in the same way "do" syntax in Haskell. In general I think you are referring to the fact that you prefer composition of expressions instead of using assignment statement. Where for me it is no specially different, it is only lets say code style, I can say for example that let expression from Elm/Haskell in JS can be replicated by just assigning local variables, this solutions are equal until we start mutating staff.
I write code, front-end and back-end, and like deploying it on AWS. Software Developer for 20 years, and still love it. Amateur Powerlifter & Parkourist.
Sort of. I make a ton of assumptions on the reader which I maybe shouldn't? If I don't, I end up writing 10 pages.
First, I assume we're using as pure of functions as possible. This means, ivory tower, there are no exceptions, but rather, a Result or Maybe is returned. So you're you're just changing this:
However, even though I screwed up return and called it retun in the function, the Promise just "handles" it fo me; no action on my part. That's the kind of stuff I know will happen eventually. It's the other stuff I don't that is quite complex like http/node-fetch responses that get super hard and complex. I'll start high level, like response => response.json(), but then break it down to handle statusCode, and various return values based on the API. Again, these functions are as pure as possible, and tend to return multiple values or a Result. The catch is always there to say "Yo dog, this is JavaScript, you missed one.... why aren't you using types?"
You can do that same style in async/await, no doubt, but I find people who do really don't care about pure functions, dependency injection, or any other FP style concepts. Again, though, you have to remember to put try/catches, whereas with Promise you don't.
The caveat with the above is in the browsers, I've seen some horrible things with window.onerror returning true. It's... it's really depressing. They'll basically create a global denylist, and say "we don't care about runtime exceptions, except for these 3". I know some love that power, but I'd prefer they endeavor to write more solid code. Yes, I get that's impossible in JavaScript, but you can make an effort and see improvements here; I believe it's worth doing.
The other caveat is Node.js, especially recent versions like 12 and 14. If you don't have a try/catch, or a catch on Promise changes, she'll crash your whole program, which I agree with. However, again, I've seen people do process.on for both sync and async exceptions and use that as a crutch rather than do the work to write more solid code. Again, that's nuanced, because some code bases are just... well, brutal. They might have been inherited or have 3rd party nastiness, so I get it. My empathy, however, doesn't condone that behavior.
Yeah, do in Haskell and let in Elm are "crutches" I use a lot. Despite practicing FP for years, my brain is still wired to think about hard problems imperatively (in sequential statements like you said). The let keyword helps immensely when I'm trying to reason about a problem in steps. I think the difference there, though, is:
you have types so you can't screw it up, or the compiler won't compile your code and
you're forced to handle Nothing or Failure scenarios where in JavaScript you can just "oh it's a happy path, if it fails, that's ok"
Ok, now you said the mutating word, it's too early in the morning... I can't go on. :: hugs immutability coffee cup ::
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I think when you say "imperative" you mean "statement based", and when you say "functional" you mean "expression based". Promises are imperative how you will use them do not change it, async/await makes promises composition more like steps, in the same way "do" syntax in Haskell. In general I think you are referring to the fact that you prefer composition of expressions instead of using assignment statement. Where for me it is no specially different, it is only lets say code style, I can say for example that
let
expression from Elm/Haskell in JS can be replicated by just assigning local variables, this solutions are equal until we start mutating staff.Sort of. I make a ton of assumptions on the reader which I maybe shouldn't? If I don't, I end up writing 10 pages.
First, I assume we're using as pure of functions as possible. This means, ivory tower, there are no exceptions, but rather, a
Result
orMaybe
is returned. So you're you're just changing this:to this:
... but then you have to ensure
JSON.parse
is actually:However, even though I screwed up return and called it
retun
in the function, the Promise just "handles" it fo me; no action on my part. That's the kind of stuff I know will happen eventually. It's the other stuff I don't that is quite complex like http/node-fetch responses that get super hard and complex. I'll start high level, likeresponse => response.json()
, but then break it down to handle statusCode, and various return values based on the API. Again, these functions are as pure as possible, and tend to return multiple values or a Result. Thecatch
is always there to say "Yo dog, this is JavaScript, you missed one.... why aren't you using types?"You can do that same style in async/await, no doubt, but I find people who do really don't care about pure functions, dependency injection, or any other FP style concepts. Again, though, you have to remember to put try/catches, whereas with Promise you don't.
The caveat with the above is in the browsers, I've seen some horrible things with window.onerror returning true. It's... it's really depressing. They'll basically create a global denylist, and say "we don't care about runtime exceptions, except for these 3". I know some love that power, but I'd prefer they endeavor to write more solid code. Yes, I get that's impossible in JavaScript, but you can make an effort and see improvements here; I believe it's worth doing.
The other caveat is Node.js, especially recent versions like 12 and 14. If you don't have a try/catch, or a catch on Promise changes, she'll crash your whole program, which I agree with. However, again, I've seen people do process.on for both sync and async exceptions and use that as a crutch rather than do the work to write more solid code. Again, that's nuanced, because some code bases are just... well, brutal. They might have been inherited or have 3rd party nastiness, so I get it. My empathy, however, doesn't condone that behavior.
Yeah, do in Haskell and let in Elm are "crutches" I use a lot. Despite practicing FP for years, my brain is still wired to think about hard problems imperatively (in sequential statements like you said). The let keyword helps immensely when I'm trying to reason about a problem in steps. I think the difference there, though, is:
Ok, now you said the
mutating
word, it's too early in the morning... I can't go on. :: hugs immutability coffee cup ::