New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficient code reuse #349

Open
nrc opened this Issue Oct 3, 2014 · 9 comments

Comments

Projects
None yet
9 participants
@nrc
Member

nrc commented Oct 3, 2014

Motivation

Data structures which closely fit a single inheritance model can be very efficiently implemented in C++. Where high performance (both space and time) is crucial there is distinct disadvantage in using Rust for programs which widely use such data structures. A pressing example is the DOM in Servo. For a small example in C++, see https://gist.github.com/jdm/9900569. We require some solution which satisfies the following requirements:

  • cheap field access from internal methods;
  • cheap dynamic dispatch of methods;
  • cheap downcasting;
  • thin pointers;
  • sharing of fields and methods between definitions;
  • safe, i.e., doesn't require a bunch of transmutes or other unsafe code to be usable;
  • syntactically lightweight or implicit upcasting;
  • calling functions through smartpointers, e.g. fn foo(JSRef<T>, ...);
  • static dispatch of methods.

Status

There has been discussion of potential solutions on discuss (http://discuss.rust-lang.org/t/summary-of-efficient-inheritance-rfcs/494) and in several meetings (minutes and minutes).

We clarified the requirements listed above (see the minutes for details) and established that an ergonomic solution is required. That is, we explicitly don't want to discourage programmers from using this feature by having an unfriendly syntax. We also summarised and evaluated the various proposals (again, see the minutes for details). We feel that no proposal 'as is' is totally satisfactory and that there is a bunch of work to do to get a good solution. We established a timeline (see below) for design and implementation. We would like to reserve a few keywords to reduce the backwards compatibility hazard (#342).

Plan

In December the Rust and Servo teams will all be in one place and we intend to make decisions on how to provide an efficient code reuse solution and plan the implementation in detail. We'll take into account the discussions on the various RFC and discuss comment threads and of course all the community members who attend the Rust weekly meetings will be invited. We will take and publish minutes. This will lead to a new RFC. We expect implementation work to start post-1.0. If we identify backwards compatibility hazards, then we'll aim to address these before the 1.0 RC.

RFC PRs

There have been numerous RFC PRs for different solutions to this problem. All of these have had useful and interesting parts and earlier RFCs have been heavily cannibalised by later ones. We believe that RFC PRs #245 and #250 are the most relevant and the eventual solution will come from these PRs and/or any ideas that emerge in the future. For a summary of some of the proposals and some discussion, see this discuss thread.

@brendanzab

This comment has been minimized.

Show comment
Hide comment
@brendanzab

brendanzab Oct 5, 2014

Member

Comment moved to discuss.

Member

brendanzab commented Oct 5, 2014

Comment moved to discuss.

@why-jay

This comment has been minimized.

Show comment
Hide comment
@why-jay

why-jay Dec 23, 2014

In December the Rust and Servo teams will all be in one place and we intend to make decisions on how to provide an efficient code reuse solution and plan the implementation in detail.

What ended up happening? :)

why-jay commented Dec 23, 2014

In December the Rust and Servo teams will all be in one place and we intend to make decisions on how to provide an efficient code reuse solution and plan the implementation in detail.

What ended up happening? :)

@huonw

This comment has been minimized.

Show comment
Hide comment
@huonw

huonw Dec 24, 2014

Member

That paragraph is unfortunately outdated: we'd actually already postponed all discussion to after 1.0 since we believe any changes/features we will add are backwards compatible and there's a lot of more urgent (I.e. backwards incompatible) work that took priority.

Member

huonw commented Dec 24, 2014

That paragraph is unfortunately outdated: we'd actually already postponed all discussion to after 1.0 since we believe any changes/features we will add are backwards compatible and there's a lot of more urgent (I.e. backwards incompatible) work that took priority.

@why-jay

This comment has been minimized.

Show comment
Hide comment
@why-jay

why-jay Dec 24, 2014

I understand. I'm excited to see what ends up being implemented.

why-jay commented Dec 24, 2014

I understand. I'm excited to see what ends up being implemented.

@breckinloggins

This comment has been minimized.

Show comment
Hide comment
@breckinloggins

breckinloggins Feb 13, 2015

One thing I love about rust is that its non-free abstractions are usually explicit. I love knowing that a struct is "just a struct". It would be nice to say that features requiring runtime and fancy "under the hood" data representation support (for some value of fancy) are built from pluggable, orthogonal components.

So how about something like "anonymous composition is inheritance"? The idea would be that

