Usecases for inheritance


#1

Continuing the discussion from Most coveted Rust features:

Abstract base classes. The best solution I can currently come up with is using a wrapper type but this doesn’t work cross-crate (IIRC, it should eventually work cross-module):

use std::fs::File;
use std::ops::{Deref, DerefMut};
use std::io::Write;

struct AbstractTextbox<T> {
    inner: T,
    text: String
}

trait ConcreteTextbox {
    fn on_update(&mut self) { }
}

impl<T> AbstractTextbox<T> where Self: ConcreteTextbox {
    pub fn new(inner: T) -> Self {
        AbstractTextbox {
            inner: inner,
            text: String::new()
        }
    }
    pub fn append(&mut self, text: &str) {
        self.text.push_str(text);
        self.on_update();
    }
    pub fn get_text(&self) -> &str {
        &self.text
    }
}

impl<T> Deref for AbstractTextbox<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.inner
    }
}

impl<T> DerefMut for AbstractTextbox<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.inner
    }
}

pub struct PersistedTextboxData {
    file: File,
    dirty: bool
}

type PersistedTextbox = AbstractTextbox<PersistedTextboxData>;

impl PersistedTextbox {
    pub fn save(&mut self) {
        if self.dirty {
            self.dirty = false;
            self.file.set_len(0).unwrap();
            let txt = self.get_text().to_string();
            self.file.write_all(txt.as_bytes()).unwrap();
        }
    }
    pub fn new() -> PersistedTextbox {
        AbstractTextbox::new(PersistedTextboxData {
            file: File::create("/tmp/textbox.txt").unwrap(),
            dirty: false,
        })
    }

}

impl ConcreteTextbox for PersistedTextbox {
    fn on_update(&mut self) {
        self.dirty = true;
    }
}

fn main() {
    let mut t = PersistedTextbox::new();
    t.append("a");
    t.save();
}

#2

I would throw my first post in here as a use case: Comparing boxed traits (possible bug?) since I think it applies here.

I have since modeled expressions and values as enums but I think I would have preferred to go a different route.


#3

One big usecase for Rust is Servo’s DOM which really asks for a decent inheritance proposal.

I personally wonder if it’s at all possible to upgrade Enums into an inheritance scheme, and will it be worth it. Problem is inheritance plays really badly with HKT and other functional thingamajigs.


#4

I like the idea of an alternative approach to simply copy pasting in OOP into rust (which seems like what the initial servo proposal is asking for if I recall).

I have been using namedtuples + simplegeneric in python to get a similar effect and it can be quite nice despite the lack of a match syntax in python. It basically gives you an open and duck typed discriminated union. I am sure there are better sources of inspiration in actual functional programming languages though.