Skip to content

Traits & Interfaces

A trait defines a contract—a collection of method signatures that multiple structs or enums can implement to provide polymorphic behavior.

Flame features semantic trait relationships (impl Type: Trait), strict compile-time contract enforcement, explicit default fn implementations, trait composition via and, and full generics <T> support across functions, structs, and enums.


Trait declarations specify required methods and optional default implementations:

trait Drawable {
fn draw(&self) -> String
fn area(&self) -> Float
}
trait Describable {
// Explicit default method implementation
default fn describe(&self) -> String {
return "default object description"
}
}

Semantic Implementation Syntax: impl Type: Trait

Section titled “Semantic Implementation Syntax: impl Type: Trait”

Flame uses intuitive semantic syntax impl Type: Trait (instead of verbose impl Trait for Type):

struct Circle {
radius: Float
}
// Implement multiple traits with comma separation or 'and'
impl Circle: Drawable, Describable {
fn draw(&self) -> String {
return $"Drawing circle with radius {self.radius}"
}
fn area(&self) -> Float {
return 3.14159 * self.radius * self.radius
}
// 'describe' is automatically inherited from Describable
}

Traits can be composed into combined contracts using and:

// Shape requires both Drawable and Describable contracts
trait Shape = Drawable and Describable
struct Rectangle {
width: Float,
height: Float
}
impl Rectangle: Shape {
fn draw(&self) -> String {
return $"Drawing rectangle {self.width}x{self.height}"
}
fn area(&self) -> Float {
return self.width * self.height
}
// You can override default methods
fn describe(&self) -> String {
return $"Custom Rectangle {self.width}x{self.height}"
}
}

Flame supports type parameters <T> with Rust-like ownership and borrow semantics across functions, structs, enums, and impl blocks:

// Generic struct
struct Box<T> {
value: T
}
// Generic impl block
impl<T> Box<T> {
fn unwrap(self) -> T {
return self.value
}
}
// Generic enum
enum MyOption<T> {
Some(T),
None,
}
// Generic function
fn identity<T>(x: T) -> T {
return x
}

If a struct implements a trait but omits a required method without a default, the compiler provides clear compile-time diagnostics:

error: not all trait items implemented, missing: `area`
--> src/main.fm:12:1
|
12 | impl Circle: Drawable {
| ^^^^^^^^^^^^^^^^^^^^^ missing `area` in implementation
= help: implement the missing trait method(s) for 'Drawable'