Skip to content
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

convenient construction syntax for anonymous structs #9

Open
nikomatsakis opened this issue May 25, 2017 · 2 comments
Open

convenient construction syntax for anonymous structs #9

nikomatsakis opened this issue May 25, 2017 · 2 comments

Comments

@nikomatsakis
Copy link
Owner

This is somewhat orthogonal, but it'd be nice to be able to "construct" an instance of a trait that has all of methods defined. This would enable modeling OO-like hierarchies quite conveniently, particularly when combined with specialization.

A rough idea (using dyn to clarify trait objects):

trait Widget {
    let bounds: Rectangle;

    fn draw(&self, cx: &mut GraphicsCx);
}

trait Button: Widget {
    let text: String;
}

impl Button {
    fn new(bounds: Rectangle, text: String) -> Rc<dyn Button> {
        Rc::new(Button { bounds, text })
    }

    // Above is equivalent to:
    fn new(bounds: Rectangle, text: String) -> Rc<dyn Button> {
        struct Dummy { bounds: Rectangle, text: String }
        impl Widget for Dummy {
            let bounds = self.bounds;
        }
        impl Button for Dummy {
            let text = self.text;
        }
        Rc::new(Dummy { bounds, text })
    }
}

default impl<T: Widget> Button for T {
    fn draw(&self,  cx: &mut GraphicsCx) {
        cx.box(self.bounds);
        cx.write(self.bounds, self.text); // or whatever
    }
}

More precise rules:

  • The sugar-y syntax would be available only for traits where all methods have defaults
  • It effectively returns a impl Button, with one field per (non-defaulted) let member
@burdges
Copy link

burdges commented May 25, 2017

I like this. It's worth considering how this interacts with structural records, if they were to make a come back.

@burdges
Copy link

burdges commented May 25, 2017

As an aside, there are interesting uses for nameable structural _sub_records of a struct of another structural records, like avoiding the verbosity of the builder pattern. If we have pub struct Foo { a: A, b: B, c: C, d: D } then Foo::{b,c} could be a name for the structural record { b: B, c: C } type, so you could write

impl Foo {
    fn new_partial(..) -> Foo::{b,c} { .. {b,c} }
    pub fn new(..) -> Foo {
        ...
        Foo { a, d, ...newpartial(..) }
    }
}

Is Foo::{b,c} a good name for a type though? Other names might be Foo {b,c} or struct Foo {b,c}. And the choices might interact with this. And the Foo { a, b ..Subrecord } syntax interacts with various ides in the RFC of course.

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

No branches or pull requests

2 participants