back
269 comments
"Memory Safe No garbage collector, no manual memory management. A work in progress, though."

I wish them the best, but until they have a better story here I'm not particularly interested.

Much of the complexity in Rust vs simplicity in Go really does come down to this part of the design space.

Rust has only succeeded in making a Memory Safe Language without garbage collection via significant complexity (that was a trade-off). No one really knows a sane way to do it otherwise, unless you also want to drop the general-purpose systems programming language requirement.

I'll be Very Interested if they find a new unexplored point in the design space, but at the moment I remain skeptical.

Folks like to mention Ada. In my understanding, Ada is not memory safe by contemporary definitions. So, this requires relaxing the definition. Zig goes in this direction: "let's make it as safe as possible without being an absolutist"

If you look at the Github, there's a design proposal (under docs/design) for that.

It looks like the idea at the present time is to have four modes: value types, affine types, linear types, and rc types. Instead, of borrowing, you have an inout parameter passing convention, like Swift. Struct fields cannot be inout, so you can't store borrowed references on the heap.

I'm very interested in seeing how this works in practice--especially given who is developing Rue. It seems like Rust spends a lot of work enabling the borrow checker to be quite general for C/C++-like usage. E.g. you can store a borrowed reference to a struct on the stack into the heap if you use lifetime annotations to make clear the heap object does not outlive the stack frame. On the other hand it seems like a lot of the pain points with Rust in practice are not the lifetime annotations, but borrowing different parts of the same object, or multiple borrows in functions further down the call stack, etc.

> Rust has only succeeded in making a Memory Safe Language without garbage collection via significant complexity (that was a trade-off). No one really knows a sane way to do it otherwise, unless you also want to drop the general-purpose systems programming language requirement.

> I'll be Very Interested if they find a new unexplored point in the design space, but at the moment I remain skeptical.

They’re the somewhat sane “don’t allow dynamic allocations; just dimension all your arrays large enough” approach from the 1950s (Fortran, COBOL).

A variant could have “you can only allocate globals and must allocate each array exactly once before you ever access it”. That would allow dimensioning them from command line arguments or sizes of input files.

The type system then would have “pointer to an element of foo” types (could be implemented old-style as indices)

Yes, that would limit things, but with today’s 64-bit address spaces I think it could work reasonably well for many systems programming tasks.

It definitely would be significantly less complex than rust.

Wasn't Borgo[1] suppose to be the new child of Rust and Go too? Rue, is like the new replacement of Borgo, which hadn't been out for long.

On top of that, the original child of Rust and Go, was called Vlang[2].

[1]: https://borgo-lang.github.io/

[2]: https://www.youtube.com/watch?v=puy77WfM1Tg (Is V Lang Better Than Go And Rust? Let's Find Out)

I always thought of Go as low level and Rust as high level. Go has a lot of verbosity as a "better C" with GC. Rust has low level control but many functional inspired abstractions. Just try writing iteration or error handling in either one to see.
I wonder if it's useful to think of this as go is low type-system-complexity and rust is high type-system-complexity. Where type system complexity entails a tradeoff between the complexity of the language and how powerful the language is in allowing you to define abstractions.

As an independent axis from close to the underlying machine/far away from the underlying machine (whether virtual like wasm or real like a systemv x86_64 abi), which describes how closely the language lets you interact with the environment it runs in/how much it abstracts that environment away in order to provide abstractions.

Rust lives in high type system complexity and close to the underlying machine environment. Go is low type system complexity and (relative to rust) far from the underlying machine.

Yep. This was the biggest thing that turned me off Go. I ported the same little program (some text based operational transform code) to a bunch of languages - JS (+ typescript), C, rust, Go, python, etc. Then compared the experience. How were they to use? How long did the programs end up being? How fast did they run?

I did C and typescript first. At the time, my C implementation ran about 20x faster than typescript. But the typescript code was only 2/3rds as many lines and much easier to code up. (JS & TS have gotten much faster since then thanks to improvements in V8).

Rust was the best of all worlds - the code was small, simple and easy to code up like typescript. And it ran just as fast as C. Go was the worst - it was annoying to program (due to a lack of enums). It was horribly verbose. And it still ran slower than rust and C at runtime.

I understand why Go exists. But I can't think of any reason I'd ever use it.

Rue author here, yeah I'm not the hugest fan of "low level vs high level" framing myself, because there are multiple valid ways of interpreting it. As you yourself demonstrate!

As some of the larger design decisions come into place, I'll find a better way of describing it. Mostly, I am not really trying to compete with C/C++/Rust on speed, but I'm not going to add a GC either. So I'm somewhere in there.

Low and high level are not well-defined concepts.

