% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/trait.R
\name{new_trait}
\alias{new_trait}
\alias{trait_method}
\title{Build a Rust-like explicit trait on top of S7}
\usage{
new_trait(
  name,
  methods = list(),
  parents = list(),
  assoc_types = character(),
  assoc_consts = list(),
  package = NULL
)

trait_method(
  generic,
  default = NULL,
  name = NULL,
  args = list(),
  returns = S7::class_any
)
}
\arguments{
\item{name}{For \code{new_trait()}, the trait name. For \code{trait_method()}, the
method name; it defaults to the generic name when omitted.}

\item{methods}{For \code{new_trait()}, a named list of S7 generics or
\code{trait_method()} objects.}

\item{parents}{Optional trait or list of supertraits.}

\item{assoc_types}{Required associated type names, or a named list of default
associated type values.}

\item{assoc_consts}{Required associated constant names, or a named list of
default constant values.}

\item{package}{Optional package name used only for display.}

\item{generic}{An S7 generic function.}

\item{default}{Optional default implementation. If supplied, \code{impl_trait()}
uses it when a class does not provide an override for that method.}

\item{args}{Optional named list of S7 classes, interfaces, or traits for
runtime argument checking with \code{with()} or \verb{\%::\%}. Dispatch arguments other
than the first can use S7 classes or unions to refine multiple-dispatch
requirements.}

\item{returns}{Optional S7 class, interface, or trait for runtime return
checking with \code{with()} or \verb{\%::\%}; defaults to \code{S7::class_any}.}
}
\value{
\code{new_trait()} returns an S7 object of class \code{s7_trait}.
\code{trait_method()} returns an S7 object of class \code{s7_trait_method}.
}
\description{
\code{new_trait()} adds a nominal contract registry on top of S7 dispatch. A class
only has the trait after \code{impl_trait()} records the implementation, even if
compatible S7 methods already exist.
}
\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")
})
}
