Hacker News new | past | comments | ask | show | jobs | submit login

This is going to open the flood gates. I am sure lot of people were just waiting for this moment for Rust adoption. I for one was definitely in this boat.

Also, this has all the goodness: open-source, high quality engineering, design in open, large contributors to a complex piece of software. Truly inspiring!




Maybe. I love Rust and use for all my work and hobby programming. With that said, I'm not in a super rush to use Async as it stands now.

This is a foundational implementation and while you _can_ use it, you are also likely to run into a host of partially implemented support problems. No fault of anyone, just a lot left to do. Examples being, you may run into needing async FS ops, so you bring in one of those libs. You may need async traits, so you bring in macro helper libs, you may need async DB interaction, so you check your db lib and hope they have support. Etcetcetc.

None of those are problems to stop you from using Async if you want. They're merely reasons you may not want to use Async quite yet.

Personally I've found Rust's development cycle to be such a joy, including manual threading, that I can get by happily without Async for the time being.

But, I'm not currently doing a lot of work where I'm dying to use greenthreads-like paradigms. Threading works fine in my web frameworks, db pooling, parallel libs like Rayon, etc. So because I've got all the power in Rust I need currently I just have no reason to use Async.

WITH THAT SAID.. use it if you want it! I just might not recommend it to people coming into Rust unless they explicitly need Async. It's bound to introduce a few - hopefully mild - headaches, currently.


It's probably worth noting that an async scheduler (executor in Rust terms) is required for this to be useful, hard to write yourself, and not provided by the standard library.

There are crates that provide ready-made ones, and that will work for almost all cases, but it's another dependency that you have to evaluate and stay on top of.

It is entirely possible to do yourself, though. Last month, I dove into the details during a game jam. Not much of a game came out, but I did manage to get a useful async system up and running from scratch:

https://github.com/e2-71828/ld45/blob/master/doc.pdf (cf. Chapter 3)


Indeed.

On a semi-related note, any thoughts on how you could merge Async with non-Async code? Eg, I've got a large codebase that is not threaded but not Async. In the future, I might upgrade the web server to be Async and slowly start porting code.

I had planned/hoped that I could make my own Async/Thread bridge. Such that non-Async code would live in it's own thread, and I would make a special Future ask a Mutex in another thread if data is available. Taking special care not to lock the Future's thread.

The goal of course is to not have to rewrite the entire app's blocking code at once.

Does this sound stupid to you?


You probably want channels.

There's an implementation in the standard library: https://doc.rust-lang.org/std/sync/mpsc/

Or a faster/more ergonomic one in the crossbeam-channel library: https://docs.rs/crossbeam-channel/0.4.0/crossbeam_channel/


I've used them a ton in Go, and a tiny bit in Rust. I would think channels could fail here though - for the same reason that a Mutex could fail, no? Channels can block a thread if you wait for data.

You could of course have a channel that you simply use in a non-blocking fashion, asking if data is ready. You could also implement similar behavior in a Mutex.

However, I do think you're right, a channel would likely fit this paradigm better; and with less chance of accidentally blocking the executor/future thread. Appreciate the feedback, thanks!


You should be able to come up with something. Fundamentally, the role of the executor is to be the bridge between sync and async code: it isn't async itself but is responsible for making all the async code move forward. No async code will do anything when the executor isn't active.

The way I split up the game code, raw event handling and rendering was written as a standard, synchronous, game loop. The game logic update was written with async code, and once per frame, I call the executor which keeps control until none of the async tasks can make further progress.

You can probably do something similar in your case: find somewhere in the existing program where it isn't disruptive to do arbitrary work, and have the executor do its work there.


That looks like a great document. It's nice to know that people occasionally still write literate programs, and do it well.


The library support's not quite there yet. But I'd bet on it being pretty good by the end of the year. A lot of popular libraries have async support on their master branches.


Agreed - just trying to temper expectations. I'd hate for new users to come in and be frustrated due to implied "completeness" of Async. While Async itself might be "complete", as a broad concept it really needs so much more to be end-user complete.

Traits are a big one for me. Though, I've seen good things with the Async Trait Macro libraries. So hopefully those do good.

It doesn't make this Async-Stable event any less big of course, not trying to downplay it. We can't really move forward without this, so I'm super happy to see it merged! I'm just hoping to manage expectations :)


It is a good idea to tempter expectations.

1) this is an MVP, some features like you mentioned are not yet implemented

2) the echosystem was preparing for this release but it will likely have a bit of churn until things settle down now that the feature is in stable

3) there was a lot of diagnostics work to make the feature minimally understandable when something is incorrect, but it will be a source of frustration because it's not as polished as other constructs that have had the benefit of several releases and us seeing how they were misused to have targeted errors. Some things are already tackled in the new beta, but I foresee a lot of work ahead of us.


