52 ms·
Moving from TypeScript to Rust / WebAssembly
- melling 6y agoI don’t know Rust and haven’t done JavaScript for years but isn’t JavaScript a bit more of a higher level language, which would make a developer more productive? Rust being closer to the hardware should require more code, and effort, to accomplish the same task.
- yarg 6y agoJavaScript's a sloppier language.
- phailhaus 6y agoDepends on what you're optimizing for. If you want memory efficiency and near-native speeds, then you need WebAssembly. And Rust is a fantastic source language to compile to WebAssembly because of its memory safety.
- iMuzz 6y agoMind explaining a bit more here why Rust is a particularly good language to compile to wasm? Why does memory safety help here? Asking out of ignorance!
- sanxiyn 6y agoMostly because WebAssembly does not include GC yet, so being a non-GC language helps.
- esperent 6y agoFrom what I understand, this mainly means that a lot of work has been put into making this process possible, while for some other languages the workflow to wasm is lacking.
- jkelleyrtp 6y agoThere aren’t very many good wasm options that will produce web-friendly binary sizes. The options are really c/c++, rust, and some other less-supported languages like Zig and Nim. Rust has a good mix of high-level constructs (making it more productive than C) and has a good ecosystem around it. Cross compiling is never easy, and the rust wasm story is arguably the best and most supported via wasm-bindgen.
- gboss 6y agoWASM doesn’t have a garbage collector built in. Languages that use a garbage collector have to also convert their language runtime into WASM which can dramatically increase the WASM file sizes and is more work to process by the browser. Since rust doesn’t have a garbage collector this should make its WASM files smaller and more performant
- connicpu 6y agoThere isn't necessarily any inherent thing about the language itself that makes it better at WASM than others, it's more that it was one of the first languages that was ready for WASM. - It's low level like C and C++ so it maps cleanly onto WASM - In your average Rust project, all dependencies are already built from source, greatly increasing the likelihood all your dependencies can be built for WASM - Already using LLVM as the compiler backend made WASM targeting a lot less work than for languages that need to do that work from scratch - Probably most importantly, a lot of developers involved in core rustc development were motivated to get Rust working on WASM At least that's my perception for how Rust became such a prominent language for WASM development early on
- jillesvangurp 6y agoYou forgot the most important thing: it doesn't need a garbage collector. This is important because wasm garbage collection is a work in progress. The solution other languages targeting wasm typically use is bundling their own garbage collector in the compiled code, which of course adds a bit of code bloat. E.g. C# blazor wasm applications are not exactly small for this reason. There was a message yesterday in the Kotlin slack about them starting work on a wasm compiler backend for Kotlin (they already have java, native, and js compilers). https://github.com/JetBrains/kotlin/tree/master/compiler/ir/backend.wasm https://github.com/JetBrains/kotlin/tree/master/compiler/ir/... Interestingly they plan to depend on the wasm GC proposal instead of bundling their own: https://github.com/WebAssembly/gc/ https://github.com/WebAssembly/gc/ So, things are improving on this front. But it's a big reason why Rust is particularly popular for wasm right now because they have no GC and lots of developer tools that are relatively mature because they've been working on this for a while. IMHO, this will take another few years to fully mature but inevitably lots of people are going to be writing web applications that don't involve any or very little javascript. Kotlin is starting to look very solid for any kind of cross platform Android, IOS, and web based development (as well as server development, which is what I do). Swift would be another candidate and there already is a wasm compiler for that as well.
- rhlsthrm 6y agoInteresting, one of the big reasons I want to learn Rust is to "future proof" myself once JS loses its monopoly on the web. Maybe Kotlin will be a better one than Rust?
- fulafel 6y agoWasm is not memory safe inside the sandbox, so the language should enforce it if you care about correctness and/or dislike the C/C++ memory bugs and debugging.
- empath75 6y agoIt’s not that bad once you get used to it.
- satvikpendem 6y agoRust actually can be a higher language. It has true generics, static algebraic data types, functional programming features, and so on, even as it is closer to the metal. It is closer to Haskell or OCaml, but more pragmatic.
- sweeneyrod 6y agoIn what ways is Rust more pragmatic than OCaml?
- satvikpendem 6y agoA good package manager, multicore support, larger community, and so on.
- fluffything 6y agoDoes not really require you to drop to a lower-level language for performance, unless you really need to use assembly for something. OCaml is great for the application level stuff, and also performs quite well in general. But for building fundamental parts of the stack in which perf is important (like the multi-threading runtime, the garbage collector, etc.) you need to drop down to C++, C, or Rust. OCaml is definitely much nicer to use than C and C++. But I don't find it that much nicer to use than Rust TBH.
- wtetzner 6y ago> OCaml is definitely much nicer to use than C and C++. But I don't find it that much nicer to use than Rust TBH. I find OCaml quite a bit nicer to use than Rust, though in a lot of ways that's due to my preference for structuring code using modules and functors. However, due to Cargo and the fact that Rust has good Windows support, I end up reaching for Rust much more often than I do for OCaml.
- fluffything 6y agoModules is pretty much the only OCaml feature I miss in Rust. I can work around functors with some effort in Rust, and hopefully GATs will make this even simpler (although I don't expect GATs to give Rust functors).
- genuine_smiles 6y agoRust’s type system is sound, unlike TypeScript, and Rust provides a lot more performance by default. You can get good performance out of JavaScript, but it can be difficult, and the code can end up being difficult to maintain. If you’re trying to right very fast, very correct code in JavaScript/TypeScript then Rust may be more productive.
- echelon 6y ago> isn’t JavaScript a bit more of a higher level language Rust has zero-cost abstractions that feel like using Ruby and a rich type system that makes it incredibly expressive. Working in other languages feels like going back to assembly. I wouldn't want to design state machines in any other language. Rust's enums make it feel smooth as butter. They're a killer app. (The whole ecosystem is. Cargo. Package naming. Traits. So much good stuff.) Rust is my most productive language now, and I work in Python, Java, and Typescript codebases frequently. Edit: I'm being downvoted for expressing preference? What's with all the Rust hate? Learn it instead of being a hater. It's a wonderful tool, and it's silly to dismiss because you think people are being hipsters or something. There's a reason people love it.
- shpongled 6y agoI'm a big Rust fan too. I have experience in all of the languages you've mentioned, and I'm most productive in Rust as well. It's funny you mention enums, there was just another thread last week where I brought up how crazy it is that sum types (Rust enums) and pattern matching have been around since the 70s but have largely been limited to the FP languages. After extensively using Rust for ~3 years now, I don't ever want to use a language without sum types - you can write incredibly expressive and concise code with them. The other major productivity boost for me is the ability to compose and chain Iterators and mix those with collection types.
- hombre_fatal 6y agoPeople often demand generics in Go. But I think that actual sum types would be a bigger boon (if I got to choose). You can basically avoid interface{} in generic Go code with some copy and paste. But you can't really avoid it when you're trying to write code that would be cleaned up by an actual sum type. Not to commit the predicable sin of comparing Rust to Go any time either is brought up. I just mean to +1 the idea that sum types should actually be a fundamental tool that we can reach for in every language. So weird that it's taking so long to go mainstream, so to speak.
- eloff 6y agoI just implemented an iterator in rust yesterday. After having done it in c++ back in the day, I was blown away by how easy and powerful it is.
- bluejekyll 6y agoThis is complicated. I’m no expert with WASM, but I’m fairly familiar with Rust and have toyed around with Rust and WASM. With Rust and WASM you pay an expense of FFI between the languages. There are tools that minimize this, but there’s still a cost. Transferring data is limited to very primitive data types today, which adds a cost to translation between Rust and JS. I expect this to reduce in cost as WASM gains abilities to access the DOM and such, but it is overhead. This generally means that for many things Rust is not much faster than JS, but it is for very hot loops over CPU bound computations. As to productivity. This debate between languages will never end. JS like Python and other interpreted languages give the impression that tasks are being accomplished, but until all code paths are tested, knowing if it is correct is not obvious. Rust like many other typesafe languages (and it’s definitely on the further end of type safe) allow the compiler to detect errors in usage at compile time, well before testing and production usage. Some of us consider this to be more “productive” as it reduces the overall maintenance of the program after it’s released, but YMMV.
- jevgeni 6y agoBest comment in this thread. To the point and factual.
- azakai 6y agoThis is an important point. Languages compiled to wasm have an FFI cost, and we will never fully remove it because it just uses different types than Web APIs do. This isn't a Rust problem or a C problem, it's just how wasm is. Wasm also can't use the JS standard library, and usually ends up shipping some runtime support, like malloc or string handling, which increases download size. Both of those limitations are why wasm won't make sense for the great majority of web dev work. But wasm shines for "engine" type code, like in this post - pure computation, without lots of links to the outside JS/DOM world.
- lmm 6y agoML family languages are so much more productive that that probably outweighs the costs of manual memory management. Rust will always be less productive than Haskell or Scala, but a language with a decent type system is going to have a huge advantage over JavaScript.
- tigershark 6y ago...Haskell and scala are not part of the ML family. OCAML and F# are languages belonging to the ML family.
- lmm 6y agoBy what definition? Haskell and Scala both have the complete ML featureset (in particular they have sum types and full pattern matching; they're also part of the small group of languages that has typeclasses, which were originally invented for Standard ML) and are on record as being heavily influenced by ML languages (via Miranda in the case of Haskell).
- tigershark 6y agohttps://en.m.wikipedia.org/wiki/ML_(programming_language) https://en.m.wikipedia.org/wiki/ML_(programming_language) “Today there are several languages in the ML family; the three most prominent are Standard ML (SML), OCaml and F#. Ideas from ML have influenced numerous other languages, like Haskell, Cyclone, Nemerle, ATS,[citation needed] and Elm.[3]” If you know F#, OCAML, Haskell and scala you can see that the first two have an extremely similar syntax to ML while for the last two the syntax is very different.
- lmm 6y agoIf you actually click down to [3] in your own link it says '"these languages" is referring to Haskell, OCaml, SML, and F#'.
- Dowwie 6y agoAn experienced Rust programmer will write generally better solutions in roughly the same amount of time as what is taken to write a solution in NodeJS, where the work is familiar. There is absolutely more code to write for a language where you can have fine control over practically everything, as long as it's within the constraints governing the compiler. However, web development consists of well-treaded paths using familiar patterns of data access and manipulation. If a new project does not benefit by code re-use, the experienced Rust programmer is going to have to use more tools and techniques to accomplish something similar in functionality to that created in other languages, but with far more guarantees and control. Who cares about guarantees and control? The team that is going to have to share the burden of maintaining the code you write. With the patterns and libraries used in just this example, you can write a very high performance, memory efficient web server that can handle a large volume of concurrent requests that involve database interactions: https://github.com/actix/examples/tree/master/async_pg https://github.com/actix/examples/tree/master/async_pg All of the work has been consolidated down to a single file for illustration purposes, and it would usually be spread across files. Does it seem like a ridiculous amount of additional work, compared to other languages? I am misleading you some as there is actually a lot more to write the moment we move beyond plain vanilla workflows but this example proves what is possible.
- kp25 6y agoI would like to get started with Rust & Game Development. Any resources for that?
- deleted 6y ago[deleted]
- rlp 6y agohttps://arewegameyet.rs/ https://arewegameyet.rs/ Rust is not really there yet for game development, in my opinion. Amethyst is probably the most advanced 3D engine at the moment, but they are having some issues with picking an ECS implementation, and it's still very young. There are a few 2D engines, but they are also not particularly mature either. Coffee looks interesting, although I haven't tried it. For something lower-level, there's gfx.rs (Amethyst uses this), which is quite impressive. gfx-hal is quite nice for abstracting over DirectX/Vulkan/OpenGL/Metal/etc.
- deleted 6y ago[deleted]
- chain-- 6y agoI haven't used it but there are some unofficial Rust bindings to the Godot game engine: https://github.com/godot-rust/godot-rust https://github.com/godot-rust/godot-rust
- pjmlp 6y agoThere is a nice book that goes through teaching Rust, while doing a Tetris game with SDL. https://www.packtpub.com/eu/application-development/rust-programming-example https://www.packtpub.com/eu/application-development/rust-pro...
- drewm1980 6y agohttps://rust-gamedev.github.io/ https://rust-gamedev.github.io/
- rkwz 6y ago> Webassembly Is Faster Than Javascript Just curious, how's the OP measuring this? Also, would be very interested in the stack - is OP using Yew/Seed/etc or server rendered pages with Rust?
- nicolodavis 6y agoI'm just using an SPA written in Svelte on the frontend. I only use Rust for the game state updates. About measurements, I just whipped up a quick benchmark comparing the JavaScript state updates with the WASM version. You do pay a cost crossing the JS / WASM boundary, but the WASM version is faster overall for my application. I'm not particularly concerned with performance at the moment (it was just a nice to have).
- danielheath 6y agoPresumably the argument is 'webassembly optimizes better', which is true provided you aren't crossing runtime boundaries (between wasm/js or js/browser api) too frequently.
- johnghanks 6y agook
- anyfoo 6y agoAs long as you use a language with a good, static type system, I don't care so much what you use. TypeScript or Rust, for all I care you can transpile Haskell into JavaScript if you feel adventurous. But don't use a dynamically typed language as the source language for anything that is supposed to be more than a simple script.
- hombre_fatal 6y ago> But don't use This is just cargo-culting static typing: "If I avoid dynamic typing at all cost, the cargo crates will surely rain on down!" You'll find that picking a language is more of a business decision than the sort of technical static-vs-dynamic checkbox test you might use to pick the language of your next weekendware. This kind of absolutist rule of thumb is more flame bait than morsel of wisdom.
- lmm 6y agoThis is the fallacy of the grey. Yes, there are nuances and special circumstances, but the overwhelming majority of the time, static typing is simply better. That's one of a small handful of clear consensuses from the last 20-30 years of programming language evolution.
- hombre_fatal 6y agoIt's not any better if business trade-offs make another decision better. You don't have "all things equal" trade-offs in the real world. Want an easy concrete example? You and your cofounder have 10 years of Ruby experience and investors/customers who want a product yesterday. Or the deliverable that makes most sense is a PHP script that users can drag into CPanel because that's your customer base. The tinkerer inside you always wants to try new things and convince you that some greener tech on the other side of the fence are going to make the difference. It's usually just procrastination from the actual hard stuff: building things people want, today.
- lmm 6y ago
- chickenpotpie 6y agoA little disappointed not to see https://www.assemblyscript.org/ https://www.assemblyscript.org/ included in the discussion. Especially since it removes the "JavaScript is slower than WASM" argument.
- titzer 6y agoI'm not quite sure what you mean here, because AssemblyScript compiles to WASM, not JS.
- iCarrot 6y agoI guess the argument was that you can write in JS (well, something that is close to TypeScript which is close to JS anyway) and compile to WASM, therefore the speed argument becomes invalid.
- toastal 6y agoWhy would you be disappointed? The author wanted more from the type system and didn't care if they were going to switch syntax. Seems like AssemblyScripts biggest 'selling point' is that it looks like TypeScript.
- hardwaregeek 6y agoWhenever I write Rust, I have a lot of fun, but I'm still not sold on it for most web dev. The analogy that comes to mind is that Rust is a really nice sports car with a great engine. It handles like a dream and you can feel the powerful engine humming while driving it. With the right open road, it's a great time. You can really optimize code, make great abstractions and work with data easily. Unfortunately, web dev generally isn't a wide open road. It's a lot of little turns and alleys and special cases. Driving Rust in web dev is a lot of accelerating only to screech to a halt. I wrote a backend API for a side project in Rust. And true to what I said, Rust handled like a dream. But I didn't need the power. I spent most of my time screeching to a halt worrying about the plumbing between the various immature Rust libraries. And that's on the backend, which is way more mature compared to the frontend Rust libraries. Judging by this post, OP managed to find a great open road in web dev to use Rust. I only wish I could find one as worthwhile.
- rkwz 6y agoLove the analogy! I think there's value in mixing Rust with languages with mature libraries like JS/Python/etc to optimize performance critical code paths - basically for things we've been using C/C++ so far. There's also a lot of progress in Rust community, I believe it'll get mature libraries very soon in future.
- nicolodavis 6y agoYep, I don't think Rust is quite there yet for web dev. I didn't use Rust for any frontend interactions. The web app is an SPA written in Svelte. I only used it for the core state update logic, which benefits from the typing and performance boost.
- hardwaregeek 6y agoYep! You found a really great open road to drive Rust. I'm jealous :D. If I had an app with as interesting requirements, I'd certainly consider your approach
- laurencerowe 6y agoFor backend web development I was somewhat disappointed to see that many of the new web frameworks (all async) allocate extensively on the heap (for example lots of Strings in their http request types.) I mean it works but I don't understand why I would go to the bother of thinking about lifetimes when it seems performance would be similar to Kotlin / Swift / F#.
- lacker 6y ago[TypeScript] does not actually ensure that the data you are manipulating corresponds to the type that you have declared to represent it. For example, the data might contain additional fields or even incorrect values for declared types. This is only a problem if you are mixing untyped code with typed code, isn't it? Like when you are parsing JSON, you need to do typechecking right then, rather than just using an "any" type. The only other situation I have run into this in practice with TypeScript is when I'm using a library that has slightly misdefined types.
- lmm 6y ago> The only other situation I have run into this in practice with TypeScript is when I'm using a library that has slightly misdefined types. Unfortunately there's no way to know which libraries have defined their types correctly, so you end up having to check the types you get back from every library you use.
- nicolodavis 6y agoThat's correct. You have to insert validation code at all the entry points, which was the case for me. Moving to Rust doesn't eliminate validation altogether, but you don't have to do any type related validation which is nice.
- mcny 6y agoNot sure if this is a place to ask this but if someone does not have experience working with Javascript, they might have trouble reasoning about this code: https://codesandbox.io/s/is849 https://codesandbox.io/s/is849 edit: complete code ```typescript class Person { id: number; name: string; yearOfBirth: number; constructor(id: number, name: string, yearOfBirth: number) { this.id = id; this.name = name; if (yearOfBirth < 1900 || yearOfBirth > 2020) { throw new Error("I don't understand you. Go back to your time machine."); } else { this.yearOfBirth = yearOfBirth; } } getAge(): number { const currentDate: number = new Date().getUTCFullYear(); return currentDate - this.yearOfBirth; } } class Dog { id: number; name: string; yearOfBirth: number; constructor(id: number, name: string, yearOfBirth: number) { this.id = id; this.name = name; if (yearOfBirth < 1947 || yearOfBirth > 2020) { throw new Error("I don't understand you. Go back to your time machine."); } else { this.yearOfBirth = yearOfBirth; } } getAge(): number { const currentDate: number = new Date().getUTCFullYear(); return (currentDate - this.yearOfBirth) * 7; } } const buzz: Person = new Person(1, `Buzz`, 1987); const airbud: Dog = buzz; console.log(`Buzz is ${buzz.getAge()} years old.`); console.log(`Airbud is ${airbud.getAge()} years old in human years.`); ```
- harikb 6y agoAlon Zakai[1] gave a good talk[2] on the current state of WebAssembly, particularly on the current state of performance 1. https://twitter.com/kripken https://twitter.com/kripken 2. https://youtu.be/4ZMY3QE5t9o https://youtu.be/4ZMY3QE5t9o
- apatheticonion 6y agoI'm not certain exactly how LLVM works so I am not sure this is the right question to ask but - How does Web Assembly relate/compare to LLVM? Does LLVM solve the problem of a single binary that can be run portably?
- harikb 6y agoThere are not comparable afaik. WASM is also more ambitious, along with WASI (system interface) creating a portable final executable (compare to JVM), whereas LLVM is only a set of intermediate language and tools. When this transition period goes away, LLVM should hopefully compile to WASM binary as a target. The current path described in the video of WASM -> C -> clang -> llvm -> native-binary is a temporary workaround afaik.
- jfkebwjsbx 6y agoWASM isn't "more ambitious". It is a spec for portable bytecode, nothing more, nothing less. LLVM is one of the best toolchains for many languages. They are completely different things.
- harikb 6y agoYes, I agree. Wording wasn't right. What I meant was that it is trying to define a universal target with runtime system interface and such. The only reason I drew a comparison was that both are trying to bring standardization, but in different contexts.
- zenhack 6y agoThey're trying to solve different problems. LLVM is trying to take care of most of the language-independent bits of writing a compiler, while wasm is a format for delivering code to browsers, with an eye towards being a good target for languages like C and making use of the existing JIT compilers in modern browsers. LLVM as a toolchain provides backends for many target machines, so as a compiler author you can just emit LLVM IR and (mostly)automatically be able to compile for x86, arm, mips, etc... And they have a wasm backend too, so the technologies are complementary -- you can use LLVM to compile to wasm. LLVM will do a fair bit of optimization too. The intent with LLVM is not to provide a portable binary distribution format, but to allow different compiler frontends to all share the same compiler backend logic. By contrast, with WASM the assumption is that by the time it gets to the browser the ahead-of-time compiler has already done a fair bit of optimization, so what a wasm compiler has to do is much simpler. WASM is also designed for space efficiency, since the code will be shipped over the network, and safety -- LLVM has a C-like notion of undefined behavior (which the optimizer makes use of), but this would be wildly inappropriate for WASM due to security (and portability) concerns.
- blacksoil 6y ago> However, it [Typescript] does not actually ensure that the data you are manipulating corresponds to the type that you have declared to represent it. For example, the data might contain additional fields or even incorrect values for declared types. This made me curious, as it sounds like something that can be added as a transpiler option under tsconfig.json. But it turns out Typescript doesn't already have a support for "nominal" type, but there are some tricks one can leverage to achieve similar thing: https://medium.com/better-programming/nominal-typescript-eee36e9432d2 https://medium.com/better-programming/nominal-typescript-eee...
- chjj 6y ago> webassembly is faster than javascript Everyone says this, but I would dispute it as misleading in a lot of cases. I've been experimenting a lot with wasm lately. Yes, it is faster than javascript, but not by all that much. It's the speed of generic 32 bit C. It leaves a lot to be desired in the way of performance. My crypto library, when compiled to web assembly, is maybe 2-3x the speed of the equivalent javascript code. Keep in mind this library is doing integer arithmetic, and fast integer arithmetic does not explicitly exist in javascript -- JS is at a _huge_ disadvantage here and is still producing comparable numbers to WASM. This same library is maybe 15 or 16 times faster than JS when compiled natively, as it is able to utilize 128 bit arithmetic, SIMD, inline asm, and so on. Maybe once WASM implementations are optimized more the situation will be different, but I am completely unimpressed with the speed of WASM at the moment.
- ben-schaaf 6y agoHave you tried with firefox? Last I heard they've got far and away the fastest wasm implementation.
- chjj 6y agoNo. I've just been building with the WASI SDK and running the resulting binary with a small node.js wrapper script. So, I've only tested v8's WASM implementation so far. Does firefox have a headless mode, a standalone implementation, or some CLI tool I can use to run a WASM binary? Running stuff in the browser is cumbersome.
- kevingadd 6y agoYou can use jsvu to grab command-line shell binaries for spidermonkey (firefox's JS engine), v8, and jsc (safari's JS engine) to toy around with.
- zelphirkalt 6y agoI think there should be a headless mode. For exampl e you can run unit tests using the gecko driver (?) without firefox showing up, running it as some process to perform the testing steps and give results.
- historyremade 6y agoHidden marketing for Rust by Mozilla assholes. Rust has no future. It will die. Stop shilling too much. STL Is great. C++ is the king.
- eddhead 6y agoThe gist of this article applies to switching from JS/TS to Uno/Blazor as well as they both support WebAssembly just as well, and they both get robust UI frameworks as a bonus.
- pjmlp 6y agoI guess AssemblyScript would have been a better option, given it being a language subset for WebAssembly.
- wtetzner 6y agoExcept that doesn't address any of the other reasons they preferred Rust...
- asdf-asdf-asdf 6y agoi'm glad it worked for the author, and i am sure you can achieve better performance with Rust than with NodeJS, but i'd like to discuss some of the mentioned advantages: in general, typescript is optimized for cooperating with other javascript code, to make it easy to drop it into a javascript-based project, and also, it does not really have it's own "runtime". typescript is javascript plus types. in fact, if you want to convert from typescript to javascript, you can take a typescript-file, and just delete all the type-definitions and you get a working javascript file (there are some exceptions to this, but it generally is true). this approach has it's downsides of course, for example,when you need to interface with a javascript (not typescript) module, you can easily, but you have to know what types it expects and returns,otherwise you might get invalid structures in your code. there are things that can help you there (https://github.com/DefinitelyTyped/DefinitelyTyped https://github.com/DefinitelyTyped/DefinitelyTyped), and it works quite well in practice, but there is no 100% guarantee that the types will be correct. >> STRICT TYPING (in typescript) For example, the data might contain additional fields or even incorrect values for declared types. - typescript is structurally typed most of time, so if you have a function that needs an `{a:string, b:string}`, and you send it an `{a:string, b:string, c:string}`, it will accept it. it's a different trade off,sometimes better, sometimes worse, compared to nominal-typing (https://en.wikipedia.org/wiki/Nominal_type_system https://en.wikipedia.org/wiki/Nominal_type_system). - the part "even incorrect values", it should not happen in your own code. as i wrote above, i can imagine it happening when interfacing with other non-typescript code. >> DATA VALIDATION: You have to write data validation code to ensure that you’re operating on correct data in TypeScript. You get this for free in Rust... in typescript if you want to read,let's say JSON data,and map it to a typescript-structure, and return an error if it does not have the correct structure, you can use libraries like IO-TS (https://github.com/gcanti/io-ts/blob/master/index.md https://github.com/gcanti/io-ts/blob/master/index.md) to make that happen. i do not know how you get this "for free" in Rust, i know there are libraries like Serde (https://serde.rs/ https://serde.rs/) that do it.
- amitport 6y agoHi Nicolo, Here are my two (or more) cents: 1 - Javascript is fast enough for your use case. No one will notice the difference in a board game website. 2 - AI should probably be implemented in python anyway. As ugly as python can be, you shouldn't fight the world; there are too many free advanced AI algo implementations in python out there. 3 - Regarding "Limitations of TypeScript" (strict typing / data validation / error handling): first of all arguable claims, but moreover, even if you think rust is better in these concerns, they are not important enough to justify reimplementation, disregarding away typescript's advantages and taking the risk involved in a new language and toolset. Yes, I can see the appeal as a programmer to learn new stuff, but seriously you should have much better reasons to rewrite existing code. BTW, also, if I would think of a rewrite, I would have gone with scala or python, both are slower on the web, but seriously, it will not amount to anything meaningful in your use-case. Scala has better typing, and contextual abstraction is a killer feature for DSLs like game mechanics specification. Python is the lingua franca of AI, and pypy has greenlets [1]! Which is much cooler than people seem to realize. Specifically, it should allow writing immutable redux-like command pattern operations, as regular code, without the weird switches everywhere. BTW2, I've contributed to boardgame.io, please consider staying with open source. We can build something like boardgame-lab together. [1] https://greenlet.readthedocs.io/en/latest/ https://greenlet.readthedocs.io/en/latest/
- nicolodavis 6y agoHey Amit, good to hear from you! > Javascript is fast enough for your use case. No one will notice the difference in a board game website. No, actually. Have you seen how long boardgame.io's MCTS bot takes to make a Tic-Tac-Toe move? Not the end of the world, but certainly in need of improvement.
- amitport 6y agoYes, but AI search algorithms like MCTS are slow in general. Even with C, it will be very slow when you want the AI to be smart and consider many actions. IMO, you should train using python libs like [1] and move it to the browser with something like [2] OR run AI in the server. YES definitely writing an AI lib for the browser is a great goal, and as a programmer, it is super interesting. Still, it is tough, and time-to-market is much more crucial, as the entire codebase will change once it will interact with actual people. [1] https://github.com/datamllab/rlcard https://github.com/datamllab/rlcard [2] https://onnx.ai/ https://onnx.ai/
- v_pragma 6y agoKeep in mind that WebAssembly is not a silver bullet for performance, and carefully crafted JS application (written in engine-friendly way) will perform roughly the same or even better than its WA equivalent. I've rewritten chunk of my math-intensive app in AssemblyScript half a year ago - it took me about a month to fight through all the compiler bugs, I used every optimization possible (used floats everywhere, disabled array boundary checks, disabled GC for 70% of classes) and still end up with a binary that is 30% slower than the original JS code. It was mostly AssemblyScript's GC, which was extremely slow (and probably still is), and with GC completely disabled (which is an unfair advantage for WA) performance was almost the same.
- maxgraey 6y agoThat's pretty interesting. Could you share you project? There are benchmark which compare JavaScript and AssemblyScript: https://github.com/nischayv/as-benchmarks https://github.com/nischayv/as-benchmarks https://github.com/nischayv/as-benchmarks/issues/3#issuecomment-623159721 https://github.com/nischayv/as-benchmarks/issues/3#issuecomm...
- v_pragma 6y agoUnfortunately, no, it's a commercial closed-source project. I profiled both JS and WA versions, the hottest methods took basically the same amount of time in both versions, except that WA build additionally spend ~25% of all time in __retain or something like that.
- maxgraey 6y agoDo you intensive use small objects like Vec3, Quaternion and etc? AS hasn't scalar replacement optimization pass yet which JavaScript definitely has. Also it will be much better after implementing tuple / records which depends on multi-value proposal for now. All this significantly reduce ARC / memory pressure. But my assumption it could be also wrong measurement. Most of people uses benchmark.js which also measure js <-> wasm interop overhead which usually main bottleneck.
- truth_seeker 6y agoIn general, I think the significant improvement in Speed in case of WebAssembly binaries will be largely due to SIMD support. But performance gap between JS and WebAssembly is not at all deciding factor unless you are creating a high quality Games. There are lot of online games with low to medium graphics quality created using 2D canvas or 2D/3D WebGL libraries which run just fine on modern web browsers. Most developers, at least in my experience see just plain Array and JSON. If they get themselves familiar with API like WeakRef (WeakSet/WeakMap), ArrayBuffer along with DataView and Various Typed Arrays (Int8, Int16, Int32, Uint8,Uint16,Uint32, Uint8Clamped and likewise for Float and BigInt) they can write Garbage heap friendly and more computation focused code. Besides that, strictly speaking for standard web application development, JS ecosystem of libraries and frameworks are miles ahead for handling various kinds of UX/UI journey scenarios. Developer tools in the browser to do various kinds of performance inspection and profiling of the JS code. I wonder why JS engines (like V8 for example) rely highly on Scalar instructions ? There is lot of scope to apply auto-vectorization and generate SSE, AVX, NEON (for ARM) instructions. If they implement this or at least provide some API like SIMD.js (one they abandoned in the past), it will make WebAssembly close to redundant unless you hate JS or other PLs which transpiles to JS.
- loxs 6y agoI will only nitpick on the part about TypeScript not being type-safe enough, where extra fields are possible or wrong types can be sent over the wire. io-ts [0] completely solves this issue, to the point where I don't think it's less type-safe than Rust in any practical manner. I've been writing apps in TS this way for the past year and I have quite a large codebase in production. The errors you mention do not happen. [0] - https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts
- nicolodavis 6y agoThanks for the link! I'll look into this for my other TypeScript codebases.
- beaker52 6y agoI love things like this, but at the same time when I look at the API this library provides, it's not junior-friendly. Even though I acknowledge it solves some problems I'd like to solve, if I put code using this library infront of a junior developer, they'd be paralaysed, and at best, if they weren't, write code with it that another junior wouldn't understand. That makes it difficult for me to justify introducing it.
- loxs 6y agoI agree in principle, though in this particular case io-ts does not tend to produce incomprehensible code. Maybe if juniors use it, it would, but it's easy to encapsulate the IO codecs in their own modules where the functional style of io-ts/fp-ts does not leak out to other parts of the code and only types can get reused.
- samhh 6y agoThat's not an unreasonable concern but it does mean you're writing code targeting the lowest common denominator. That's not a decision free from negative consequences.
- qaq 6y agoI like Rust but I would much rather use Swift for something like that especially if SwiftUI like thing was part of the deal.
- nicolodavis 6y agoNote that Rust is only used for the state updates. All the UI stuff is TypeScript (using Svelte).
- niuwenyan 6y agotest
- mastrsushi 6y agoMigrating a web app to a static typed system programming language is asinine. I swear these fanatics will do anything to say they rewrote it in Rust. This site is full of language-specific indulgent blog posts that are no more sophisticated than arguing over Pokemon cards. I want to see more posts about exciting new concepts like WebAssembly. So sick of hearing that the world would be a better place if the sky and trees were written in Rust instead of C++. Incoming Rust wankers to downvote my post to oblivion.
- collyw 6y agoHave an upvote from me, your attitude put a smile on my face, which is unusual for a comment on HN.
- jevgeni 6y agoIf we're are talking about Rust criticism it's pretty average in terms of tone and substance.
- mastrsushi 6y agoSpotted the rust wanker
- jevgeni 6y ago> Migrating a web app to a static typed system programming language is asinine. Why?
- deleted 6y ago[deleted]
- mastrsushi 6y agoBecause it's redundant to have low level functionalities for building a web app.
- 6y ago
- deleted 6y ago[deleted]
- franklampard 6y ago> For example, the data might contain additional fields or even incorrect values for declared types. Can you give an example?
- Longwelwind 6y agoI spent the last 2 years making an online adaptation of a board game. I chose Typescript mainly because I was comfortable enough in this language and I don't regret this choice. Typescript is, for me, the right balance between the strictness required to manage a mid-size codebase, and the looseness necessary to be productive (I definitely don't want to manage low-level things like memory when coding the gameplay of the board game). On top of that, if your project is open-source, using JS/TS makes it more likely that someone can contribute to the project, compared to Rust, which has a higher learning curve. Being able to easily share code between the client and the server is a big bonus too. The article points that with WebAssembly, it's possible to do it with any language, but I'm not sure it's stable enough to be used yet. I'm thinking of making a library similar to boardgame.io (because I think there are some parts that could be done better), and I'll most probably keep Typescript for it. Curious to see how using Rust for this will play out!
- wdb 6y agoI am actually converting a work project from TypeScript to Swift as it makes the writing of code more fun and then just leverage either for the backend application or as part of web application via WebAssembly. Main reason it's easy to share the code with different targets (win32, arm, WebAssembly, osx) so its highly reusable. And I like Swift more as a language compared to Rust Really enjoying it so far.
- nailer 6y ago> For example, the data might contain additional fields or even incorrect values for declared types. I understand 'incorrect values' (this is true, see https://github.com/Microsoft/TypeScript/issues/15480 https://github.com/Microsoft/TypeScript/issues/15480) . But TypeScript definitely doesn't like adding additional fields. Right now I'm working on TypeScript, added the new Fastify raw body plugin, and forgot to extend our custom Request type. The error is: Property 'rawBody' does not exist on type 'CustomRequest<DefaultQuery, DefaultParams, DefaultHeaders, any>'.ts(2339) Ie, we can't just add a field. Appreciate I may be wrong, or we have different definitions here, but I'd like to discuss.
- nicolodavis 6y agoSomething like this is valid TypeScript I think? interface MyType { a: number; } function process(value: MyType) { console.log(value); } const value = { a: 1, b: 2 }; process(value);
- Joshi323 6y agoNo substantial arguments in the article. Hackernews used to be one of the rare places where quality is valued. How can such a low content and low quality article get so high on the HN frontpage?
- AzzieElbab 6y agoThat is quite a move. Like moving from USSR to USA.
- k__ 6y agoGood idea. TypeScript is too Java/C# for my taste. Rust feels more OCaml-ish. It has more predictable performance than JavaScript and often it can be better. If Rust gets a bit more ergonomic (via language or crates) it could be a good alternative and finally save us from the horrors of Electron/Slack/Bitbucket/etc.
- danbruder 6y agoRust's type safety and error handling are helpful tools to have in your belt when gluing together the pieces needed for a web api. I have been working on a new product at my day job that has needed to change a lot as we learn and grow and I am happy with how Rust has been reliable in the face of that change.
- deleted 6y ago[deleted]
- Accacin 6y agoCompletely off topic, but I'm a front end developer who dabbles with a range of languages and also enjoys trying out new languages, but I've never really used a 'back-end' language and I've been trying to find one that works for me. What do people recommend nowadays? (Only asking as I've seen people talking about Rails/PHP/Node, etc.).
- Asooka 6y agoOne thing articles like this always miss, and what I'm most keen on, is how exactly the bridging works. Is there a standard Rust wasm crate that exposes the DOM? Do you pass some struct with function pointers? Is the Rust code exposed as a black box with no connection to the outside world and you just call a few entrypoint functions? Can you call Rust from JS and JS from Rust? If you go JS->Rust->JS->Rust->JS and the innermost JS function throws an exception, is all that properly propagated up the stack?
- nicolodavis 6y agoThe Rollup plugin linked to in the article produces JS functions that call into WASM code. JS objects are automatically converted to Rust structs via Serde and vice-versa. I use TypeScript / Svelte for DOM interactions and only call into Rust code for the state updates (treating it like a black box).
- steveklabnik 6y agoThere are two low-level bridges: js-sys provides bindings to all the ECMAScript stuff, and web-sys provides bindings to all of the rest of a browser environment, including the DOM. > Can you call Rust from JS and JS from Rust? Yes. I personally have written some JS code that returns a promise, wrapped in wasm that turned it into a Rust Future, then converted that Future into a promise that I've returned to Javascript. > If you go JS->Rust->JS->Rust->JS and the innermost JS function throws an exception, is all that properly propagated up the stack? Sort of. Rust doesn't use exceptions, but the binding converts a JavaScript exception to a Rust "result" type and vice versa at the boundary, so if you propogate it, it will get properly propagated.
- maerF0x0 6y ago@nicolodavis I would love to hear your thoughts and reasoning for not using go + wasm compile target? Not as a critique but to understand your point of view.
- nicolodavis 6y agoNo reason except that I've written Go in the past and wanted to learn a new language :) Comparing the two languages, I would say that Rust's enums and pattern matching make it easier to work with for my specific use case.
- ralmidani 6y agoAs someone who has (mostly) enjoyed working with Python and JS (CoffeeScript in the past, and ES6+ and TypeScript more recently), and also dabbled in Ruby/Rails, I've been intrigued by Rust for a while. Its promise of being close in speed to C/C++, but safer and more ergonomic, sounds great. I have not attempted to build anything with it yet, but I've looked at what (I think) is enough examples to be familiar with its constructs, and have seen some benchmarks. For systems software or libraries that are meant to be hooked into from, say, a JS/TypeScript environment (see https://deno.land https://deno.land, a promising alternative to Node), it seems like Rust has a lot of potential. But for building applications (which is what I'm focused on currently) it seems Rust has a "No OOP for you!" attitude that gets in the way of modeling your application domain quickly. Yes, you can use impl and trait as an alternative to classes. But it seems like you have to jump through a lot of hoops; define your structs, define a trait for default behavior and remember that &self is provided as an implicit first argument to the methods (this is similarly cumbersome in Python), then define an impl for each corresponding struct (don't forget about &self!). As opposed to just declaring a base class and overriding when you need to in the subclasses. I am definitely not saying classes are the only way to do OOP, but at least give developers the option of using them. I have found Swift attractive for application development because it gives you structs for one-off (value-based) data types, classes when you need an easy way to do inheritance and polymorphism (and/or need reference-based data types), and extensions as a more abstract way to enhance structs and/or classes (and/or enums). It doesn't force you to use classes (and the community appears to think protocols are a better construct), but the language remains approachable, and you can always start with classes then refactor to protocols when the need arises.
- deltron3030 6y agoIs Vapor the rails-like go to web framework for Swift? Is it viable for indie hackers, or is it more like Java geared towards the enterprise? I find Swift interesting as a language because it seems that it's well balanced, usable for low level systems programming and higher level applications. But protocol first kinda indicates big design up front, something more geared towards enterprise usecases..
- 6y ago
- _bxg1 6y agoDoes anyone know the progress on exposing browser APIs (and hopefully real JS objects) to WASM directly? I think its use-cases will remain pretty narrow until then, but I haven't heard much noise about those developments lately.
- RyanGoosling 6y agoIf you push Rust to client-side WASM, can it still perform DOM manipulations?
- steveklabnik 6y agoYes. It has to call out to JS to do so. It's implemented in a way that's forwards-compatible so once wasm can do so natively, your code will just magically get faster.
- nicolodavis 6y agoThat's right. For my use-case I decided to just stick with JS for UI stuff (using Svelte). I call into Rust code like a black box to update some state.
- ronanyeah 6y agoI replaced Node.js with Rust ages ago. It was a brutal learning curve but having the compiler cover everything I do is a massive advantage that never stops paying dividends.
- magicmouse 6y agoRust is extremely poor for web apps and graphical interactive software in general. Having been using Beads (a competitor to typescript) for the last few months, i couldn't possibly build my food ordering app quickly in Rust. There are hundreds of art assets to manage, and every screen has to automatically re-flow depending on the resolution of the device. Without a concept of DPI and the ability to measure text, and have a layout system, all of which is built into the Beads language, it would require a very tedious programming effort. Most of the time coding a graphical interactive product is making it look nice on all the different sized screens; Rust does nothing for this very time consuming task. Typescript may force you to use the awful CSS, but having some layout system is better than none. And we could also talk about event management, and sync between client and server, none of which Rust is particularly good at.