One, objective definition is simply that everything that is not an assembly is a high-level language - but that is quite a useless def. The other is about how "deeply" you can control the execution, e.g. you have direct control of when and what gets allocated, or some control over vectorization, etc.

Here Rust is obviously as low-level as C, if not more so (both have total control over allocations, but still leaves calling conventions and such up to the compiler), while go is significantly higher (the same level as C#, slightly lower than Java - managed language with a GC and value types).

The other often mistaken spectrum is expressivity, which is not directly related to low/high levelness. E.g. both Rust and Scala are very expressive languages, but one is low, the other is high level. C and Go both have low expressivity, and one is low the other is high level.

This answer is imo a very must have read about the topic of expressivity: https://langdev.stackexchange.com/a/2016

Agree with Go being basically C with string support and garbage collection. Which makes it a good language. I think rust feels more like a c++ replacement. Especially syntactically. But each person will say something different. If people can create new languages and there's a need then they will. Not to say it's a good or bad thing but eventually it would be good to level up properly. Maybe AI does that.
All are high level as long as they don't expose CPU capabilities, even ISO C is high level, unless we count in language extensions that are compiler specific, and any language can have compiler extensions.
I think it is precisely why Rust is gold - you can pick the abstraction level you work at. I used it a lot when simulating quantum physics - on one hand, needed to implement low-level numerical operations with custom data structures (to squeeze as much performance as possible), on the other - be able to write and debug it easily.

It is similar to PyTorch (which I also like), where you can add two tensors by hand, or have your whole network as a single nn.Module.

C was designed as a high level language and stayed so for decades
Go has a GC and Rust doesn't. That alone makes Go higher level.
> Memory Safe

> No garbage collector, no manual memory management. A work in progress, though.

I couldn't find an explanation in the docs or elsewhere how Rue approaches this.

If not GC, is it via:

a) ARC

b) Ownership (ala Rust)

c) some other way?

I am playing around with this! I'm mostly interested in something in the space of linear types + mutable value semantics.
ARC is GC, chapter 5.

https://gchandbook.org/

Check out V-lang ... it has the details. It's a beautiful language... but, mostly unknown.
I couldn't figure out the main points, besides the "between Rust & Go" slogan. I've worked both with Rust and Go, and I like Rust more, but there are several pain points:

* macro abuse. E.g. bitshift storing like in C needs a bunch of #[...] derive_macros. Clap also uses them too much, because a CLI parameter is more complex than a struct field. IDK what's a sane approach to fixing this, maybe like in Jai, or Zig? No idea.

* Rust's async causes lots of pain and side effects, Golang's channels seem better way and don't make colored functions

* Rust lacks Python's generators, which make very elegant code (although, hard to debug). I think if it gets implemented, it will have effects like async, where you can't keep a lock over an await statement.

Zig's way is just do things in the middle and be verbose. Sadly, its ecosystem is still small.

I'd like to see something attacking these problems.

I've been having fun with Gleam. I'm not really sure where it falls on the spectrum though. It is garbage collected, so it's less abrasive than Rust in that sense. But it's pure functional which is maybe another kind of unfriendly.
It’s too early to have slick marketing and main points.

Noted, thanks for the comment. I share some of these opinions more than others, but it’s always good to get input.

I am surprised that a language with nothing than a couple of promises gets so much attention. Why exactly?
Probably best to link to the repo itself, this is not meant to be used yet. https://github.com/rue-language/rue
It may have been more useful to link to the blog post [0] which gives more of an introduction than the front page at this point.

[0] https://rue-lang.dev/blog/hello-world/

Interesting, for me the "between Rust and Go" would be a nice fit for Swift or Zig. I've always quite liked the language design of Swift, it's bad that it didn't really take off that much
All the Rue code in the manual seems to also be valid Rust code, except for the @-prefixed intrinsics
Okay, right now it's basically Pascal as it was described in Revised Report, only even more restricted. Which is... fine, I guess, you can still write a whole OS with something like that (without using pointers/addresses) as Per-Brinch Hansen demonstrated but it's... an acquired taste.

Are the actual references/pointers coming in the future?

How does this differ from Hylo [0]?

[0] https://hylo-lang.org

I don't need lower level than go. I just really like Rust' type system and error handling and I want it in a compiled language.

Zero Cost abstractions and it's memory model is fascinating - but isn't particularly useful for the part of the tech stack I work on.

I have mostly been writing Rust in the last 10 years, but recently (1 year) I have been writing Go as well as Rust.

The typical Go story is to use a bunch of auto generation, so a small change quickly blows up as all of the auto generate code is checked into git. Like easily a 20x blowup.

Rust on the other hand probably does much more such code generation (build.rs for stuff like bindgen, macros for stuff like serde, and monomorphized generics for basically everything). But all of this code is never checked into git (with the exception of some build.rs tools which can be configured to run as commands as well), or at least 99% of the time it's not.

