TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

From Rust to TypeScript

213 pointsby valandover 4 years ago

19 comments

aerovistaeover 4 years ago
The first code example he uses immediately threw me for a loop. Why is he adding the return value of a function call to a function itself? bar() + bar????<p>function bar(someNumber: number)<p>{<p><pre><code> return foo(someNumber) + 1; </code></pre> }<p>function baz(someNumber: number) {<p><pre><code> return bar(someNumber) + bar; </code></pre> }<p>baz();<p>Moreover, baz is called with its only argument being undefined-- so the exception throwing code won&#x27;t even throw, because it isn&#x27;t 0. And _moreover_, this is typescript, so this would have thrown a type error since a required numeric argument is omitted.<p>This has so many problems. This is not a promising start to this article&#x27;s correctness or thought-outtedness. Yet here it is at the top of hacker news...
评论 #24454455 未加载
评论 #24454524 未加载
评论 #24454540 未加载
评论 #24454425 未加载
评论 #24454877 未加载
XVincentXover 4 years ago
I love this. It reminds me a lot of the work I did in Prism to port what I learned using Haskell in TypeScript: <a href="https:&#x2F;&#x2F;dev.to&#x2F;vncz&#x2F;forewords-and-domain-model-1p13" rel="nofollow">https:&#x2F;&#x2F;dev.to&#x2F;vncz&#x2F;forewords-and-domain-model-1p13</a><p>Reading the article, I do have some suggestion:<p>1. Never use isLeft or isRight; they break the composability of the monad instance — use `fold` instead, as late as possible<p>2. Do not use Enum in TypeScript — they have a runtime representation in JavaScript that&#x27;s likely messing up a lot of things. Use string unions to accomplish the same result
评论 #24453231 未加载
评论 #24453333 未加载
评论 #24453685 未加载
评论 #24458254 未加载
flowerladover 4 years ago
This article is unconvincing.<p>From the article: <i>Compared to the first snippet, this one is harder to debug. It seems so because 1.) You don&#x27;t know that callMe will throw an error or not. 2.) If it throws an exception you will not know what is the type of the exception. The more modular your code is, the harder it is to debug exceptions.</i><p>This is only a problem with unchecked exceptions as seen in TypeScript and C#. Checked exceptions are the solution.<p>The problem with error code return is tediousness:<p><pre><code> int foo() { int result = bar(); if (result == ERROR_CODE) return result; int result2 = baz(); if (result2 == ERROR_CODE) return result2; int result3 = bazz(); if (result3 == ERROR_CODE) return result3; } </code></pre> Compare to the same code written in a language that supports checked exceptions:<p><pre><code> int foo() throws SomeException { int result = bar(); int result2 = baz(); int result3 = bazz(); } </code></pre> In the first version the logic is interspersed with error handling, which makes the logic hard to see.<p>How do people using Go and other languages that don&#x27;t have exceptions solve this reduced readability problem?
评论 #24453474 未加载
评论 #24453428 未加载
评论 #24453345 未加载
评论 #24453549 未加载
评论 #24456732 未加载
评论 #24453530 未加载
评论 #24453676 未加载
评论 #24453378 未加载
评论 #24453633 未加载
评论 #24454340 未加载
评论 #24453455 未加载
评论 #24453792 未加载
评论 #24454357 未加载
评论 #24453757 未加载
gregopetover 4 years ago
Sure, people say they want to have to check for _every_ possible error, but then Java gets endless heat for having checked exceptions.
评论 #24457965 未加载
taosxover 4 years ago
I resonated with the post as I&#x27;m in a similar position but I&#x27;m really sad that typescript chose just to be a thin layer on top of javascript.<p>The sentiment mostly comes from having the JS ecosystem mostly being untyped and having to interact with it.<p>That being said I tried io-ts but found it undocumented, missing examples and hard to write. For future libraries&#x2F;projects I&#x27;m looking to try again ReasonML, tried in the past but had to write too many bindings.
评论 #24454580 未加载
评论 #24455426 未加载
rmrfrmrfover 4 years ago
IMO the `Either` construct should be avoided in JS because inevitably you&#x27;ll either need to wrap everything in `try ... catch` anyway or you&#x27;ll be pulling your hair out trying to figure out how to get them to work in an async&#x2F;event context, in which case you&#x27;ll end up re-inventing the Promise api (perhaps wrapped in an extra thunk to make it more fp-friendly or whatever).<p>A more practical approach is to work along the grain of JS while getting inspiration from fp. A common snippet would be:<p><pre><code> function maybeUrl(str) { try { return new URL(str); } catch (err) { return null; } } </code></pre> This is much more straight-forward and interoperable. Dealing with something like Left&lt;InvalidUrlError&gt; where you&#x27;ve created an entire error subclass and wrapping function for an unrecoverable failure that will be discarded is way overkill.<p>The unreliablility of thrown values in JS is a valid concern, but instead of trying to wrap all my code in a container construct, I simply wrap&#x2F;convert the untrusted errors themselves if I need to use properties on an error reliably.
评论 #24455764 未加载
emmanueloga_over 4 years ago
Don&#x27;t write code like this... trying to fake sum types in an object oriented language ends up being a horrible, hard to maintain mess, similar to those examples on the original post.<p>Typescript&#x27;s &quot;discriminated unions&quot; [1] make for incredibly inelegant looking code for anything but the most basic sum types, the ergonomics are nothing like the experience of using Haskell or OCaml.<p>I love sum types but in an OOP the equivalent implementation is the visitor pattern (if the problem calls for it). I was once starry eyed about &quot;making invalid states irrepresentable&quot;. I even managed to introduce a code generator to bolt sum types into a production Dart app. My colleagues loved it (not) :-)<p>Thing is, programs have this annoying tendency of being incorrect no matter what technique you use :-), there&#x27;s no silver bullet! If a pattern is natural for a given language, it is better to use that pattern than to force it to be something it isn&#x27;t.<p>1: <a href="https:&#x2F;&#x2F;www.typescriptlang.org&#x2F;docs&#x2F;handbook&#x2F;unions-and-intersections.html#union-exhaustiveness-checking" rel="nofollow">https:&#x2F;&#x2F;www.typescriptlang.org&#x2F;docs&#x2F;handbook&#x2F;unions-and-inte...</a>
评论 #24455413 未加载
chrismorganover 4 years ago
The first example code is rather off-putting, because it has multiple errors. The code would <i>not</i> throw an exception, because it produces compiler errors so you’ll never run it. (OK, so it still generates JavaScript that you could run, but I’m assuming you’re using TypeScript properly and won’t do so.)<p>• `return number + 1;` should be `return someNumber + 1;`. If you ignore errors and run the JavaScript, this means that it’ll throw a ReferenceError on this line.<p>• `bar(someNumber) + bar;` is adding a number (well, it should be a number, but you’ve omitted the return types, so the previous error will mean it infers `any` instead of `number`) to a function. This is a type error.<p>• `baz()` is called with zero arguments instead of the one it requires.<p>&gt; <i>When baz is called it will throw an uncaught exception. By reading the code you know that foo throws an Error. Debugging this snippet is a piece of cake, right?</i><p>As mentioned, this code doesn’t compile, but if you ignore that and run it anyway, then the uncaught exception is a ReferenceError, <i>not</i> the error you see on a throw line. I… don’t <i>think</i> this is what was intended. This also demonstrates what I consider a bit of a weakness of the exception system in such languages: various programming errors that a compiler should catch come through as runtime errors instead.<p>(I’d generally prefer to use exceptions to indicate <i>exclusively</i> programmer errors, and basically never use a try&#x2F;catch block, but too much is designed around treating exceptions as normal parts of control flow to be able to do this in most cases. I like the Result&#x2F;panic split in Rust, where panic <i>always</i> means programmer error, and Result is for probably-exceptional cases, but where they’re still generally expected and part of the design rather than programmer error.)<p>If you fixed only the first error, you’d get a value like &quot;NaNfunction bar(someNumber) {\n return foo(someNumber) + 1;\n}&quot; out of the baz() call. Fun times.
评论 #24454759 未加载
评论 #24454743 未加载
rattrayover 4 years ago
Reminds me of a pattern I&#x27;ve wished would take off in TS, but hasn&#x27;t (yet):<p><pre><code> const result = await fetchData().catch(e =&gt; e) if (_.isError(result)) { return &quot;some failure&quot; } return (await result.json()).foo </code></pre> TS is smart enough to know whether result will be of type Error or the Response type.<p>This pattern should replace most Either cases when the left is an error state of some kind. Also should replace exceptions and promise rejections.<p>You can also analogously replace a Maybe type with nullability, simply `type MaybeFoo = Foo | null`.
评论 #24455927 未加载
评论 #24456410 未加载
judahover 4 years ago
Tangent: This article made me think deeper about programming languages in general and I found it fascinating. So I went to subscribe to his blog in my feed reader, but alas, no RSS feed. :-(
评论 #24458565 未加载
unnouinceputover 4 years ago
You can write bad code in any language, Rust included. This article is cherry-picking.
评论 #24453796 未加载
评论 #24458544 未加载
tym0over 4 years ago
You don&#x27;t actually need the tag on Either. This is how I defined my Result type. The shape is enough to discriminate them.<p><pre><code> type Result&lt;S, E&gt; = Success&lt;S&gt; | ResultError&lt;E&gt;; type Success&lt;S&gt; = { value: S }; type ResultError&lt;E&gt; = { error: E };</code></pre>
评论 #24454653 未加载
hn_throwaway_99over 4 years ago
I&#x27;m very unconvinced considering the section on avoiding exceptions doesn&#x27;t discuss async code at all. I mean, a returned Promise from an async function is very similar to the author&#x27;s &quot;Result&quot; object where you can even pass a success handler and a rejected handler right in the single &quot;then&quot; method. That said, I greatly prefer instead to await on an async function and handle any rejections in a catch block.
评论 #24455127 未加载
tantamanover 4 years ago
Please please please don&#x27;t perpetuate the use of either or maybe types :(<p>They make software very hard to maintain and end up breaking anyone who depends on a library that uses them.<p>Rich Hickey (author of Clojure) has a great discussion of Either and Maybe here: <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=YR5WdGrpoug" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=YR5WdGrpoug</a> that dives into their unsoundness.
评论 #24457859 未加载
评论 #24457757 未加载
aussieguy1234over 4 years ago
With JS and Typescript, I find myself going back to logic error handling in the catch block, because there is only one Error type. You can&#x27;t have multiple types of exceptions. So you have to set the error.type attribute and then do logic.
评论 #24456794 未加载
nsonhaover 4 years ago
Why do you need Either when you have union? All the left types subclass Error so you can easily separate that from the successful value as well. Seems rather a dogmatic choice.
ape4over 4 years ago
Does anyone else hate foo(), bar() and baz() as example names. They are meaningless - except communicating that its a programmer selected name. Even func1(), func2() would be better.
评论 #24454525 未加载
评论 #24454451 未加载
评论 #24454435 未加载
sdwvitover 4 years ago
Well exceptions are generally a sign that code smells. Instead of throwing an exception, just return the default value.
评论 #24454249 未加载
评论 #24454058 未加载
评论 #24455164 未加载
评论 #24454097 未加载
评论 #24454346 未加载
auggieroseover 4 years ago
Stopped reading after the exception &#x2F; result stuff. You can have both, both are useful, learn yourself some Swift maybe.
评论 #24453265 未加载
评论 #24453725 未加载
评论 #24453248 未加载