aboutsummaryrefslogtreecommitdiff
path: root/doc/ref/guile/util-object.texi
blob: ceac2f2a1d05bdbb032f02380aac77653da2e1f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@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{<name>} should be
replaced with whatever was given as @var{name} to define-type.

@defun @var{<name>} [kv-args ...]
Type constructor. Takes key-value arguments. Where the keys are the
names of the fields.
@end defun

@defun @var{<name>}? x
Type predicate.
@end defun

And for each field @var{<field>}:

@defun @var{<field>} 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