Agree. I was starting with Rust a couple of times, but complicated async IO was exactly the reason I waited. Especially when knowing that async/await is coming there was zero reasons to learn the old way. But even when it hit nightly channel, it was impossible to use until major libraries expose the new API. So waiting now until Tokio and other mentioned libraries fully implement this. The next year is likely going to be the year of Rust, at least for me.


Are there that many people looking for a new low level language for server side software?


Rust isn't only great because it's low level. Things like sum types (called enums in rust), pattern matching and expression orientation mean that it is often much more expressive than other languages for high level code.


ML-inspired languages have all these features too; is the advantage of Rust over those just that it’s more mainstream, the ecosystem is bigger, etc.?


That, and that it has better support for imperative features than most ML languages. You can combine your fancy combinators with mutable variables and for-loops when just want to get something done quickly.

In general, Rust just has all the little details right. It's hard to describe that in concrete terms, but it makes using it a very smooth and satisfying process. I get a similar feeling when using postgres: there's usually a nice way of doing what I want, and I rarely come up against unwelcome surprises.


ML has always had easy mutables in the form of references, and the closest deployed language to Standard ML (Ocaml and Reason), has always had for-loops and while-loops. Mutable references are used frequently.

Rust is great because it's low level, high-performance, non-garbage collected and it's primary inspiration for higher-level programming is languages like ML and Haskell.


Having used OCaml and Reason i'd say the documentation and compiler messages of Rust are more helpful IMHO


Thanks! I actually do use Rust as my main professional language (since my company’s product is based on timely-dataflow and differential-dataflow, so it was the only natural choice).

But I’m always curious about how it stacks up against other languages I’m less familiar with that share similar ideas.


Right. You could use F#, and get the pretty big .NET ecosystem with it. I think some people are mainly attracted to Rust due it's novel and open-source attributes. There is certainly a hype factor involved in it. In my opinion Rust is great (I use it), but I think it's main strength are in different domains than web applications.


One of my favorite features of Rust as someone who dabbles is that thread safety is expressed in the type system. F# is perfectly happy to let me share mutable data across threads without any synchronization, while the Rust compiler knows whether something can be safely accessed because you've either transferred ownership, or the type is thread safe.

The ownership system is also a very clever approach to managing mutable state. Usually in F# you'd get something of the same effect by using immutable structures and creating new copies, which does have a small performance impact


IMO both language types offer shared state and immutable data structures so I don't see them as mutually exclusive. As the Rust guys I've heard say "sharing state and mutation are fine, just not together". It's a question of whether the problem your trying to solve is better as a highly mutable one with "sharing" (e.g I'm thinking system programming with contended system resources) or you want to share data across many threads simultaneously and are happy with slower single threaded performance for greater multi threaded throughput (writes are rare so sharing and locking on an atomic ref on occasion is OK so you want structural sharing of data). Rust helps the coder avoid the issues when coding in the traditional "sharing and mutation" paradigm especially without a GC; languages like F# have some modern things to do this like atomic refs for data sharing, flagging mutables, async lock types, support for imperative programming etc. Both approaches work and IMO suit different kinds of problems; good to have both available.


I call Rust a hybrid of Haskell and C++, it has most of the powerful type features you come to rely on with the MLs but the additional low level control and default imperative behavior of C/C++.

I came from Haskell to Rust and it really is a joy to program in.


Yes!

Rust is the first language that is both truly good as a low-level systems language and also truly good as a high-level modern labguage at the same time.

To me, it's amazing to finally have another option aside from just C/C++.

Technically, I might have had some other options before, but rust gets it right.


I would say Ada/SPARK gets a lot of things right, too. What it lacks is hype and thus, a vibrant ecosystem. It can be a huge deal-breaker to many people.


Ada does have a good ecosystem and community, just not what we'd call modern and mainstream.

I looked specifically at Ada, and for my use case macros are quite important. If I were to use Ada, I would need a separate code gen step.

I also need concurrency without making new threads. I know Ada can do async but it doesn't have something like tokio.

A shame. I wanted to give Ada a try, but didn't get very far before losing hope.


Have you taken a look at D? It might be what you're looking for. Although I wouldn't consider it mainstream.


I was planning to look more carefully at D if rust didn't work out.


I spend the majority of my time working with high level Rust while doing web development and writing networked services. It's really great to have the option to go low-level when I need to, though. The ecosystem doesn't have everything I wanted / needed so I occasionally go low, but it's infrequent as there are already a lot of great tools available that I make use of.


I think so. Off-course this is my belief and based on different opinions/experiences shared by people over last 3-4 years.


Rust is more high level than Java.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: