Core
Object → Object
The "root" of everything. Everything delegates to Object
, including toplevel objects.
Generally, to create new objects you send clone
to this if there's nothing more specific.
p := e → @ok
Defines e
to be evaluated when the message described by p
is dispatched to any of its targets. Returns @ok
. See definition-syntax.
When defining a method of the same name as an existing one, it will be inserted with the most precise first. If two patterns are equivalent, the new method replaces the old.
Example:
> 0 fib := 1 @ok > 1 fib := 1 @ok > (n: Integer) fib := (n - 2) fib + (n - 1) fib @ok > 5 fib 8
This defines three fib
methods on Integer
. The order of the definitions doesn't matter; they are inserted in order of precision, so the methods that pattern-match on 0
and 1
are always chosen over the more general Integer
match.
The method's expression e
is evaluated with a new toplevel object containing the bindings from the pattern-match as methods, and delegating to the context of the method definition.
Example:
> x foo: [y, z] bar: _ := this @ok > 1 foo: [2, $3] bar: 4 <object (delegates to 1 object)> x := 1 y := 2 z := $3 > a = 2 2 > foo := [1, a] @ok > foo 10 > { a = 3; foo } call 10
Here we're using this
to simply return the toplevel object that the expression is evaluated in.
p = v → v
Pattern-match p
on v
, inserting the bindings from the match into the current scope. Returns the value it's matching on (v
). See pattern-syntax.
Example:
> a = 1 1 > [x, y] = [2, 3] [2, 3] > @(ok: foo) = @(ok: 4) @(ok: 4) > [a, x, y, foo] [1, 2, 3, 10]
In addition to simple pattern-matching, =
can also define methods. However, it always evaluates the right-hand side before insertion, and roles in a message pattern are all objects (not patterns), unlike its brethren :=
.
x set!: y → y
A macro for set!:to:
; updates a slot to a given value. Will not add a new slot, as =
would in nested scopes, and panics if the slot isn't found.
x set!: name to: value → value | name is-a?: String
Update slot name
on x
to value
, searching for where the slot is defined (following delegates) to ensure it is updated rather than overridden. If the slot is not found, it panics.
o copy → any
Copies object o
, creating a new object with the same methods and delegates.
o new → is-a?: o
Generally, this initializes a new clone of o
, which will usually be the base object (e.g. Regexp
itself). The initialization typically uses clone
and sets up some state.
This is not defined for Object
; it (or some variation) should be defined for any object's initialization rather than overriding clone
.
Other conventions are new:
and new.foo: _ bar: _
, with any additional optionals.
x delegating-to: y → @ok
Yields a new object with x
's method table and y
affixed to its delegates list.
x with-delegates: ds → @ok | ds is-a?: List
Yields a new object with x
's method table and ds
as its delegates list.
x delegates-to?: y → Boolean
Returns True
if x
delegates to y
.
Example:
> X = Object clone <object (delegates to 1 object)> > Y = Object clone <object (delegates to 1 object)> > Y delegates-to?: X False > Y (delegating-to: X) delegates-to?: X True
x delegates → List
Returns a list of x
's delegates.
Example:
> x = 1 clone <object (delegates to 1 object)> > x delegates [1] > x (delegating-to: 2) delegates [1, 2]
x super → any
Returns the first value that x
delegates to.
Example:
> 1 clone super 1 > 1 clone (delegating-to: 2) super 1
x responds-to?: p → Boolean | p is-a?: Particle
Check if object x
would respond to the partial message p
.
The particle can have any number of roles missing; the first slot is filled and a "partial match" is done. That is, when searching for a method, only the filled-in roles are matched with; empty slots are a match for any role in a method's message pattern.
Example:
> X = Object clone <object (delegates to 1 object)> > X responds-to?: @foo False > X foo = 42 42 > X responds-to?: @foo True > 1 responds-to?: @+ True > 1 responds-to?: @(+ 2) False > 1 responds-to?: @(+ "foo") False
x has-slot?: name → Boolean | name is-a?: String
Check if object x
directly (that is, not through delegates) contains a slot called name
.
Implies x replies-to?: (Particle new: name)
.
Example:
> x = Object clone <object (delegates to 1 object)> > x a = 1 1 > x has-slot?: "a" True > x clone has-slot?: "a" False
x show → String
Convert x
to a proper representation of that value in code (if possible).
top load: filename → @ok | filename is-a?: String
Executes the file filename
with top
as its top scope.
top require: filename → @ok | filename is-a?: String
Like load:
, but loaded files are remembered (by their canonicalized, absolute path), so subsequent attempts to require them will be a no-op, returning @ok
.
v match: branches → any | branches is-a?: Block
Pattern-match v
on the patterns described by branches
, evaluating the first branch that matches the value.
Errors with @(no-match-for: v)
if none of the branches match the value.
v case-of: branches → any | branches is-a?: Block
Similar to match:
, but performs some case-specific matching via matches?:
. For example, a Range
matches if a value is within the range, and a Regexp
test will perform the match on the string.
Using _
as the test acts as a catch-all.
Yields @ok
if none of the branches match the value.