Skip to content
This repository has been archived by the owner on Sep 30, 2020. It is now read-only.

Explicitly answer the question "Is Rust object oriented?" #467

Closed
wants to merge 2 commits into from
Closed

Explicitly answer the question "Is Rust object oriented?" #467

wants to merge 2 commits into from

Conversation

JinShil
Copy link

@JinShil JinShil commented Aug 4, 2016

The FAQ "How do I map object-oriented concepts to Rust?" explicitly states "Rust is not object-oriented", so it should be explicitly stated in the FAQ that directly asks that question.

The FAQ "How do I map object-oriented concepts to Rust?" explicitly states "Rust is not object-oriented", so it should be explicitly stated in the FAQ that directly asks that question.
@rust-highfive
Copy link

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@brson
Copy link
Contributor

brson commented Aug 9, 2016

Hi @JinShil, sorry for the delay.

I wonder if we want to be that forceful. 'object-oriented' means a lot of things, and you can write code in Rust that is more or less object-oriented as one desires, as you can even in C (though if somebody asked this question about C I would not hesitate to say 'no').

f? @steveklabnik @AndrewBrinker

@brson
Copy link
Contributor

brson commented Aug 9, 2016

Really, this question probably calls for more nuance than a single sentence.

@alilleybrinker
Copy link
Contributor

Yeah, it really depends by what the questioner means when they say "object oriented." If they mean "object oriented as in Java" then we can explain that Rust doesn't have classes, objects, inheritance and the like. If they mean "object oriented as in Smalltalk" we can talk about message passing and how you would go about that in Rust. In the end, an analogy to C is probably the strongest answer, with an explanation of what that means, along with a suggestion that OO may not be the best way to program in Rust by default, even if it is possible.

@JinShil
Copy link
Author

JinShil commented Aug 9, 2016

I'll update this pull request with more nuance a little later. However, there needs to be more blunt honesty. I approached Rust with the expectation that there was some object-oriented capabilities, and came away extremely disappointed, and even felt lied to.

Rust does have a few patterns (very few) that can be used as an alternative to object-oriented programming, but they are clearly alternatives; they are not object-oriented.

Furthermore, the question "How do I map object-oriented concepts to Rust?" frankly says "Rust is not object-oriented". So which is it?

If someone wants to come up with some more appropriate language, I'll update this pull request. Just be frank and honest. I still plan on predicating whatever is said with a definite "No."

@steveklabnik
Copy link
Member

Really, this question probably calls for more nuance than a single sentence.

Yes, please.

@JinShil
Copy link
Author

JinShil commented Aug 9, 2016

Added a little softer nuance without going into great detail, and without substantially deviating from what's already there. But, at least now its frank and honest.

@steveklabnik
Copy link
Member

I know @wycats has strong feelings about this.

@brson
Copy link
Contributor

brson commented Aug 10, 2016

@JinShil thanks for pointing out the inconsistency in the two OO-related questions. Since I think the best answer here will be somewhat involved, I opened an issue on the subject.

I'm still not sure about the answer as written here, which basically says 'no'. At least the existing wording hints that there is more subtly to the matter.

@wycats
Copy link

wycats commented Aug 10, 2016

I've programmed in a number of languages with various object oriented capabilities, and there's a lot less consistency between the languages than this answer might suggest.


Does Rust have objects with special syntax and semantics for methods?

Very strongly yes. In fact, method calling syntax is the one place in Rust where borrowing is automated. The &self parameter also gets special precedence in the lifetime elision rules. The rationale for that rule was very expressly about objects and methods.


Does Rust provide an "interface" facility, allowing functions and methods to declare that they need an object that implements some interface, and other uncoordinated code to implement it on objects they have created?

Yes. Rust's "traits" are very similar to interfaces in other typed object oriented languages. Unlike interfaces, traits are scoped, which means that you have to import a trait in order to use its methods. This allows for convenience traits that can work on simple objects (like u64) without globally polluting those objects.

More recently, the specialization feature (which has largely landed but is not yet stabilized) allow you to specialize existing implementations. For example, Rust has a Hash trait that allows an object to indicate how to compute its hash code, and many objects implement it. Rust has provided a built-in implementation for Option<T> as long as T itself implements the Hash trait. The specialization features allows me to implement it on Option<MyType>.


Does Rust allow to express inheritance hierarchies?

In Rust, traits can depend on other traits, which provide some mechanisms for expressing inheritance patterns. Interestingly, trait inheritance both avoids the limitations of single inheritance, which requires a strict single inheritance hierarchy, and traditional forms of multiple inheritance, which combines all "traits" of an object into a single method resolution order.

