What ideas from Rust would be most helpful in designing a new programming language?

Hi all — I’m experimenting with a new language called Solnix and want to learn from successful designs like Rust.

In your experience, what parts of Rust’s syntax, error handling, or borrow/ownership style have the most benefits — and what parts caused the most pain?

I’d love to learn from real Rust users before locking in any design decisions. Thanks!

When you design a new language, it’s to answer a problem, so you should rather tell us what problem you’re trying to solve or what is missing in existing languages that you’d like to see, and we can go from there. :slight_smile:

4 Likes

Thanks, that’s a fair point :slightly_smiling_face:

Solnix is aimed specifically at eBPF programming with a strong focus on verifier-friendliness and security. The problem I’m trying to address is that today’s eBPF development (mostly in C, sometimes Rust) still involves a lot of trial-and-error with the kernel verifier, and many bugs only surface as verifier rejections rather than at compile time.

Concretely, Solnix is exploring:

  • Verifier-aware semantics: language rules that prevent unbounded loops, invalid pointer arithmetic, and unsafe memory access by construction, instead of relying on verifier diagnostics.
  • Restricted but explicit memory model: inspired by Rust’s ownership ideas, but simplified to match eBPF constraints (no heap allocation, controlled aliasing, map/value lifetimes tied to program scope).
  • Security-first defaults: no implicit casts, explicit bounds checks, and types that encode “trusted vs untrusted” data (e.g., packet data vs verified data).
  • Compiler-enforced constraints: rejecting programs that would be unverifiable or unsafe before they reach the kernel.

That’s why I’m particularly interested in which parts of Rust’s ownership model, error handling, and type system have delivered real safety benefits in practice—and which parts became too complex or painful—so I can adapt the ideas without importing unnecessary complexity.

2 Likes

BPF is a pain in Rust. Rust safety is at type level so panic is only undesirable but safe, until you write for BPF and find it not supported.

Maybe range is useful to carry over and integrate with a verifier.

Long time since I wrote a small bit in Rust but think tests were non existent so some support is probably good.

This is by no means an exhaustive list, but just a few things that come to mind when I think about what I like the most about Rust:

Things I like

Clear APIs

When I see the signature of a function written in Rust, I get almost all the information I need about it, making local reasoning a real thing.

For example:

  • I see what error handling approach was taken
  • If parameters are passed by value or by reference
  • What behaviour (traits) a given parameter requires to satisfy

Error handling

Rust's approach to error handling is the most ergonomic one I've experienced so far. On this subject, I would particularly highlight:

  • Rust's approach to error handling makes it easier to reason about how to handle fallible vs. infallible errors
  • The Result type being monadic makes it easier to handle the success and error branches
  • The try (?) operator is super ergonomic to bubble errors upstream

Null safety

The Option type is by far the approach I like the most with regards to null safety.

Enums to represent algebraic sum types

Rust enums are more powerful than enums in most other programming languages in the sense that enum variants can hold associated data, thus being the mechanism to represent algebraic sum types.

Combined with pattern matching and exhaustiveness checking, they become a very powerful tool for domain modelling.

Reasonable defaults

Rust's has the most reasonable defaults as far as I can think. For example:

  • Struct fields are private by default
  • Variable bindings are immutable* by default
  • User-defined types cannot be used in cross-thread boundaries by default
  • User-defined types have no behaviour by default

Suffice to say that most of these features are not specific to Rust, but having all of them in a single language is probably the reason why I like Rust the most.

Where friction appears

  • Rust ownership model makes it a difficult language to learn for people with baggage
  • Rust lack of OOP features like inheritance makes it a difficult language to learn for people with baggage
  • Opaque/Unnamable types
1 Like

That’s quite interesting! I didn’t know what eBPF was. If I understand well, you need even more compile-time safety than what Rust offers, and also at different levels?

Part of it is already done in Rust, though, so I’m wondering if it wouldn’t be possible to enforce the rest either by using its type system (e.g. for trusted vs untrusted data), then by plugging something into the compiler or by doing another verification, a little like Clippy. I’m playing the devil’s advocate, of course, but it’s a huge amount of work that’s already been done, and a big ecosystem that’s already there.

Regarding Rust:

For me, the part that bring the most benefit without pain is the type system: unit structs and algebraic-type enums allow to avoid a lot of issues at compile time. On top of what’s already been said above, type inference is a very good ally, there, since it allows to use the type system without too much boiler plate; otherwise, it could very well become the most painful part.

The part that’s the most difficult for me in Rust is avoiding aliases (borrow checker) and handling lifetimes. You must acquire a new mindset and learn to program a little differently. From the compiler’s perspective, I think it’s very hard to make the borrow checker smart and not too intrusive so that it’s possible to write code with as much pain as possible. Maybe it’s worth looking at the lessons learned and how Polonius is attempting to solve the current issues.

To clarify, I’m not trying to build a Rust-like general-purpose programming language. Solnix is intentionally narrow: it’s a Linux security and policy-oriented language designed specifically for eBPF-based use cases such as network packet counters, intrusion prevention rules, and attack detection logic.

Today, these kinds of systems are usually implemented using:

  • C directly for eBPF, or
  • Rust with libraries and frameworks that eventually lower to eBPF.

Both approaches work, but they still leave developers dealing with:

  • verifier rejections,
  • subtle pointer and bounds issues,
  • and a lot of trial-and-error to satisfy the eBPF verifier.

Solnix takes a different approach:

  • The language itself encodes eBPF verifier constraints (bounded loops, restricted memory access, controlled aliasing).
  • The compiler is not targeting userspace or general execution, but only eBPF.
  • The backend generates strict, verifier-friendly eBPF C code, reducing rejection rates before the program ever reaches the kernel.

While Rust’s type system and tooling are excellent, extending Rust to fully enforce eBPF verifier rules would still mean:

  • working around general-purpose language features that eBPF does not support,
  • relying on additional tooling, lints, or post-compilation checks.

By designing a dedicated language, I can:

  • make verifier-safe constructs the default,
  • forbid unverifiable patterns entirely,
  • and shift more security guarantees to compile time instead of verifier feedback.

That said, Rust is a huge inspiration — especially its type system, explicitness, and safety-first design. The goal isn’t to replace Rust, but to specialize for a domain where the constraints are so strong that a purpose-built language can reduce complexity and improve reliability.

2 Likes

That’s very close to what I’m seeing too. Solnix is trying to bake those BPF constraints (like ranges and verifier limits) directly into the language instead of fighting them later in Rust.
If you’re curious, I’d really appreciate a quick look or feedback from your BPF experience — https://solnix-lang.org

Yes, that makes sense. I was thinking about easy adoption and the existing ecosystem, but if the user isn’t able to use a part of it, that may be confusing and frustrating.

If the language simply doesn’t allow forbidden constructions, it’s a little bit similar to using a type system to reject as many problems as possible at compile time rather than dealing with them at runtime (if that makes sense).

1 Like

I do not know if it is possible, but I can do same thing in Rust in dozen ways. Make it only in one way in your language.

This is a really interesting project, I'm curious to see where it goes! Personally, I'd say that its exhaustiveness is my favorite feature that would seem to go well with eBPF. The way matches, error handling, borrowck, etc. all work together to make sure (as far as possible) that your program is bug-free. If I had to pick one feature... I'd say sum types (enums) with exhaustive, well-integrated pattern matching is a total game changer. Albeit a lot of work.

(nit: your syntax appears to change between the homepage and docs; which syntax are you going with?)

Appreciate the insight! If you’re interested, I’d be happy to invite you to the Solnix GitHub org to continue design discussions

I admit I've not actually done anything with eBPF, just kind of skirted around it, so I doubt I'd be very helpful. My interest is more academic/recreational: domain-specific languages with unusual constraints are a fun concept to me. If you just want somebody to bounce ideas off of, though, or to pitch in with the occasional ill-informed half-thought-out idea, I'd be glad to fill that role. :wink:

not very relevant to your needs, but: doctests