@node define-type @section Yet Another Object System @defmac define-type (name type-parameters ...) fields ... Introduce a new type. Each field is either a symbol, or a list where the first element is a symbol, and the remaining elements are alternating keywords and values, as per @ref{Field Parameters}. All fields are optional by default, but can be made non-optional through its type parameter. The example below creates a new type called @var{type}, with a custom printer which always displays the string ``TYPE''. It has two fields, @var{x}, which must be an integer, and @var{y}, which can have any type, but gets the value ``Hello'' in none is given. @example (define-type (type #:printer (lambda (r p) (display "TYPE" p))) (x #:type integer?) (y #:default "Hello")) @end example @end defmac @subsection Type Parameters @deffn {Type Parameter} constructor (λ (primitive-constructor type-validator)) Use a custom constructor for the type. The given procedure is called with two values: @itemize @item the types primitive (and usually hidden) constructor, which takes as many arguments as there are fields, in the order given in define-type, and @item the type validator procedure, which also takes all arguments, but instead either returns an undefined value if everything is fine, or throws @code{'wrong-type-arg} otherwise. @end itemize The procedure should then return a new procedure, which will be bound as the constructor for the type. Note that default values are current disregarded with custom constructors. A custom constructor for the type above might look like @example (lambda (primitive-constructor type-check) (lambda* (#:key x y) (type-check x y) (primitive-constructor x y))) @end example @end deffn @deffn {Type Parameter} printer (λ (record port)) Use a custom printer for the type. @end deffn @subsection Field Parameters @anchor{Field Parameters} @deffn {Field Parameter} default value Value the field should get if not given. @end deffn @deffn {Field Parameter} type type-clause A type predicate that the field must obey. See @ref{type-clause} for details. @end deffn @subsection Introduced Bindings Define type introduces a number procedures. (@var{} should be replaced with whatever was given as @var{name} to define-type. @defun @var{} [kv-args ...] Type constructor. Takes key-value arguments. Where the keys are the names of the fields. @end defun @defun @var{}? x Type predicate. @end defun And for each field @var{}: @defun @var{} object [value] Accessor for the given filed. Returns the current value if called with only an object, and returns a new object with @var{field} set to @var{value} if called with two values. The updating version checks the type if #:type was given on creation. @end defun