In other words, Rust traits allow you to have a separate inheritance hierarchy per concept, without adding cognitive cost when working on code unrelated to a particular trait. As above, the fact that traits must be imported also makes them more usable for convenience APIs, which interestingly means that Rust tends to make more aggressive use of OO patterns that are usually very dangerous in other OO languages (like defining methods on common types like numbers).


Does Rust allow you to create subclasses, where the subclasses have access to the fields of the superclass?

Today, there is no direct facility for doing so. However, various efforts to improve Rust in this direction have been underway for some time. @nrc's efficient code reuse RFC, opened before 1.0, is a good starting point. At the time, he proposed "Efficient single inheritance with traits", which was postponed due to the impending 1.0.

More recently, there have been some efforts to allow traits to express a dependency on fields, including @nikomatsakis's RFC on the topic.

Ultimately, combining specialization with traits-with-fields should get us much closer to being able to express something resembling traditional object oriented styles, but built on top of more flexible primitives that can also be used to express many more concepts as well.

As a person who grew up in Ruby, perhaps the most aggressive object oriented languages that is still heavily used ("everything is an object" and there are only methods on object, no standalone function declarations), I believe that the flexibility of the traits system solves significant, real-world problems in other object-oriented systems (indeed, Ruby introduced refinements to solve many of these issues).


So is Rust Object Oriented?

It depends what you mean 😄

Rust has a number of features (like method syntax with special semantics) that can only be explained in terms of object orientation.

However, Rust takes a non-traditional (and initially minimal) view towards inheritance that takes some getting used to. There are ongoing efforts to beef up the trait-oriented story of inheritance, some of which have landed since 1.0, and many of which are still active or ongoing.

Even once the full gamut of trait-improvement features land, you will still need to learn and grok the Rust view of object orientation, which is far more trait-focused than other object oriented languages you might be used to.

While object orientation, today, has converged on a particular set of patterns, early object oriented pioneers did a number of explorations with characteristics similar to Rust's traits: flavors ("Flavors: A non-hierarchical approach to object-oriented programming", wikipedia) and mixins ("Mixin-based Inheritance"). These ideas were important in CLOS (the common-lisp object system), and famously adapted in Ruby. More recently, Ruby has evolved to mixins with scoped imports, similar to Rust traits.

As a big believer in the utility of object oriented patterns when appropriate, I'm excited about the fact that recent languages are exploring the space of available options for improving object orientation, and am optimistic about Rust's ability, in both the medium term (with specialization) and long term (by finally providing a whole solution for the original "efficient code reuse" problem), to iterate towards something very nice.

In terms of what we should write, I think we should take some inspiration from Scala's language on this topic, with a heavy emphasis on how important traits are in modelling many patterns people are used to.

@oblitum
Copy link

oblitum commented Aug 10, 2016

I consider the points in this old blog post interesting regarding this aspect of Rust not being OO... because it states the contrary, using GoF references:

I think the main issue here is constructing an affirmation (it is or it's not) over loosely defined terms (OO, FP, etc).

@oblitum
Copy link

oblitum commented Aug 10, 2016

Maybe the position of not negating its influences is a better one. Influences, hence not definitely siding over paradigms, which are generally loosely defined.

@nrc
Copy link
Member

nrc commented Aug 10, 2016

Yes.

For me the key point about OO is that we consider data and behaviour to be strongly linked. That is clearly the case in Rust.

Whilst the definition of OO is loose, I think it is extremely rare for anyone knowledgeable to subscribe to the 'old' view of OO being defined by classes and inheritance. It is hard, for example, to find anyone to argue that (pre-ES6) Javascript (or Self) is not OO. By any 'modern' interpretation of OO, Rust qualifies.

Another way to think of whether a language is OO is to focus on the "oriented" part of the name - how do we think about designing a Rust program? I think that for most Rust programmers, the primary design element (abstraction mechanism) is data-based (or data + behaviour), rather than in terms of functions or any other building block.

It might well be worth contrasting Rust's OO with Java/C++'s OO, especially when talking about design patterns, etc. We could explicitly use "class-based OO" to differentiate that common model from the broader concept.

@JinShil
Copy link
Author

JinShil commented Aug 10, 2016

I nominate @wycats to rewrite this part of the FAQ. I'd be happy with a near cut-and-paste of his comment

@JinShil
Copy link
Author

JinShil commented Aug 13, 2016

The FAQ, as it currently exists is inconsistent, with one question saying explicitly "Rust is not object-oriented" while commenters in this PR seem to believe it is. So Rust needs to get its story straight.

As a student of Rust, I'm not qualified to write a complete answer, so I'm closing this for now. Issue 476 at least documents the problem.

@JinShil JinShil closed this Aug 13, 2016
@scottmcm
Copy link
Member

For anyone who happens to land here in the future, the book now has an entire chapter about this: https://doc.rust-lang.org/book/second-edition/ch17-00-oop.html

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants