Live data from Hacker News

How Rust Is Tilde’s Competitive Advantage [pdf]

rust-lang.org

41–50 of 127 posts

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#41
post #2

So, I've been eyeing Rust for a while and have messed around with it a bit in my free time. Here are some things I'd want to know before trying it out on a large project: 1. What development environment are other developers using with very large code bases? Is the tooling responsive? 2. Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators f…

> Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators for async (assuming you want to stay on stable)? And is there a date yet when async/await will be stabilized? Can someone explain to me what async/await is, in the context of a language like Go? I've used Rust a fair amount, but Go has been my native language for ~5 years now. With that…

> Again, I use Rust and Go similarly in this post because Go is my frame of reference. I thought they were the same on this front, though. No?

No. Rust used to have a green threads runtime like Go (and Erlang/BEAM, Haskell, etc.) but that was removed before the 1.0 release. So today, a thread in Rust is a heavyweight OS thread, like in C/Java and most mainstream languages.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#42
post #37

Earlier quoted context omitted.

Yeah, you are missing some details. But this is a huge area, and it's hard to explain in a single HN comment. Basically, yes, the convenience of not needing to write async/await is useful, but in order to accomplish that, you need a bunch of other supporting decisions. These decisions make sense for Go, but do not make sense for Rust. The first thing to say on this topic is that virtually all of this (including async…

Technically you can get the convenience of not needing to write async/await, with the same runtime implementation decisions underneath as Tokio/futures. Kotlin is an example of this approach- its coroutines are state machines but with implicit awaits. This can even be extended to "awaiting across function calls" with effect polymorphism. I haven't seen this done in this context, but it would allow things like passing…

> I haven't seen this done in this context, but it would allow things like passing an async closure, or a generic type with an async trait implementation, to a normal function and having it automatically become an async function instead.

I've done that a fair bit in Scala using HKT. E.g. superclass is written in terms of a generic monadic type, one subclass implementation uses Future (actually EitherT with Future), another uses identity, a third uses Writer to track statistics...

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#43
post #2

So, I've been eyeing Rust for a while and have messed around with it a bit in my free time. Here are some things I'd want to know before trying it out on a large project: 1. What development environment are other developers using with very large code bases? Is the tooling responsive? 2. Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators f…

IntelliJ and a workspace based project will get you a modern IDE experience. However don't expect a responsive edit/compile cycle, compilation times just doesn't scale for large projects, even with incremental compilation. Linking against shared libraries for stable dependencies can help though.

No the ecosystem is not mature enough to get the "enterprise" libraries. Wrappers to c/c++ libraries are often needed.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#44
post #2

So, I've been eyeing Rust for a while and have messed around with it a bit in my free time. Here are some things I'd want to know before trying it out on a large project: 1. What development environment are other developers using with very large code bases? Is the tooling responsive? 2. Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators f…

> Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators for async (assuming you want to stay on stable)? And is there a date yet when async/await will be stabilized? Can someone explain to me what async/await is, in the context of a language like Go? I've used Rust a fair amount, but Go has been my native language for ~5 years now. With that…

async/await means you mark all your yield points explicitly; rather than having the runtime implicitly preempt you whenever it chooses, you mark the points at which task switching can happen, and at every other point it's impossible (equivalently it's as though any block of code that doesn't contain an "await" were a critical section). The syntax strikes a nice balance, making these markers as lightweight as possible but no lighter: you don't want the yield points to be completely invisible, but you don't want them to distract too much from reading through the straight-through happy-path control flow.

I find that having one implicit, pervasive, uncontrolled effect in a given piece of code is ok, but having multiple uncontrolled effects is very much not ok, because the ways those effects will interact can be very surprising. E.g. https://glyph.twistedmatrix.com/2014/02/unyielding.html gives an argument for using explicit async/await rather than go-style implicit (green) threads, in terms of how task switching will interact with state mutation. You can make similar arguments in terms of how task switching interacts with error handling or logging or database transactions or... - one uncontrolled effect is fine, multiple uncontrolled effects cause chaos when they interact. Unfortunately the kind of examples where one can see multiple effects in a single application tend to be quite big by their very nature (and if your app is small enough to only need to have one kind of effect, then using a language in which that particular effect is uncontrolled is probably fine, perhaps even a good idea).

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#45
post #29

