new_trait() adds a nominal contract registry on top of S7 dispatch. A class
only has the trait after impl_trait() records the implementation, even if
compatible S7 methods already exist.
Arguments
- name
For
new_trait(), the trait name. Fortrait_method(), the method name; it defaults to the generic name when omitted.- methods
For
new_trait(), a named list of S7 generics ortrait_method()objects.- parents
Optional trait or list of supertraits.
- assoc_types
Required associated type names, or a named list of default associated type values.
- assoc_consts
Required associated constant names, or a named list of default constant values.
- package
Optional package name used only for display.
- generic
An S7 generic function.
- default
Optional default implementation. If supplied,
impl_trait()uses it when a class does not provide an override for that method.- args
Optional named list of S7 classes, interfaces, or traits for runtime argument checking with
with()or%::%. Dispatch arguments other than the first can use S7 classes or unions to refine multiple-dispatch requirements.- returns
Optional S7 class, interface, or trait for runtime return checking with
with()or%::%; defaults toS7::class_any.
Value
new_trait() returns an S7 object of class s7_trait.
trait_method() returns an S7 object of class s7_trait_method.
Details
This makes default methods and associated metadata practical, but the result remains a runtime R abstraction. It does not emulate Rust's compile-time trait bounds, coherence, orphan rules, or type-checked associated types.
Examples
local({
area <- S7::new_generic("area", "x")
perimeter <- S7::new_generic("perimeter", "x")
Circle <- S7::new_class(
"Circle",
properties = list(r = S7::class_double)
)
Measurable <- new_trait(
"Measurable",
methods = list(
area = trait_method(area),
perimeter = trait_method(perimeter, default = function(x) NA_real_)
),
assoc_consts = c("UNITS")
)
impl_trait(
Measurable,
Circle,
methods = list(area = function(x) pi * x@r^2),
assoc_consts = list(UNITS = "unitless")
)
has_trait(Circle, Measurable)
trait_call(Measurable, "area", Circle(r = 2))
trait_assoc_const(Measurable, Circle, "UNITS")
})
#> [1] "unitless"