struct Node {
    // stuff
}

struct FooNode {
   Node;
   // more stuff
}

implies a specific struct layout with the requisite syntactic sugar. For simplicity let's suppose that we only allow one anonymous component per struct.

EDIT: It was pointed out to me by @steveklabnik and others that rust has had trait objects since forever. I'll keep the following bit in place and just say that std::raw::TraitObject is the kind of thing I would love to be not only "pluggable" but "leave-out-able", in the sense that if I'm writing an OS and I can't implement that yet, I can tell the compiler that it can't make me any TraitObjects and that it wouldn't be ok for me to use them right now.

For dispatch, it would be nice if we could plug-in and compose the dispatch resolution mechanism. I don't want the "doesn't play well with others" feel of C++ vtables. What if I want to back this part of the language with the Objective-C runtime? Or Glib? The current "personality" of rust feels like this should be possible, in the same way that "give me your allocator function and then I'll let you use boxed things" works.

I guess my main point is that rust is the first language in a long time where I really feel like the modern features of the language don't come with being chained to a runtime layout and functionality set that's given from up on high by the Gods of Rust.

I would love it if the rust team could implement functionality like this while still retaining that ethos.

breckinloggins commented Feb 13, 2015

One thing I love about rust is that its non-free abstractions are usually explicit. I love knowing that a struct is "just a struct". It would be nice to say that features requiring runtime and fancy "under the hood" data representation support (for some value of fancy) are built from pluggable, orthogonal components.

So how about something like "anonymous composition is inheritance"? The idea would be that

struct Node {
    // stuff
}

struct FooNode {
   Node;
   // more stuff
}

implies a specific struct layout with the requisite syntactic sugar. For simplicity let's suppose that we only allow one anonymous component per struct.

EDIT: It was pointed out to me by @steveklabnik and others that rust has had trait objects since forever. I'll keep the following bit in place and just say that std::raw::TraitObject is the kind of thing I would love to be not only "pluggable" but "leave-out-able", in the sense that if I'm writing an OS and I can't implement that yet, I can tell the compiler that it can't make me any TraitObjects and that it wouldn't be ok for me to use them right now.

For dispatch, it would be nice if we could plug-in and compose the dispatch resolution mechanism. I don't want the "doesn't play well with others" feel of C++ vtables. What if I want to back this part of the language with the Objective-C runtime? Or Glib? The current "personality" of rust feels like this should be possible, in the same way that "give me your allocator function and then I'll let you use boxed things" works.

I guess my main point is that rust is the first language in a long time where I really feel like the modern features of the language don't come with being chained to a runtime layout and functionality set that's given from up on high by the Gods of Rust.

I would love it if the rust team could implement functionality like this while still retaining that ethos.

@pcwalton

This comment has been minimized.

Show comment
Hide comment
@pcwalton

pcwalton Feb 13, 2015

Contributor

Virtual dispatch will of course be explicit under this proposal or any other.

Contributor

pcwalton commented Feb 13, 2015

Virtual dispatch will of course be explicit under this proposal or any other.

@steveklabnik

This comment has been minimized.

Show comment
Hide comment
Member

steveklabnik commented Aug 27, 2015

withoutboats pushed a commit to withoutboats/rfcs that referenced this issue Jan 15, 2017

Merge pull request #349 from Idolf/master
Replaced `list` with `iter`, since that is the function arguments' name

@jonysy jonysy referenced this issue Feb 6, 2017

Closed

Struct inheritance #12

@sighoya

This comment has been minimized.

Show comment
Hide comment
@sighoya

sighoya Mar 11, 2018

What's the state in 2018?

Couldn't we agree to any "inheritance" proposal?

sighoya commented Mar 11, 2018

What's the state in 2018?

Couldn't we agree to any "inheritance" proposal?

@blueridanus

This comment has been minimized.

Show comment
Hide comment
@blueridanus

blueridanus Apr 12, 2018

What happened to @nikomatsakis's proposal?

I'm trying to create a general UI framework for Rust, basically based on push-pull FRP. There's no way to do it, however, because there's no way to model a type hierarchy: enums don't actually "add" types together, and the nodes of enums aren't really types, only tags.

blueridanus commented Apr 12, 2018

What happened to @nikomatsakis's proposal?

I'm trying to create a general UI framework for Rust, basically based on push-pull FRP. There's no way to do it, however, because there's no way to model a type hierarchy: enums don't actually "add" types together, and the nodes of enums aren't really types, only tags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment