- Up - | Next >> |
The module Record
contains procedures operating on records.
Procedures that iterate over the subtrees of a record operate in ascending order as specified for Arity
.
.
{Value.'.'
+RC
+LI
X
}
returns the field X
of RC
at feature LI
.
HasFeature
{Value.hasFeature
+RC
+LI
?B
}
tests whether RC
has feature LI
.
CondSelect
{Value.condSelect
+RC
+LI
X
Y
}
returns the field of RC
at feature LI
, if RC
has feature LI
. Otherwise, return X
.
IsRecord
{Record.is
+X
?B
}
tests whether X
is a record.
MakeRecord
{Record.make
+L
+LIs
?R
}
returns a new record with label L
, features LIs
, and fresh variables at every field. All elements of LIs
must be pairwise distinct, else an error exception is raised.
For example, {MakeRecord L A R}
waits until L
is bound to a literal, say b
, and A
is bound to a list of literals and integers, say [c d 1]
, and then binds R
to b(_ c: _ d: _)
.
clone
{Record.clone
+R1
?R2
}
returns a record R2
with the same label and features as R1
and fresh variables at every field.
Label
{Record.label
+R
?L
}
returns the label of R
in L
.
Width
{Record.width
+R
?I
}
returns the width of R
in I
.
Arity
{Record.arity
+R
?LIs
}
returns the arity LIs
of R
. The arity of R
is the list of its features, beginning with all integer features in ascending order, followed by the literal features. The atomic literals occur in ascending order interspersed with names.
For example, {Arity a(nil 7 c: 1 b: c)}
yields [1 2 b c]
as output.
Adjoin
{Record.adjoin
+R1
+R2
?R3
}
returns the result of adjoining R2
to R1
. Note that features and label in R2 take precedence over R1.
For example,
{Adjoin a(a b c: 1) b(4 b: 3 c: 2)}
yields the record b(4 b b: 3 c: 2)
as output.
AdjoinAt
{Record.adjoinAt
+R1
+LI
X
?R2
}
binds R2
to the result of adjoining the field X
to R1
at feature LI
.
For example,
{AdjoinAt a(a c: 1) 2 b}
yields a(a b c: 1)
as output, whereas
{AdjoinAt a(a c: 1) c b}
yields a(a c: b)
as output.
AdjoinList
{Record.adjoinList
+R1
+Ts
?R2
}
binds R2
to the result of adjoining to R1
all entries of Ts
, a finite list of pairs whose first components are literals or integers, representing features. Features further to the right overwrite features further to the left.
For example,
{AdjoinList a(b:1 c:2) [d#3 c#4 d#5]}
yields a(b: 1 c: 4 d: 5)
as output.
subtract
{Record.subtract
+R1
+LI
?R2
}
If R1
has feature LI
, returns record R1
with feature LI
removed. Otherwise, returns R1
.
subtractList
{Record.subtractList
+R1
+LIs
?R2
}
Returns record R1
with all features in LIs
removed.
For example,
{Record.subtractList f(jim: 1 jack: 2 jesse: 4) [jesse jim]}
returns the record f(jack: 2)
.
zip
{Record.zip
+R1
+R2
+P
?R3
}
Given two records R1
and R2
and a ternary procedure P
, R3
is bound to a record with the same label as R1
and those features which are common to R1
and R2
. Features appearing only in one of the records are silently dropped. Each fields X
of R3
is computed by applying {
P
R1
.
X
R2
.
X
R3
.
X
}
.
For example,
{Record.zip
f(jim: 1 jack: 2 jesse: 4)
g(jim: a jack: b joe: c)
fun {$ X Y} X#Y end}
yields as output the record f(jim: 1#a jack: 2#b)
.
toList
{Record.toList
+R
?Xs
}
binds Xs
to list of all fields of R
in the order as given by Arity
(which see).
For example,
{Record.toList f(a a: 2 b: 3)}
yields [a 2 3]
as output.
toListInd
{Record.toListInd
+R
?Ts
}
binds Ts
to the property list that contains the feature-field pairs of R
in the order as given by Arity
(which see).
For example,
{Record.toListInd f(a a: 2 b: 3)}
yields [1#a a#2 b#3]
as output.
toDictionary
{Record.toDictionary
+R
?Dictionary
}
returns a dictionary Dictionary
whose keys and their entries correspond to the features and their fields of R
.
All of the following procedures are provided in two versions. The so-called index version passes to the procedures an additional index as first actual argument. The index is an integer or a literal giving the feature of the field currently processed.
map
{Record.map
+R1
+P
?R2
}
returns a record with same label and arity as R1
, whose fields are computed by applying the binary procedure P
to all fields of R1
.
For example,
{Record.map a(12 b: 13 c: 1) IntToFloat}
yields the record a(12.0 b: 13.0 c: 1.0)
as output.
mapInd
{Record.mapInd
+R1
+P
?R2
}
is similar to Record.map
, but the ternary procedure P
is applied with the index as first actual argument.
For example,
{Record.mapInd a(1: d 3: a f: e) fun {$ I A} A(I) end}
yields the record a(1: d(1) 3: a(3) f: e(f))
as output.
foldL
{Record.foldL
+R
+P
X
?Y
}
foldR
{Record.foldR
+R
+P
X
?Y
}
Used for folding the fields of R
by applying the ternary procedure P
.
Suppose that R
has the arity [
F1
...
Fn
]
. Applying the left folding procedure {Record.foldL
R
P
Z
Out
}
reduces to
{
P
...
{
P
{
P
Z
R
.
F1
}
R
.
F2
...
R
.
Fn
Out
}
The first actual argument of P
is the accumulator in which the result of the previous application or the start value Z
is passed. The second actual argument is a field of R
.
Besides the left folding procedure there exists a right folding variant. The application {Record.foldR
R
P
Z
Out
}
reduces to
{
P
R
.
F1
{
P
R
.
F2
...
{
P
R
.
Fn
Z
}
...
Out
}
The first actual argument of P
is a field of R
; the second actual argument is the accumulator in which the result of the previous application or the start value Z
is passed.
For example,
{Record.foldL a(3 a: 7 b: 4) fun {$ Xr X} X|Xr end nil}
yields the output [4 7 3]
, whereas
{Record.foldR a(3 a: 7 b: 4) fun {$ X Xr} X|Xr end nil}
yields the output [3 7 4]
.
foldLInd
{Record.foldLInd
+R
+P
X
?Y
}
foldRInd
{Record.foldRInd
+R
+P
X
?Y
}
are similar to Record.foldL
and Record.foldR
, but the 4-ary procedure P
is applied with the current index as first actual argument.
forAll
{Record.forAll
+R
+PO
}
applies the unary procedure or object PO
to each field of R
.
Suppose that the arity of R
is [
F1
...
Fn
]
. The application {Record.forAll
R
P
}
reduces to the sequence of statements
{
P
R
.
F1
}
...{
P
R
.
Fn
}
For example,
{Record.forAll O1#O2#O3 proc {$ O} {O do()} end}
sends the message do()
to the objects O1
, O2
, and O3
.
forAllInd
{Record.forAllInd
+R
+P
}
is similar to Record.forAll
, but the binary procedure P
is applied with the current index as first actual argument.
For example, assuming O1
, O2
, and O3
are objects,
{Record.forAllInd a(do: O1 stop: O2 run: O3)
proc {$ M O} {O M} end}
sends the message do
to the object O1
, the message stop
to O2
, and the message run
to O3
.
all
{Record.all
+R
+P
?B
}
some
{Record.some
+R
+P
?B
}
tests whether the unary boolean function P
yields true
when applied to all fields resp. some field of R
. Stops at the first field for which P
yields false
resp. true
. The fields are tested in the order given by Arity
(which see).
allInd
{Record.allInd
+R
+P
?B
}
someInd
{Record.someInd
+R
+P
?B
}
is similar to Record.all
resp. Record.some
, but the binary boolean function P
is applied with the current index as first actual argument.
filter
{Record.filter
+R1
+P
?R2
}
partition
{Record.partition
+R1
+P
?R2
?R3
}
Record.filter
computes a record R2
which contains all the features and fields of the record R1
for which the unary boolean procedure P
applied to the field yields true
. Record.partition
works similarly, but returns in R3
a record with all remaining fields of R1
.
For example, the application
{Record.partition a(1 4 7 a: 3 b: 6 c: 5) IsOdd ?R2 ?R3}
returns a(1: 1 3: 7 a: 3 c: 5)
in R2
and a(2: 4 b: 6)
in R3
.
filterInd
{Record.filterInd
+R1
+P
?R2
}
partitionInd
{Record.partitionInd
+R1
+P
?R2
?R3
}
are similar to Record.filter
and Record.partition
, but the binary boolean function P
is applied with the current index as first actual argument.
takeWhile
{Record.takeWhile
+R1
+P
?R2
}
dropWhile
{Record.dropWhile
+R1
+P
?R3
}
takeDropWhile
{Record.takeDropWhile
+R2
+P
?R2
?R3
}
While Record.filter
selects all fields and features of a record which satisfy a certain condition, the procedure Record.takeWhile
selects only the starting sequence of features and fields which fulfill this condition. The procedure Record.dropWhile
is dual: It computes a record with the remaining features and fields. Record.takeWhileDrop
computes both records.
For example,
{Record.takeWhile a(1 4 7 a: 3 b: 6 c: 5) IsOdd}
yields as output a(1)
, whereas
{Record.dropWhile a(1 4 7 a: 3 b: 6 c: 5) IsOdd}
yields a(2: 4 3: 7 a: 3 b: 6 c: 5)
as output. Both records can be computed simultaneously by
{Record.takeDropWhile a(1 4 7 a: 3 b: 6 c: 5) IsOdd ?R2 ?R3}
takeWhileInd
{Record.takeWhileInd
+R1
+P
?R2
}
dropWhileInd
{Record.dropWhileInd
+R1
+P
?R3
}
takeDropWhileInd
{Record.takeDropWhileInd
+R1
+P
?R2
?R3
}
are similar to Record.takeWhile
, Record.dropWhile
and Record.takeDropWhile
but the binary boolean function P
is applied with the current index as first actual argument.
waitOr
{Record.waitOr
+R
?LI
}
blocks until at least one field of +R
is determined. Returns the feature LI
of a determined field. Raises an exception if R
is not a proper record, that is, if R
is a literal.
For example,
{Record.waitOr a(_ b: 1)}
returns b
while
{Record.waitOr a(2 b: _)}
returns 1
, and
{Record.waitOr a(_ b: _)}
blocks.
- Up - | Next >> |