aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2022-07-09 21:39:12 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2022-07-09 21:50:05 +0200
commit1ec118a27fa56f1167cab990814f88d847056da5 (patch)
tree5aeeeb2c719e56fed8e8a33091fa473b65b83cb4
parentMove type checking macros to own module. (diff)
downloadcalp-new-object-system.tar.gz
calp-new-object-system.tar.xz
Document type and object system.new-object-system
-rw-r--r--doc/ref/guile.texi2
-rw-r--r--doc/ref/guile/util-object.texi86
-rw-r--r--doc/ref/guile/util-type.texi62
3 files changed, 150 insertions, 0 deletions
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
index a6c5ebe4..58c162e1 100644
--- a/doc/ref/guile.texi
+++ b/doc/ref/guile.texi
@@ -7,6 +7,8 @@
@include guile/util.texi
@include guile/util-path.texi
@include guile/util-config.texi
+@include guile/util-type.texi
+@include guile/util-object.texi
@include guile/base64.texi
@include guile/web.texi
@include guile/vcomponent.texi
diff --git a/doc/ref/guile/util-object.texi b/doc/ref/guile/util-object.texi
new file mode 100644
index 00000000..ceac2f2a
--- /dev/null
+++ b/doc/ref/guile/util-object.texi
@@ -0,0 +1,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
diff --git a/doc/ref/guile/util-type.texi b/doc/ref/guile/util-type.texi
new file mode 100644
index 00000000..104b00b3
--- /dev/null
+++ b/doc/ref/guile/util-type.texi
@@ -0,0 +1,62 @@
+@node Type utilities
+@section Type utilities
+
+Provided by the module @code{(hnh util type)}
+
+@subsection Type Clauses
+@anchor{type-clause}
+@cindex type-clause
+
+Type clauses are an effective way of writing compound predicates
+without explicitly mentioning the variable at all steps.
+
+The simplest type predicate is a single symbol, which is directly
+called on the object:
+@example
+predicate? ⇒ (predicate? x)
+@end example
+
+Otherwise, if the predicate is a list then the variable is spliced
+into the argument list in the first position:
+@example
+(proc args ...) ⇒ (proc x args ...)
+@end example
+
+The two primitives @code{and} and @code{or} are also available, which
+both take an arbitrary number of predicates, and calls them in order,
+with Scheme's usual short-circuiting rules.
+@footnote{@code{and} and @code{or} doesn't have to be primitives, but
+we would otherwise have one hell of a namespace conflict}
+
+@defmac list-of variable type-clause
+Checks if @var{variable} is a list, and that every element satisfies type-clause.
+@end defmac
+
+@defmac pair-of variable car-type-clause cdr-type-clause
+Check if @var{variable} is a cons-pair, and that the car satisfies
+@var{car-type-clause}, and that the cdr satisfies @var{cdr-type-clause}.
+@end defmac
+
+@subsection Deffinitions
+
+@defmac build-validator-body variable type-clause
+``Entry point'' of type clauses. Inserts variable into the
+type-clause, returning something ready to be passed along the eval (or
+rather, spliced into another macro).
+
+Also used if new ``primitives'' are to be added, such as list-of.
+@end defmac
+
+@defmac typecheck variable type-clause [procedure-name=(current-procedure-name)]
+Checks @var{variable} against @var{type-clause}, and raises
+@code{'wrong-type-argument} if it fails. @var{procedure-name} is used
+as the calling procedure for @code{scm-error}.
+
+Useful at the start of procedures.
+@end defmac
+
+
+@defmac current-procedure-name
+Returns the current procedure name as a symbol, or @code{#f} if not found.
+@end defmac
+