1. 42
  1. 10

    My kingdom for a garbage-collected, green-threaded rust.

    It feels impossible to write quality, correct software without sum types (especially Maybe and Result).

    1. 4

      Would Kotlin be close to what you want? It doesn’t have sum types natively, but people seem to implement them easily using sealed classes.

      1. 3

        I like a lot of Kotlin! Sealed classes do the job for me, and they’re the only language to have done async correctly, IMO.

        But it’s still full of exception pitfalls, and their Result doesn’t really protect you from how hard it is to reason about it all.

        That, and the toolchain is astronomically hard to use.

        1. 3

          I find kotlins attempt at null-safety in my android programming to be useless 90% of the time. Or you have to at least double-check all the time, because something somewhere could’ve changed it between your if-null and the actual usage. And sprinkling ?.run{} ?: everywhere is really annoying. Oh and then there are these problem with deserializing and getting null-values or 0s as default for missing ints. So you have to define everything as ?.

          1. 1

            With the caveat that I’ve never touched Android, just server-side Kotlin, in my experience some of the things you’re talking about are a symptom of using mutable data structures. I’ve found Kotlin pretty good at remembering when I’ve already done a null check on a val property.

            But maybe the data structures in question aren’t ones you control, in which case yeah, it’s a pain.

            1. 1

              Yeah I don’t actually have a choice to define them immutable. For the deserialization that could be something to apply, but then I’d have to duplicate my data classes (I use them also for the stuff I send back, to store everything in one object which the UI then changes but uses as source of truth).

      2. 3

        In addition to other suggestions, what about Ocaml which Rust has a lot of DNA from?

        1. 2

          I’m waiting until multicore lands to check it out. I’ve heard very few reviews of its toolchain, is it as nice to use as cargo?

          1. 3

            These days it’s quite nice but there’s been lots of churn in the past. It’s true that Multicore is what’s probably keeping a lot of people hanging off of Ocaml for now.

        2. 2

          Nim ?

          1. 2

            Swift has Result and Maybe (Optional) without the borrow checker. It also has structured concurrency.

            1. 3

              My impression is that Swift is still highly bound to the Apple ecosystem, despite being open source. Is there a vibrant ecosystem for things like backend development?

              1. 2

                I think it’s about as vibrant as Kotlin’s or Rust’s. The Swift server-side workgroup does a lot of work. https://github.com/swift-server/guides

                I know that one of their current issues is providing something equivalent to rustup for a plug-and-play tool to start building backend Swift apps.

                1. 1

                  Swift is an OCaml anyway, like rust is, and doesn’t have GC. OCaml or GHC Haskell may be closest to what you’re looking for.

                  1. 1

                    That is true, but Swift doesn’t really need a GC since it has ARC instead.

              2. 2

                You can use a GC with rust if you want, but the whole point is you shouldn’t have to, since the compiler is smart enough to do most of it at compile time.

                As for green threads… pretty sure rust actually has async syntax right in the language now. So you don’t even need to “pick a syntax” there is an official one.

                1. 1

                  There is no real GC for rust. Even if there’s a crate providing one, there is no part of the ecosystem that will work ergonomically with it.

                  The compiler’s “smarts” do not help the additional cognitive load. It’s nice for lower-level software– Rust is an excellent replacement for C++. But I want something higher.

                  I’m well aware of async. And this article highlights all the issue with it. Both the syntax and semantics suffer without native green thread support, a la golang.

                  1. 1

                    …async and go style green threads are literally the same thing. This does not compute for me.

                    1. 2

                      I’ve always seen “async” used as event loop programming and “threads” (whether green or kernel level) to be, well, threads. The distinction makes perfect sense in most contexts I’ve used it/seen it used.

                      1. 1

                        I think I’m using the green thread terminology wrong. What I really mean is having one way of doing IO, without different syntax or semantics. In go, all blocking IO looks like async IO.

                        1. 1

                          Oh, yes, I can see what you mean now. Haskell and Ruby 3 have this too, I agree it’s very nice.

                2. 9

                  I liked the conversation on this topic and felt like sharing an opinion here. You don’t need async. My only complaint here is the proliferation of async where alternatives that are as high-quality and maintained are difficult to find now

                  “Async in Rust is hard”, FTFY

                  Just don’t use it. I’m not trying to be cheeky. I am a seasoned Rust dev and I avoid async. Async giving better performance is a half-lie. Though Rust community is party to blame here, because it is becoming hard to find non-async libraries. Thankfully, one can usually take an async library and .block_on all the calls. There’s also possibility of using async in parts of the system where it makes sense, and send messages back and forth between sync and async parts. More people are pragmatically reaching the same conclusion.

                  1. 2

                    In Python I’ve had a lot of painful experiences with someone calling a sync function from an async context this blocking the event loop and taking the entire app down (with timeouts in unrelated handlers, making debugging a nightmare). Does Rust have a similar problem?

                    1. 1

                      Blocking in event loop is problematic in Rust too. That said, typically you can spawn a thread (or use spawn_blocking) to run synchronous code within an asynchronous function.

                      1. 1

                        Blocking in event loop is problematic in Rust too.

                        Thanks for sharing. I didn’t know if Rust had features to make it hard to call a sync function from an async context or if it was error prone as with Python.

                        That said, typically you can spawn a thread (or use spawn_blocking) to run synchronous code within an asynchronous function.

                        Sure, I’m more concerned about someone unintentionally invoking a sync API (e.g., someone calls a library function which in turn uses an SDK that makes sync calls).

                  2. 6

                    Moreover, my prediction is that Rust will never be as popular as Java or Python.

                    I’m fine with that. People get far too excited about popularity. The fact is that Rust has had a huge permanent impact due to it’s applications in systems software. A lot of this work is even usable in higher level languages via C FFI or WASM.

                    The main benefit of massive Rust popularity would be more applications running more efficiently. While that would be great, it would come at a high complexity cost, and complexity is already spiraling out of control within software engineering. Keep Rust focused on what it does, systems software; be happy when it applies outside that scope but don’t corrupt the language for the sake of popularity.

                    1. 7

                      The honest companion to the statement you quote would be: C isn’t as popular as Java or Python either.

                      1. 4

                        People get far too excited about popularity

                        Fully agree. The ergonomics should continue to be worked on, but Rust was designed to be a systems language, and not every problem requires that.

                        Additionally, I much prefer a community of users that is consciously choosing said language for intended domains versus one where users choose it mostly because it is popular. I realize that sounds somewhat elitist, but mainstream popularity is a double-edged sword.

                        1. 2

                          The space of all programs is very large and IMO too much for most humans to handle. Having opinions in your language is a necessary evil to tame cognitive load. I think it’s fine that Rust is forging its own path closer to other systems languages. As long as there are other options in the space (and there are tons of PLs), there’s nothing wrong with focusing on a certain set of applications, IMO.

                        2. 2

                          Keep Rust focused on what it does, systems software

                          Then why is it called “general purpose”?

                          1. 11

                            Because it’s “general purpose”?

                            Really, it’s only systems software languages (C, C++, Ada, Rust, etc) that are general purpose in the broadest sense – most other high level languages have made decisions (typically, to have GC or a significant runtime) that rules them out for writing certain classes of software.

                            “General purpose” doesn’t mean it’s as convenient to write a CRUD web app in Rust as it is in Ruby; it just means that you could write a CRUD web app, an OS, or anything in between in Rust, whereas Ruby has less generality. You’re still better off using Ruby for the web app and saving Rust for the systems stuff, though.

                            1. 2

                              You’re still better off using Ruby for the web app and saving Rust for the systems stuff, though.

                              I agree, but now I have to go and hide all my rust CRUD apps, which definitely took longer to make than just throwing rails or django at them.

                              1. 2

                                Hey nothing wrong with choosing the less “convenient” path either. Sometimes the journey is the goal, not getting to the destination ASAP.

                                1. 1

                                  well you always tell yourself that its more efficient / runs a lot more robust (error handling vs throwing in production) etc

                                  But maybe that’s completely irrelevant ? I guess I’m still not at the point where I know exactly what counts for me. At least I can say that the stuff I did deploy runs very smooth. But it can be a ton of overhead to get started.

                            2. 7

                              Is it? I think Rust calls itself a systems programming language (although that term is also a bit fuzzy). Either way, I don’t think it’s technically wrong to call it that. It is reasonable to use it for a wide range of programs. If you don’t insist on abstractions having absolutely zero cost (like the TFA) it’s not even that difficult. But for programs that don’t need to maximize efficiency there are tons of nice languages to choose from, so while Rust may be usable, it’s not the best choice for everything.