-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Implement classes as per pcwalton's proposal #1726
Comments
classes should probably be able to declare interfaces that they implement, like |
Now that the old object system is gone, this proposal would be not only an object system redesign but an object system resurrection. :) Not that there's anything wrong with that. But it seems to me that the original motivation for Patrick's proposal is gone now, since it had to do with the limitations of the old object system. |
Grasping for metaphors, I think it more of an object-system dissection. Believe me when I say nobody's more sympathetic to the concerns of going-around-in-circles than myself. I've been going around in these circles for years and years. But object systems were an area I had more technical-familiarity with the variants of, than opinions on the correct formulation of. I tend to dislike OO and habitually write very close-to-the-data-structure procedural and functional code. So I chose an object system that was too conservative and conflated too much. This is ironic since I felt much of the virtue of the obj system you and I worked on was that it didn't conflate as much as classes tend to (say, in C++). Yet it still conflated too much:
This conservatism was based on my own areas of interest and style, and an assumption that objects would be something we "didn't lean on much", and that most objects would be "big" and "long-lived" so the conservatism wouldn't hurt too much. This was a mistake. There are too many small-to-medium cases that benefit from object-like treatments, where one or more aspects of the conservatism would bite. People wound up avoiding the object system for its costs, and getting irate. We lost contributors and users over the apparent willingness to impose systemic costs; the obj system was one of those cost centers. Costs really matter. Take a look through http://www.cs.virginia.edu/kim/publicity/pldi09tutorials/memory-efficient-java-tutorial.pdf and reflect on the numbers. Common collections -- 80% overhead! We've since split off all these conflated facets into orthogonal concepts, each of which can be used in its most-efficient form independent of the others.
So please try not to look at this as a "rip it out and put it right back in" exercise. It's nothing of the sort. The pieces being put-back-in have very different characteristics: they're orthogonal to one another, more universal, and tend to perform much better. The parts that remain to be supplied in the "new" system are:
I'm much more interested in Much of the material written in Patrick's email above is redundant or not applicable anymore, in the presence of the iface/impl work. Which is a good thing. We have ifaces that can apply to numbers and tuples and tags now. That's great. |
Coming from Ruby and passing by Go, I must say that I mostly agree with graydon. Still, some syntactic sugar for "class" (without subtyping) might be sweet, and might help people coming from other languages adjust. |
@catamorphism I see you've started adding code for this. I don't think there is any up-to-date proposal related to classes. Please open a mailing list thread to discuss whathever it is you're implementing. |
@marijnh I'm implementing @pcwalton 's proposal from November (linked above), with no significant changes. I was gone while it was being discussed, so I was under the impression (from talking to Dave et al.) that the proposal had been accepted and it was just waiting for someone to have time to implement it. Is that not so? |
In November, there were no ifaces or impls. I thought it was agreed during last week's meeting that someone (@nmatsakis? @pcwalton?) would send a new proposal to the mailing list. |
@marijnh I think sending a new proposal makes sense. However, I wouldn't anticipate many changes from what pcwalton originally proposed: modulo a few details, the ifaces and impls we have are a subset of the original proposal---though with the (granted, very significant!) added ability to have interface bounds. Do you think substantial changes are needed? |
If people feel the original proposal still applies, that works for me. I had gotten another impression from last meeting, and still feel it'd be good to clearly define things like how a class declares which interfaces it implements, but I guess it'll fall out rather naturally. |
Maybe I was drifting off during that part of the meeting last week, as I don't remember it. In any case, I had thought that it would be pretty straightforward to just not implement the parts of the proposal that are already implemented :-) If anything comes up that requires a design discussion, I'll certainly post about it. |
Addendum to the proposal: As per in-person discussion on Tuesday, I think we have consensus to require |
Current status: Classes with only fields work (either intra-crate or inter-crate). Methods don't work yet. I also haven't implemented the change to require |
If you aren't doing this already, please try to unify the code for class methods and impl methods as much as you can, so we don't end up with yet another different kind of callable thing. |
@marijnh Yes, I'm trying to do so. |
@nikomatsakis suggested allowing class methods to have additional ty params (other than the class's ty params), and I guess I don't see why not. |
Impl/iface methods allow this, so it's needed to allow classes to implement arbitrary ifaces. There are some gotchas with properly instantiating the type parameters, but nothing problematic. |
Pushing residual state of this bug to 0.3. The quantity of classes (first-cut, rough form) is working enough to satisfy 0.2. |
Question about traits (from Boris on IRC, paraphrased by me): It seems from reading the proposal that there is no way to declare an argument as "having trait X", since traits are not types. Instead, you would have to declare an iface, which introduces virtual calls. Is there a way to write code that's boundedly-polymorphic over things that have a certain trait, while ensuring that you won't introduce any virtual calls? And if there isn't, should the proposal be extended to support that? (In C++, this can be done when all subclasses are known; our ifaces aren't closed, so we can't necessarily make calls-through-ifaces non-virtual.) |
Scala has traits http://www.scala-lang.org/node/126 |
Pending issues (that I'm working on):
|
Regarding using self as a first-class value: I think what we will eventually want is to assign self a region type. Then no special checks are needed. Also, I was wondering if maybe we should "spin off" traits---not sure if anyone is free to work on them---but I think they are urgently desired. At least by me. :) |
If someone wanted to go ahead and work on traits, that would be fine. I guess it's not that likely that any of the issues with classes I listed would block traits, but some coordination might still be necessary. |
"Is there a way to write code that's boundedly-polymorphic over things that have a certain trait, while ensuring that you won't introduce any virtual calls?" Bounded polymorphism doesn't introduce virtual calls in Rust, because of the way monomorphization works. (Assuming it works the way I think it does.) |
I'm going to consider this done and make issues for the remaining sub-problems. |
Improve `needless_borrow` lint fixes: rust-lang#5327 fixes: rust-lang#1726 fixes: rust-lang#1212 This is merging `needless_borrow` into the `dereference` pass in preparation for `explicit_auto_deref`. `explicit_auto_deref` needs to implement most of what `needless_borrow` implements in order to work. There is a minor regression here where `let x: &str = &x.deref()` will trigger `needless_borrow` without triggering `explicit_deref_methods`. Removing the redundant borrow will cause `explicit_deref_methods` to trigger. This will be fixed when `explicit_auto_deref` is implemented. changelog: Lint `needless_borrow` when a borrow is auto-derefed more than once changelog: Lint `needless_borrow` in the trailing expression of a block for a match arm
I didn't see an issue for this, so I'm making one:
https://mail.mozilla.org/pipermail/rust-dev/2011-November/000929.html
The text was updated successfully, but these errors were encountered: