Why don't we call Rust Behavior-Oriented Programming

Hi all,

from time to time topics like 'Why is Rust so bad at OOP?', 'Why doesn't Rust support feature X from OOP-language Y?' and so on turn up on in this forum. I think most of you know what I'm talking about. In those discussions it is then pointed out that with enough tricks, hacks and crates you can have more OO-ish Rust. However, I think this is the wrong way to go. The way Rust's type(/trait) system is designed it is just different from the hierarchical approaches that are favored in C++, Java, C# and so on (by design, I know that it is not recommended).

Therefore, I propose to call Rust's way of doing OOP Behavior-Oriented Design. In many OOP classes the first thing you learn is abstractions like a car is a vehicle and vehicles have this properties and methods. In difference, the Rust way (from my point of view) is to say a car is movable and movable types have this behavior. And it's the same for abstraction. Instead of stating that a function takes any kind of a vehicle (fn func(v: &dyn Vehicle)), a Rust function rather states that it requires something that can move (fn func(m: impl Movable)). This can also be seen at traits like Copy and Clone that rather describe behavior than a class of objects.

I know this view is not very different from Java's interfaces but I think it can help beginners to faster understand the mind set behind Rust's way of abstracting things.

What do you think about this?

17 Likes

I agree, that giving separate name for it (because it actually differs from Javaish/C#ish OOP) may improve learning curve, but I don't think that it would solve the problem. The problem is that people doesn't like changing their habits, and way of thinking at all. This is the reason why it is so hard to learn functional programming after couple years of doing imperative programming (its much easier to teach it to someone completely new to programing world). The same is true for Rust - similarly to FP, Rust introduces completely new approaches which were not a case in typical OOP programming. I am not even talking about borrow checker, but even things like reversing logic about trait implementation (trait is implemented for type vs type implements some defined set of interfaces), lack of any distinction between generics typing and dynamic distpatch typing (like concepts/enable_if for C++ templates and inheritance for dynamic dispatch - i don't know if in Java there is some way of constraining generics). This makes learning Rust more difficult with every year you are working with C++ or Java.

1 Like

IMO, in the case of Rust, rather than Object-Oriented Programming, it'd be more precise to call it Module-Oriented Programming. Most of the time, OOP centers privacy around single classes and that no one, but the class itself should be accessing its fields directly, but practice has shown, that being overprotective to the internals leads to terrible-performing designs and brittle interfaces. Rust offers a more practical design, having chosen the module as the default and strictest possible layer of privacy you can have. In addition to module-level privacy, Rust also offers super-module-level and crate/package-level privacy, providing a more flexible way of handling privacy, solving privacy issues by thinking in more than just black and white.

6 Likes

Why argue when you are both right: Rust is BOP and MOP!

  • Behavior-Oriented Polymorphism âźą code reuse

  • Module-Oriented Privacy âźą abstraction boundary


I stumbled upon a talk discussing how "classes" were initially designed as an abstraction boundary (good design), and how they ended up getting side-tracked with inheritance as a way of offering polymorphism (and that's the part of the design of OOP that I think is most often criticised).

By splitting these two programming paradigms into their own tools (traits and modules), Rust has offered a way to use each more accurately.

16 Likes

Specifically, one of the bigger sins of Class Oriented Programming is the way inheritance ties together polymorphism and code reuse. In practice this can lead to poor design. There are principles, such as SOLID, that can aid good design but IMHO it's rare that (for example) Liskov substitution principle is truly upheld, even with the best of intentions. Class based languages will rarely help you here, and indeed they often make doing the wrong thing easier.

2 Likes

I think it's meaningless and futile to try and shove any sophisticated programming style into the same square-shaped hole.

People arguing whether Language X is "true OOP" or "true FP" or "true XYZ" would probably be better off investigating specific cases in which the interactions between a given subset of language features and programmers' a priori expectations clash. This is way more productive and meaningful because it can lead to actual results and observations, instead of everybody ending up arguing about arbitrary definitions.

Furthermore, I don't think Rust would benefit from such a hype train approach – sensible ideas could then be rejected and not-so-sensible ones could be implemented in the language in the name of making it "pure BOP" (or whatever it ends up being called).

See my previous discussion on the topic.

11 Likes

To a certain extent I think that trying to name Rust an "anything" oriented language would be somewhat misleading no matter how you do it. What its oriented around is safety and correctness and its type system is based heavily on traits, which seem somewhat unique ( other than Haskell, as I've heard ).

The other thing is that you can use the language like a functional programming language, or you can use it do accomplish another style no matter what you call it.

The "orientedness" of a language, as I would guess, should be used to give indication of what programming model the language will attempt to make productive with it. Rust, though, as far as I can tell, isn't necessarily oriented at a specific programming model as much as being able to provide powerful, ergonomic, and safe interfaces. Often these interfaces are to things such as hardware, which is inherently unsafe.

4 Likes

So that's it then, Rust is a "COP" language, "Correctness Oriented Programming"

:slight_smile:

4 Likes

Sort of, but I don't think we should call it that. :slight_smile:

Just tell them about it, don't invent a new term or attempt to use an old term for it. The point at which you need a term for it is when you have a lot of languages or something that are related to each other because they share the same vision or model.

1 Like

Ha! I don't think we should call it that either.

Let's just call it Rust. Media, pundits and those that make a living by selling paradigms and software engineering methods will no doubt come up with some gross term for this sort of thing eventually.

3 Likes

That's a COP-out :wink:

2 Likes

I think trait-based polymorphism might be the most accessible and familiar term to object-oriented programmers.

Another important OOP concept applies to Rust is the notion that Delegation Is Inheritance, developed in the seminal OOPSLA 1987 paper of the same name.

1 Like

Swift creators like to talk about Protocol-Oriented Programming and Swift Protocols are roughy the same as Rust Traits. Funnily enough, I've been also using the term Behavior-Oriented Programming when talking about systems of this kind. The thing is, Rust is not unique in this regard, and having concise terminology to refer to this programming paradigm could be helpful. If nothing else, it could be useful to people who want to educate themselves.

Traits are only one tool that Rust offers for building abstractions, but the language as a whole is not oriented around them, only certain APIs are. Rust doesn't provide any high-level organizational paradigm which you can use to reason about the structure of programs, save for the fact that it is largely an imperative language that enforces some kind of memory safety. That being said, it would make sense to call Rust a safety-oriented programming language, but that doesn't seem all that useful as a programming paradigm because there are many other ways to achieve that goal in other programming paradigms.

4 Likes

Assigning labels to a language doesn't make it easier to learn it or to understand it's philosophy. What makes it easier is practice. It is pretty much pointless to try to understand a language without writing code, and if you're already doing that, any label is only a needless distraction. The code says it all. And so does the front page of rust-lang.org.

2 Likes

Exactly. That is one thing I loved about getting into Rust. Right up on the front page and on the very first page of the book, you are told what Rust is all about: empowering people to make efficient and correct software.

Even after looking around for a while, I couldn't actually figure out what the Go language was about. All I could find was that it was supposed to be a better replacement to C or Java, but that didn't tell me what drove the vision of Go.

The vision of a project is a lot of what is important to me about a project. Where are they trying to go with it and what drives future development and practice.

1 Like

I'm not sure I follow, since here's the first search result for "go lang":

(So as a result, I don't fine "reliable/efficient/correct" to be particularly useful descriptions of either Rust or Go.)

That's a valid point.

I think it was more about impression. For example, this:

Meant a lot more to me than this:

image

Rust just went further in the direction of telling me how they were going to do what they said than just telling me what they were going to do. That makes me believe in it more.


Then you get into the rust book and it goes even further:

It wasn’t always so clear, but the Rust programming language is fundamentally about empowerment : no matter what kind of code you are writing now, Rust empowers you to reach farther, to program with confidence in a wider variety of domains than you did before.

Take, for example, “systems-level” work that deals with low-level details of memory management, data representation, and concurrency. Traditionally, this realm of programming is seen as arcane, accessible only to a select few who have devoted the necessary years learning to avoid its infamous pitfalls. And even those who practice it do so with caution, lest their code be open to exploits, crashes, or corruption.

Rust breaks down these barriers by eliminating the old pitfalls and providing a friendly, polished set of tools to help you along the way. Programmers who need to “dip down” into lower-level control can do so with Rust, without taking on the customary risk of crashes or security holes, and without having to learn the fine points of a fickle toolchain. Better yet, the language is designed to guide you naturally towards reliable code that is efficient in terms of speed and memory usage.

...

It really gets into the meat about what it is about. All of the sudden I know why I want to learn Rust.

7 Likes

Labels can help, but only if said label has a clear, well-defined meaning and if there are more than one language that can fit into that category. Then people knowing a similar "OOP" or whatever language know to look for similarities. This will aid in learning the new language quicker.

However, new terms for the sake of terms isn't helping anybody.

3 Likes

IMHO, OOP is a bad example (or a good one, depending on the point of view). Most people don't even realise that it does not necessarily imply inheritance, yet one of the first things every other language book tells about OOP is that Dog is a subclass of Mammal. Then people eventually discover Rust and start to complain that there is not enough OOP in it or that it doesn't have any, which is, of course, complete bollocks. I don't know about you, but I definitely don't want to spend too much time explaining to colleagues and other people the meaning of vague terms such as "behaviour-oriented", and why Rust is more "behaviour-oriented" than, say aspect-oriented or whatever-oriented. The way I see it, Rust is not oriented towards anything. Sure, it has goals, but they are not embossed on some holy stone tablets.

There is a better way: show off good-looking, performant and safe code, that is too hard or even impossible to write in e.g. C++, and let it speak for itself. When a sparkle ignites the fire in someone's eyes, they are determined to learn the language, and they will have to break mental barriers inherited from their previous experience. They will passionately learn ownership, borrowing, etc. and decide for themselves to which category Rust belongs. In other words, don't try to fit Rust into a category preemptively, let that process be natural. 10 years later the language will be different, and the label you chose today will become a dangling pointer, so to speak.

4 Likes