x-lang

← Index

x/type/class

Object-oriented class system: classes-as-values, message passing, single inheritance.

Instances: (obj name args…) – method wins, else field (obj m)/(obj m v).

Classes are callable: (Class name args…) – static method, (Class new …) to

instantiate, else static field (Class m)/(Class m v). Use classes as

namespaces of static methods. Raw field access in methods: (field ‘m)/(set-field! ‘m v).

class-call-handler / bind-call-over! are the PUBLIC value-call extension hooks

(the % marks handler-layer machinery, not module privacy): (bind-call-over! (Type of v) Class)

routes a value’s symbol-selector calls to the class’s statics, subject-LAST.

Accessors (internal plumbing)

Flat dispatch tables (the hot path)

Did-you-mean: near-match selectors for a failed dispatch

Member lookup (walks the single-inheritance parent chain)

Dispatch handlers

method-of

Resolve a static method to a bare closure for hot-loop direct calls.

The sanctioned de-dispatch door: resolve once, call directly in the hot

loop with the class as argument 0 – ((method-of C ‘step) C cur v).

Do NOT (wrap …) the handle; a stored method already evaluates its

args exactly once at direct call.

Parameters:

Returns: CALLABLE — The resolved static method closure, or nil

Examples:

(do (def-class Twice () (static (method of (self n) (* 2 n)))) ((method-of Twice 'of) Twice 4)) => 8

See also: method-ref

class-call-handler

Make the call handler that gives a type’s values method dispatch: (value selector args…) calls the class’s static method, subject-last, and any other call form is echoed as data.

Parameters:

Returns: CALLABLE — An operative for the type’s call slot, installed with Type push-call

bind-call-over!

Install method dispatch to a class over a type’s existing call handler: a symbol selector reaches the class’s static method, and anything else falls through to what the type’s call slot did before.

Parameters:

Returns: ANY — What the type’s push-call answers

Write handlers

Inheritance

super

Invoke the parent class’s version of a method.

Selector is literal: (super self method args…). Instance methods only.

Resolves from the parent of the method’s DEFINING class, so it is correct

through multi-level inheritance.

See also: def-class

method-ref

Make a class/instance method usable as a first-class function value.

Selector is literal: (method-ref Class method). Works for static and instance methods.

Examples:

(List map (method-ref Str upcase) (list "a" "b")) => ("A" "B")

See also: def-class

Predicates and introspection

object?

Test whether a value is an object instance.

Parameters:

Returns: BOOL — True if x is an object instance

Examples:

(do (def-class P () x) (object? (new P x 1))) => #t
(object? 5) => #f

See also: class?

class?

Test whether a value is a class.

Parameters:

Returns: BOOL — True if x is a class

Examples:

(class? List) => #t
(do (def-class P () x) (class? (new P x 1))) => #f

See also: object?

class-of

Return the class an instance belongs to (itself a callable class value).

Parameters:

Returns: CLASS — The class an instance belongs to

Examples:

(do (def-class P () x) (same? (class-of (new P x 1)) P)) => #t

See also: class-name

class-name

Return the name symbol of a class, or of an instance’s class.

Parameters:

Returns: SYMBOL — The class name

Examples:

(class-name List) => 'List
(do (def-class P () x) (class-name (new P x 1))) => 'P

See also: class-of

class-parent

Return a class’s parent class (the one it extends), or nil if it has none.

Parameters:

Returns: CLASS — The parent class, or nil for a root class

Examples:

(do (def-class Pet ()) (def-class Cat (extends Pet)) (class-name (class-parent Cat))) => 'Pet
(null? (class-parent List)) => #t

See also: class-name

instance-of?

Test whether an instance belongs to a class or any of its descendants.

Parameters:

Returns: BOOL — True if inst is a class or one of its subclasses

Examples:

(do (def-class Pet ()) (def-class Cat (extends Pet)) (instance-of? (new Cat) Pet)) => #t
(do (def-class Pet ()) (def-class Cat (extends Pet)) (instance-of? (new Pet) Cat)) => #f

See also: object?

Introspection – field/method names (own, not inherited), used by help

class-fields

List a class’s own instance field names (not inherited).

Parameters:

Returns: LIST — This class’s own instance-field names

Examples:

(do (def-class P () x y) (class-fields P)) => ('x 'y)

See also: class-methods

class-methods

List a class’s own instance method names (not inherited).

Parameters:

Returns: LIST — This class’s own instance-method names

Examples:

(do (def-class C () (method get (self) 1) (static (method make-one (self) 2))) (class-methods C)) => ('get)

See also: class-fields

class-static-fields

List a class’s own static field names (not inherited).

Parameters:

Returns: LIST — This class’s own static-field names

Examples:

(do (def-class C () x (static (n 7))) (class-static-fields C)) => ('n)

See also: class-static-methods

class-static-methods

List a class’s own static method names (not inherited).

Parameters:

Returns: LIST — This class’s own static-method names

Examples:

(do (def-class C () (method get (self) 1) (static (method make-one (self) 2))) (class-static-methods C)) => ('make-one)

See also: class-static-fields

class-static-ref

Look up a class’s static method by name, through the parent chain, as the value it was defined as.

Parameters:

Returns: CALLABLE — The static method as defined – a procedure or an operative – or nil, also for a C that is not a class

Examples:

(do (def-class Pet () (static (method kind (self) 'pet))) (def-class Cat (extends Pet)) ((class-static-ref Cat 'kind) Cat)) => 'pet
(null? (class-static-ref List 'no-such-method)) => #t

See also: method-ref

Class definition

def-class

Define a class (a callable class value) with fields, methods, and statics.

Names are literal (no quotes). Body forms (fields and methods intermixed):

NAME (NAME default) instance field (default optional, nil if omitted;
                                       evaluated per construction, so (links (Set make)) is fresh each time)

(doc DECL “desc” meta..) document a field; DECL is NAME or (NAME default)

(method NAME (self . args) body…) instance method

(static FIELD… (method …)…) static fields + static methods

(interface NAME…) abstract: a concrete subclass must implement each NAME

(private DECL…) (protected DECL…) visibility blocks (fields and methods; also inside (static …)):
                                       private = defining class's methods only; protected = its chain.
                                       Enforced at the dispatch door; introspection and (help) still list them.

(doc “summary” (note ..) (see ..) (example ..)) class-level docs, shown by (help Class)

A method shadows a field of the same name. Parent: () or (extends Class).

Inside a method, (self m) accesses fields; (field ‘m)/(set-field! ‘m v) are raw.

A (method %init (self) …) runs after every construction, fields built –

the initialize hook; a child’s override wins, (super self %init) chains.

Examples:

(do (def-class C () (static (n 7) (method get (self) (self n)))) (C get)) => 7

See also: new

new

Construct an instance inline; names literal, values evaluated.

Inline construction: field names are literal (bare, not quoted) and

values are expressions, evaluated in the caller’s env:

(new C name val name val …) plist form – the usual one

(new C (name . val) …) dotted-alist form (val is an expression)

(new C v1 v2 … name val …) positional prefix: values fill fields in

constructor order (root ancestor's fields first, then each subclass's own),
until the first bare declared-field name starts the keyword tail.

A TRAILING bare field name is positional ((new Distances root) passes the root

variable); the footgun: a NON-trailing positional value spelled as a bare field

name (or a call headed by one) reads as the keyword tail – use keywords there.

For a computed/quoted store (a list of ready values) use new-from.

Examples:

(do (def-class P () x) ((new P x 5) x)) => 5

See also: new-from

new-from

Instantiate a class from a computed option store (alist or plist) of values.

Data counterpart to new: the store is evaluated (new-from is a fn) and its

values are used as-is, not re-evaluated – so pass a quoted list, a variable,

or a built alist/plist. Unknown keys fall back to declared defaults.

Parameters:

Examples:

(do (def-class P () x y) ((new-from P '(x 1 y 2)) x)) => 1

See also: new