4 ms·
"Which program is easier to read?" For me it was the second. Am I the only one ?
by guggle 5y ago
"Which program is easier to read?"
For me it was the second. Am I the only one ?
- conistonwater 5y agoThe first one reads like somebody just found out about functional programming and functors and tried to "improve" a straightforward bunch of if statements. I can read the second program without having read the plain English description, but I definitely would prefer to have the comment for the first one. I think even in languages like Haskell I would prefer (just sometimes) to read just a straight if-elseif-elseif-else. The whole thing about the way it's written with throwing/catching is a red herring anyway, you should just replace those with a different choice of if's. If you're feeling super adventurous, you can instead replace them with goto's, which is kinda funny; it would actually simplify the code, how often do you see that?
- jamincan 5y agoI think part of the problem is that Typescript doesn't have support for error-as-value baked into the language and pervasive in the ecosystem, so adopting that style isn't as ergonomic as it would be in a language that does. The equivalent in Rust would be far more clear and concise due to the ? operator and Result-types being ubiquitous.
- user-the-name 5y agoThe second by far, especially if you just remove the else statements and let program flow continue naturally. There are very good reasons to prefer Result over exceptions, but this example is not one.
- yakubin 5y agoTbh, to me the first one is easier to read. There's less jumping. But both are terrible. It should just be a bunch of if (...) { ... } else if (...) { ... } else { ...} etc. with no mutation of variables (what are all those v += 1 for?).
- Joker_vD 5y agoThose v += 1 implement the exact specification given above: 1. Parse an integer N from a string. 2. If N is NaN, fail with an error. Otherwise, increment N by 1. 3. If N is > 3, fail with an error. Otherwise, increment N by 1. 4. If steps 1-3 failed, set N to 3. 5. Increment N by 1. Those are quite strange requirements, and the resulting second code looks strange too, but... it faithfully and obviously correctly represents the given specification.
- Cthulhu_ 5y agoIt's the kinda assignment where you should look at a higher level - what does it do? What is N used for? What are the possible inputs? I mean if you start with a set of tests instead of pseudocode written down in text you could probably write something smarter.
- Jonathanks 5y agoThe example is strange and contrived. I couldn't torture the logic enough to demonstrate how readability breaks down with exceptions. Reading through the comments, I realise that even if the code is unreadable with exceptions, it can be rewritten to be readable. I updated the article to highlight not only readability, but also compositionality. I also tried to draw parallels with Promises (which are also monadic). I tried to target the article to intermediate programmers that may not already know most of the concerns raised in the comments, and I surely can't cover enough space on error handling without writing a book. Thank you for the comments. I've learned more from reading the comments.
- mschuetz 5y agoSecond one is way easier to read, even though it's verbose on purpose.
- alfonsodev 5y agoAgree and it could be easier to read in my opinion if you deal with the exceptions first. For example. let v = Number.parseInt("a3", 10); try { if (Number.isNaN(v)) { throw new Error("NaN"); } else if (v > 3) { throw new Error("gt 3"); } v += 1; } catch (error) { v = 3; } v += 1; Or writing a "guard function" that throws ... function throwIfNaNorGt3(v) { if (Number.isNaN(v)) { throw new Error("NaN"); } else if (v > 3) { throw new Error("gt 3"); } } let v = Number.parseInt("a3", 10); try { throwIfNaNorGt3(v); v += 1; } catch (error) { v = 3; } v += 1;