This difference has impact on the developer story. In go land, you need to manually invoke the auto generator and it's easy to forget until CI reminds you. The auto generator is usually quite slow, and probably has much less caching smartness than the Rust people have figured out.

In Rust land, the auto generation can, worst case, run at every build, best case the many cache systems take care of it (cargo level, rustc level). But still, everyone who does a git pull has to re-run this, while with the auto generation one can theoretically only have the folks run it who actually made changes that changed the auto generated code, everyone else gets it via git pull.

So in Go, your IDE is ready to go immediately after git pull and doesn't have to compile a tree of hundreds of dependencies. Go IDEs and compilers are so fast, it's almost like cheating from Rust POV. Rust IDEs are not as fast at all even if everything is cached, and in the worst case you have to wait a long long time.

On the other hand, these auto generation tools in Go are only somewhat standardized, you don't have a central tool that takes care of things (or at least I'm not aware of it). In Rust land, cargo creates some level of standardization.

You can always look at the auto generated Go code and understand it, while Rust's auto generated code usually is not IDE inspectable and needs special tools for access (except for the build.rs generated stuff which is usually put inside the target directory).

I wonder how a language that is designed from scratch would approach auto generation.

Just pointing out here that "rue" is used to express "to regret", emphatically. Perhaps it is not the best name for a programming language.
I write a lot of go. I tried to write a lot of rust but fell into lifetime traps. I really want to leave C++ but I just can’t without something that’s also object oriented.

Not a dig at functional, it’s just my big codebases are logically defined as objects and systems that don’t lend itself to just being a struct or an interface.

Inheritance is why I’m stuck in C++ land.

I would love to have something like rust but that supports classes, virtual methods, etc. but I guess I’ll keep waiting.

If this language is supposed to be used for systems programming, doing a factorial isn't really a selling example of why Rue.
The positioning is interesting - claiming Rust's performance with Go's simplicity is basically every new systems language's promise since 2015. The key differentiator seems to be "zero-cost exceptions" which I assume means compile-time Result types without runtime unwinding overhead? That's compelling if true, since Rust's Result ergonomics can get verbose in deeply nested error chains.

But the real test is compile times and cognitive overhead. Rust's borrow checker is theoretically elegant but practically brutal when you're learning or debugging. If Rue can achieve memory safety without lifetime annotations everywhere, that's genuinely valuable. However, I'm skeptical - you can't eliminate tradeoffs, only move them around. If there's no borrow checker, what prevents use-after-free? If there's garbage collection, why claim "lower level than Go"?

The other critical factor is ecosystem maturity. Rust's pain is partially justified by its incredible crate ecosystem - tokio, serde, axum, etc. A new language needs either (1) seamless C FFI to bootstrap libraries, (2) a killer feature so valuable that people rewrite everything, or (3) 5+ years for the ecosystem to develop. Which path is Rue taking?

I'd love to see real-world benchmarks on: compile time for a 50k line project, memory usage of a long-running web server compared to Rust/Go, and cold start latency for CLI tools. Those metrics matter more than theoretical performance claims. The "fun to write" claim is subjective but important - if it's genuinely more ergonomic than Rust without sacrificing performance, that could attract the "Python developers wanting systems programming" demographic.

What the world needs is a more expressive language than Go, that interops with Go's compilation model and libraries.
Any plans for adding algebraic data types (aka rust enums)?
Any tentative ideas yet as to how you will manage the memory management? Sounds like a sort of magic 3rd way might be in the making/baking!
What was the rationale to not use cargo? By the way, I really enjoy when you are a guest on the fallthrough podcast.
In the intro text, the Ramsus is who ? a typo about php creator or a more obscure language creator?
Looks nice, but -> syntax always feels extremely off-putting. What does it get me?
How does it achieve memory safety?

    fn fib(n: i32) -> i32
so unnecesary, just extra writing. We're developers, we understand that function return types are after first ()

       let mut i = 0;
No, no, copy Go here, i := 0 is just fine
I wince every time I see naive recursive fibonacci as a code example. It is a major turnoff because it hints at a lack of experience with tail call optimization, which I consider a must have for a serious language.
How does this compare to Swift?
This is a bit silly but when i look at new languages coming up I always look at the syntax, which is usually horrible(Zig and Rust are good examples), and how much garbage there is. As someone that writes in Go, I can't stand semicolons and other crap that just pollutes the code and wastes time and space to write for absolutely no good reason whatsoever. And as this compares itself with Go, I just cannot but laugh when I see ";", "->" or ":" in the example. At least the semicolon seems optional. But still, it's an instant nope for me.
when we are we getting a language that looks like python and runs 50 times faster than c++ /s