rune icon indicating copy to clipboard operation
rune copied to clipboard

Feature request: Traits

Open Fluffyalien1422 opened this issue 2 years ago • 3 comments
trafficstars

There are already impl blocks but no traits

Traits can be syntax sugar for regular impl blocks

trait Y {
	fn say_hi() {
		println!("Hi!");
	}
}

struct X {}
impl Y for X {}

is the same as:

struct X {}

impl X {
	fn say_hi() {
		println!("Hi!");
	}
}

Fluffyalien1422 avatar Sep 24 '23 23:09 Fluffyalien1422

I've started working on this here https://github.com/Fluffyalien1422/rune

Fluffyalien1422 avatar Sep 25 '23 00:09 Fluffyalien1422

Also see #23

Some thoughts:

Since traits and their associated methods can be defined elsewhere (e.g. other crates where they trait is defined), they can't strictly be syntactic sugar for impl blocks. So how do you propose dealing with method naming conflicts and potential disambiguation?

How would method name resolution work? In Rust, the methods of a trait are only visible implicitly if the trait is in scope, but this relies on knowing the types of values which we obviously don't in Rune.

In #23 traits are solely used to define protocols. And this could be a nice area for you to explore since we currently can't implement protocols in pure Rune.

Thanks!

udoprog avatar Sep 25 '23 15:09 udoprog

@udoprog

How would method name resolution work? In Rust, the methods of a trait are only visible implicitly if the trait is in scope, but this relies on knowing the types of values which we obviously don't in Rune.

idk how the codebase works exactly yet so idk if this will actually work but here's the idea: A trait would really only exist for compiler errors and default implementations, so it won't matter if the trait is in scope to use the methods or not because implementing a trait will be the same as just a normal impl block So

trait X {
	fn no_default_implementation();
	fn default_implementation() {
		println!("Hello, World!");
	}
}

struct Y {};
impl X for Y {
	fn no_default_implementation() {
		println!("Bye!");
	}
}

Is the same as

struct Y {};
impl Y {
	fn no_default_implementation() {
		println!("Bye!");
	}
	fn default_implementation() {
		println!("Hello, World!");
	}
}

So it wouldn't matter if the trait is in scope because the trait only exists to give compiler errors and to fill in default implementations, it will actually just end up being exactly the same as a normal impl block

Since traits and their associated methods can be defined elsewhere (e.g. other crates where they trait is defined), they can't strictly be syntactic sugar for impl blocks. So how do you propose dealing with method naming conflicts and potential disambiguation?

struct X {}
impl a::b::C for X {}

a::b::C would be resolved at compile time, if a method in the trait already exists on the struct then that would be an error

Fluffyalien1422 avatar Sep 25 '23 22:09 Fluffyalien1422

Closed in favor of #23

udoprog avatar Aug 15 '24 07:08 udoprog