> Rust is much easier to teach than C or C++, Not sure about that. If you know C, which is easy to learn, you already know a lot about C++, or at least the parts that are used most of the time. Learning about the borrow checker, match enums don't seem very easy at first, although they surely seem elegant and much safer.

C appears easy to learn. C++ a bit harder, but learnable.

What isn't easy to learn is all the horrible ways C is broken. Don't return addresses to local variables. Remember realloc can change the location pointer. Don't use the C string functions.

C++ adds fun gotchas like using the c_str() of a temporary string object. Carelessly passing local objects by reference to a lambda thread function. All of the amusingly horrible ways to screw up data structures using shared_ptr and enable_shared_from_this.

Better yet, linking C or C++ objects together that have been compiled with different "#defines" set so the structs, objects and vtables are different sizes.

C is not easy to learn.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#46
post #2

So, I've been eyeing Rust for a while and have messed around with it a bit in my free time. Here are some things I'd want to know before trying it out on a large project: 1. What development environment are other developers using with very large code bases? Is the tooling responsive? 2. Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators f…

I just switched from VS Code to InteliJ and it's great. There's been huge improvements in IDE support recently.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#47
post #29

> Rust is much easier to teach than C or C++, Not sure about that. If you know C, which is easy to learn, you already know a lot about C++, or at least the parts that are used most of the time. Learning about the borrow checker, match enums don't seem very easy at first, although they surely seem elegant and much safer.

That doesn't square with my experience. I've taught beginning programmers more or less the "C subset" of C++, and it was a nightmare.

The biggest problem is that when they inevitably hit undefined behavior, there is no easy way to learn what is wrong. The program hits a segfault or prints garbage on the screen—where to begin? I instinctively know what is likely to be wrong, but that's only through years of experience; it's almost impossible to teach that quickly. Even if, by luck, the program segfaults instead of silently corrupting memory, the line number where the failure occurred doesn't necessarily correspond to what is wrong—often the problem occurred earlier.

Rust is in a much better position here, since the compiler can actually isolate precisely what is wrong in those cases and emit diagnostics at the exact location where the problem occurred. That's much easier to teach.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#49
post #29

> Rust is much easier to teach than C or C++, Not sure about that. If you know C, which is easy to learn, you already know a lot about C++, or at least the parts that are used most of the time. Learning about the borrow checker, match enums don't seem very easy at first, although they surely seem elegant and much safer.

It really depends on where you're coming from. I had no difficulties learning Rust, but I already knew Swift pretty well.

Re: How Rust Is Tilde’s Competitive Advantage [pdf]

#50

Earlier quoted context omitted.

> Using a language for a large project without some kind of async/await notation seems painful. How bad is it using only combinators for async (assuming you want to stay on stable)? And is there a date yet when async/await will be stabilized? Can someone explain to me what async/await is, in the context of a language like Go? I've used Rust a fair amount, but Go has been my native language for ~5 years now. With that…

Async/await makes sense in python or JavaScript because it’s syntactical sugar that improves readability/maintainability and mitigates against concurrency errors stemming from the event loop (JS) or the GIL (python). I haven’t worked with Go beyond playing with it a bit, but it seems async/await would be utterly useless in Go since goroutines already accomplish the same thing in a much more performant manner.

C# was, as far as I'm aware, the first major language to implement async/await atop of Task (akin to Java's Future). The CLR uses native threads.

Go channels are also orthogonal to async/await. Message passing is not a substitute for futures/tasks, though it can be used to achieve similar goals. I would be extremely cautious about claiming that Go channels would be "more performant" than an otherwise-equivalent futures implementation, too.

Post reply on HN