Collection interfaces, comparison helpers, iteration utilities, and view slicing helpers.
Interfaces and conversions
Index exposes at and size; Iter exposes next and may expose size; View exposes iter, size, and slice, with at and index optional. next returns item valid; the item is meaningful only when valid is TRUE.
isDirtyOrDynamic
(object -- cond) Returns TRUE when either isDirty or isDynamic returns TRUE for object.- The result is a known schema-shape condition; it tests field presence, not current field values or method callability.
sizeis not required by this predicate.- The result is known and tests field presence, not method callability.
atandindexare optional for this predicate.- The result is known and tests field presence, not method callability.
schemaNameBeginsWith
(object text -- cond) Tests whether object's SCHEMA_NAME field begins with text.- An absent field returns
FALSEwithout processingtext. - Otherwise, the field and prefix must be known, non-
NILText. The field need not be static.
Known issue: with an unknown initial offset, makeTupleIter over a tuple of Ref items can return the wrong reference while valid is TRUE; keep the initial offset known for such tuples. With a stable unknown initial offset, tuples of Text or Code items are rejected at compile time; use a known initial offset for those as well.
Built-in source adaptation
Array adapters use a reference to contiguous item storage and a logical size. Tuple adapters use zero-based field ordinals. Text adapters expose UTF-8 code units as Nat8 items.
makeArrayIndex, makeArrayIter, makeArrayView, toTextIter, toTextView, makeTupleIndex, makeTupleIter and makeTupleView borrow their backing storage; keep it alive, at the same address, and large enough for the selected range while using the adapter or a reference derived from it.
Unknown bounds are checked at run time only when DEBUG is enabled; disabling DEBUG does not make out-of-bounds access valid. The size inputs of makeArrayIndex, makeArrayIter, makeArrayView, toTextIter and toTextView must be nonnegative; a negative input reports invalid size. The makeTupleIndex, makeTupleIter and makeTupleView size checks report size is out of bounds.
makeArrayIndex
(data size -- index) Constructs an Index over size contiguous items beginning at data.ataccepts a zero-based key and returns a reference to the selected item. Item references are mutable only through a mutable data reference and a mutable adapter access path.sizereturns the requested logical size.- A key outside the range produces
key is out of bounds.
Remarks
- A known size is stored as a static field; a stable unknown size remains a run-time value. If the count is read from unstable storage, pass a snapshot made with
newrather than the unstable reference.
makeArrayIter
(data size -- iter) Constructs a forward Iter over size contiguous items beginning at data.- Each successful
nextreturns the current item as a reference andTRUE, then advances the stored data reference and decrements the remaining size. Item references are mutable only through a mutable data reference and a mutable adapter access path. - After the requested items are consumed,
nextreturns an item whose value is not meaningful andFALSE. sizereturns the remaining item count.
Remarks
- A known size is carried as a known count; an unknown size is evaluated at run time.
atreturns a reference;indexanditerconstruct the corresponding array adapters over the same range. Item references are mutable only through a mutable data reference and a mutable adapter access path.slicetakesoffset sizeand returns the selected subview without changing the original view.- An invalid key, offset, or subview size reports
key is out of bounds,offset is out of bounds, orsize is out of bounds, respectively.
toTextIter
((data size) -- iter) Constructs a forward iterator from one two-field Struct containing an item reference and a count.- Supply one Struct containing
datafollowed bysize. References retaindata's item schema; an immutable data reference or access path does not become mutable. - For
Text,toIterandtoViewsupply an immutableNat8reference and a UTF-8 code-unit count. - Successful
nextreturns the current item as a reference andTRUE;sizereturns the remaining count. After exhaustion, the item is not meaningful andFALSEis returned.
toTextView
((data size) -- view) Constructs a View from one two-field Struct containing an item reference and a count.- Supply one Struct containing
datafollowed bysize. References retaindata's item schema; an immutable data reference or access path does not become mutable. - For
Text,toIterandtoViewsupply an immutableNat8reference and a UTF-8 code-unit count. - The view exposes
iter,size, andslice; its iterator returns references whose mutability follows the data reference and access path. - Slicing reports
offset is out of boundsorsize is out of boundswhen its arguments exceed the view.
Remarks
- The size must be a stable value. If the count is read from unstable storage, pass a snapshot made with
newrather than the unstable reference.
makeTupleIndex
(tuple offset size -- index) Constructs an Index over size fields beginning at tuple field offset.atadds the key to the stored offset and reads that tuple field. A non-static In-place field produces a view whose mutability follows the access path; static and Ref-like fields follow the field-read rules.- The key must satisfy
0 <= key < size; otherwise the diagnostic iskey is out of bounds. sizereturns the requested field count. The offset and size ranges must remain within the tuple; invalid arguments reportoffset is out of boundsorsize is out of bounds.
Remarks
- The size must be a stable value. If the count is read from unstable storage, pass a snapshot made with
newrather than the unstable reference. - The initial offset must be a stable value. Snapshot an offset read from unstable storage with
new, subject to the tuple-schema restrictions. - Unknown field positions require uniform field schemas. Keep positions known when selecting heterogeneous fields.
- A stable unknown initial offset is not supported for
TextorCodefields. - Known issue: with an unknown initial offset, a tuple of Ref fields can select the wrong reference. Keep the initial offset known for such tuples.
makeTupleIter
(tuple offset size -- iter) Constructs a forward iterator over size tuple fields beginning at offset.nextvisits selected fields in increasing ordinal order and returnsitem valid; the item is meaningful only whilevalidisTRUE.- Before exhaustion,
sizegives the remaining selected-field count. - The offset and size ranges must stay within the tuple; failures report
offset is out of boundsorsize is out of bounds.
Known issue: an unsuccessful next can advance beyond the selected range and make size negative; do not use size after FALSE.
Remarks
- With a known offset, a non-static In-place field produces a view whose mutability follows the access path; static and Ref-like fields follow the field-read rules. Unknown field positions require uniform field schemas; keep positions known when selecting heterogeneous fields.
- A stable unknown initial offset is not supported for
TextorCodefields. Keep the initial offset known for those as well. - See the known-issue note above before using an unknown offset with tuple
Ref,Text, orCodefields.
makeTupleView
(tuple offset size -- view) Constructs a view over size tuple fields beginning at offset.atreadsoffset + key; a non-static In-place field produces a view whose mutability follows the access path, while static and Ref-like fields follow the field-read rules.indexanditeradapt the same selected range.- The key must satisfy
0 <= key < size; otherwise the diagnostic iskey is out of bounds. slicereturns a nested tuple view relative to the current view.- The offset and size ranges must stay within the tuple; invalid arguments report
offset is out of boundsorsize is out of bounds.
Remarks
- The size must be a stable value. If the count is read from unstable storage, pass a snapshot made with
newrather than the unstable reference. - The initial offset must be a stable value. Snapshot an offset read from unstable storage with
new, subject to the tuple-schema restrictions. - Unknown field positions require uniform field schemas. Keep positions known when selecting heterogeneous fields.
- A stable unknown initial offset is not supported for
TextorCodefields. - Known issue: with an unknown initial offset, a tuple of Ref fields can select the wrong reference. Keep the initial offset known for such tuples.
toIndex
(source -- index) Converts a built-in tuple, an Index, or an object exposing index to an Index.- Built-in tuple adaptation takes precedence, followed by a direct
Index, then theindexmethod. - A built-in tuple becomes a zero-based tuple index. For a direct
Index,newis used when there is noDIEfield; otherwise the supplied object is used directly. An object with anindexfield uses that field. - Unsupported input raises the compile-time message
Built-in tuple, Index, or Indexable expected. - Built-in tuple adaptation borrows the tuple's storage. Keep it alive, at the same address, and large enough for the selected range while using the adapter or its derived references. Do not assume that other conversion results are borrowed; follow the source type's ownership contract.
toIter
(source -- iter) Converts built-in text, built-in tuples, direct Iter values, or objects exposing iter to an Iter.Textand built-in tuple adaptation take precedence, followed by a directIter, then theitermethod.Textis adapted as an immutable UTF-8 code-unit iterator; a built-in tuple becomes a tuple iterator.- For a direct
Iter, an immutable view usesnewwhen copyable, and a mutable view usesnewwhen movable. Otherwise, the supplied iterator is used directly. An object with aniterfield uses that field. - Unsupported input raises the compile-time message
Built-in text, tuple, Iter, or Iterable expected. - Built-in Text and tuple adaptation borrows the backing storage. Keep it alive, at the same address, and large enough for the selected range while using the adapter or its derived references. Do not assume that other conversion results are borrowed; follow the source type's ownership contract.
- Built-in text and tuple adaptation take precedence, followed by a direct
View. Textbecomes an immutable UTF-8 code-unit view; a built-in tuple becomes a tuple view.- For a direct
View,newis used when there is noDIEfield; otherwise the supplied object is used directly. The view is accepted by itsiter/size/sliceshape; optionalatandindexare not required. - Unsupported input raises the compile-time message
Built-in tuple or View expected. - Built-in Text and tuple adaptation borrows the backing storage. Keep it alive, at the same address, and large enough for the selected range while using the adapter or its derived references. Do not assume that other conversion results are borrowed; follow the source type's ownership contract.
makeObjectIter
(object method -- iter) Constructs an object-field iterator that applies method to the object and each field ordinal.methodis a callable stored as a static field, with stack effect(object ordinal -- item). It runs through a call boundary.nextincrements from ordinal zero and returnsTRUEwhile fields remain; at the end it returns() FALSE.sizereturns the number of fields not yet visited.
- Each record's
keyis the field name andvalueis the field-read result: a view for a non-static In-place field, a value for a static field, or a copied Ref-like value. A view's mutability follows the access path. - The iterator ends with
() FALSE.
objectKeys
(object -- iter) Iterates over an object's field names in ordinal order.- Each successful item is the field-name text; the iterator ends with
() FALSEand exposes remaining field count throughsize.
objectValues
(object -- iter) Iterates over an object's field values in ordinal order.- A non-static In-place field produces a view whose mutability follows the access path; a static field produces a value. Ref-like fields are copied according to the field-read rules.
- The iterator ends with
() FALSEand exposes remaining field count throughsize.
Matching and branching
<
(left right -- cond) Reports whether left is less than right, including lexicographic comparison of supported iteration sources.- The collection overload requires each operand to be
Textor a Struct withoutlessorgreaterfields. Both operands must also be accepted bytoIter. Alessorgreaterfield on either operand excludes this overload, even if it is not applicable on that side. - The control adapters use
right.lessorleft.greater. - The collection overload converts both operands with
toIterand compares items in order; equal common prefixes make the shorter source less. - The result is a
Cond; unsupported item comparisons remain subject to the selected comparison overload's requirements. - Known limitation: comparing
Textwith a built-in tuple can fail to compile even when their item schemas match. For byte storage, use an array iterator rather than the tuple adapter.
=
(left right -- cond) Reports whether two supported iteration sources contain equal items in equal-length order.- The collection overload requires at least one Struct operand and no
equalfield on either operand. Both operands must be accepted bytoIter.Text-to-Textequality and objects withequaluse other overloads. - The control adapters use
right.equalorleft.equal. - The collection overload converts both operands with
toIter, compares corresponding items, and requires both sources to end together. - Different lengths or a differing item returns
FALSE; an empty source equals an empty source. - Known limitation: comparing
Textwith a built-in tuple can fail to compile even when their item schemas match. For byte storage, use an array iterator rather than the tuple adapter.
>
(left right -- cond) Reports whether left is greater than right, including lexicographic comparison of supported iteration sources.- The collection overload requires each operand to be
Textor a Struct withoutlessorgreaterfields. Both operands must also be accepted bytoIter. Alessorgreaterfield on either operand excludes this overload, even if it is not applicable on that side. - The control adapters use
right.greaterorleft.less. - The collection overload converts both operands with
toIterand compares items in order; equal common prefixes make the longer source greater. - The result is a
Condand follows the selected item-comparison overload's requirements. - Known limitation: comparing
Textwith a built-in tuple can fail to compile even when their item schemas match. For byte storage, use an array iterator rather than the tuple adapter.
case
(... value descriptors -- ...) Selects and runs the first branch whose descriptor equals value, or the final fallback branch.descriptorsis one Struct of alternating match values and actions, followed by one fallback action. Supply at least the fallback.- Matches are tested from the first pair forward.
- The selected action runs through a call boundary without an automatically supplied argument. Its stack effect determines the selector's effect on the surrounding stack. Branches controlled by an unknown condition must leave matching stack shapes.
- The fallback runs when no match is found. A descriptor Struct containing only its final branch therefore always runs that branch.
cond
(... value descriptors -- ...) Calls the first action whose predicate accepts value, or the final fallback action.descriptorsis one Struct of alternating predicates and actions, followed by one fallback action. Supply at least the fallback.- Each predicate runs through a call boundary, consumes
value, and returns oneCond; the first true result selects its following action. - The selected action runs through a call boundary without an automatically supplied argument. Its stack effect determines the selector's effect on the surrounding stack. Branches controlled by an unknown condition must leave matching stack shapes.
cond0
(... descriptors -- ...) Selects and runs the first action whose no-argument predicate is true, or an optional fallback action.descriptorsis one Struct of alternating no-argument predicates and actions, optionally followed by a fallback action.- Predicates run through call boundaries and return one
Cond; the first true result selects its following action. - The selected action runs through a call boundary without an automatically supplied argument. Its stack effect determines the selector's effect on the surrounding stack. Branches controlled by an unknown condition must leave matching stack shapes.
- With no match and no fallback, the surrounding stack is unchanged. An empty Struct does nothing.
Search result conventions
The sequence search helpers convert their operands with toIter. Ordinals are zero-based, and an exhausted item returned with FALSE is not inspected.
- An empty prefix returns
TRUE; a nonempty prefix cannot match a shorter source.
contains
(source pattern -- cond) Reports whether pattern occurs as a contiguous subsequence of source.- An empty pattern returns
TRUE; a pattern longer than the source returnsFALSE. - The pattern source must support a fresh traversal for each attempted match. Look-ahead requires an independent copy of the remaining source iterator.
- An operand without
sizemust support a finite sizing traversal of an independent iterator copy. - Known limitation: searching a tuple containing unknown values for a multi-item built-in
Tuplecan fail to compile. Use array adapters over the storage for run-time subsequence searches.
find
(source pattern -- ordinal) Returns the first zero-based ordinal where pattern begins in source.- Matching is contiguous and leftmost; an empty pattern matches at ordinal
0. - If no match exists, the result is the source size, not
-1. - The pattern source must support a fresh traversal for each attempted match. Look-ahead requires an independent copy of the remaining source iterator.
- An operand without
sizemust support a finite sizing traversal of an independent iterator copy. - Known limitation: searching a tuple containing unknown values for a multi-item built-in
Tuplecan fail to compile. Use array adapters over the storage for run-time subsequence searches.
findOneOf
(source patterns -- sourceOrdinal patternOrdinal) Finds the first source position whose remaining sequence begins with one of the candidate patterns.patternsis an iteration of pattern sources; candidates are tested in pattern ordinal order at each source position.- The candidate collection must support a fresh traversal at each source position. Each candidate check requires an independent copy of the remaining source iterator.
- An operand without
sizemust support a finite sizing traversal of an independent iterator copy. - The result contains the first matching source ordinal followed by the matching pattern ordinal.
- If no candidate matches, the result is the source size followed by
-1.
Known issue: an empty source with a nonempty collection of nonempty patterns reaches Static loop count limit (256) reached instead of returning 0 -1; handle an empty source separately.
findOrdinal
(source predicate -- ordinal) Returns the first zero-based source ordinal whose predicate returns true.- The predicate is called through a call boundary for each item and must consume the item and return a
Cond. - If no predicate match exists, the result is
-1.
findOrdinalStatic
(iter predicate ordinal -- result) Recursively searches an Iter, starting at ordinal, for the first item satisfying predicate.- Supply the initial ordinal, normally
0, after the iterator and predicate; recursion increments it after a false predicate result. - The predicate runs through a call boundary, consumes one item, and returns one
Cond. A true predicate returns the current ordinal; an exhausted iterator returns-1.
Remarks
- Recursive processing must terminate during compilation. Item values, predicate results, and the final result need not be known.
Iteration helpers
Unknown bounds are checked at run time only when DEBUG is enabled; disabling DEBUG does not make out-of-bounds access valid.
Transformers return new iterator objects. Consumers exhaust a converted source or compute an aggregate. A body called through a call boundary receives the current item as a reference; the inline static consumer does not create that call boundary.
fibonacci
(previous current -- iter) Creates an unbounded iterator that yields the current value and advances the pair by Fibonacci addition.- The first
nextreturns the suppliedcurrent; each later item is the next sum after the state advances to(current previous + current). - Each item is returned as a value copy followed by
TRUE; this iterator has nosizefield.
iota
(start -- iter) Creates an unbounded iterator that yields successive values beginning at start.- Each
nextreturns the current value, increments the internal counter by one, and returnsTRUE. - Items are value copies and the iterator has no
sizefield.
countIter
(source count -- iter) Wraps a source iterator and increments count after each successful item.- The wrapped source is converted with
toIter; its items and valid flags are forwarded unchanged. - The supplied counter is incremented only when
validisTRUE, and a mutable counter reference is updated in place. - If the source has
size, the wrapper exposes the same size.
enumerate
(source start -- iter) Wraps a source iterator and pairs each item with an increasing ordinal.- Each successful item is a Dict with
keyset to the current ordinal andvalueset to the source item; the ordinal starts atstartand increments after each valid item. - The
valuefield retains a source reference's mutability; a by-value In-place item becomes an In-place field. - If the source has
size, the wrapper exposes the same size.
filter
(source predicate -- iter) Returns an iterator containing only source items accepted by predicate.- The predicate is called through a call boundary for each candidate and must consume the item and return a
Cond. - Rejected items are skipped until an accepted item or source exhaustion; accepted references retain their mutability, and by-value items are returned by value.
- The result does not expose a
sizefield, because filtering changes the count.
- A converted source with
sizeis capped at its remaining count. Otherwise, the wrapper counts successful items. A negative size reportsinvalid size. - While items remain,
nextforwards source items and valid flags. At the limit, it supplies the end item withFALSE. - If an unsized source ends before the limit, its invalid result is forwarded without using
end. - A non-callable
endis read as the end item; a callableendhas stack effect(-- item). It is read or called on each invalid result supplied by the wrapper, not as a one-shot notification. - When validity is unknown, successful and end items must have matching schemas, including Ref versus In-place.
- The result exposes
sizeonly when the converted source does.
joinIter
(sources transform end -- iter) Zips the source iterators, unpacks each tuple of aligned items into transform, and returns the transformed results.sourcesis converted bywrapIter.transformruns through a call boundary, consumes one item per source in source order with the last source's item on top, and returns one item.- Advancement follows
wrapIter; the transform runs only for a valid tuple of items. The end provider supplies each invalid result. - A non-callable
endis read as the end item; a callableendhas stack effect(-- item). Usingendis not a one-shot notification: it is read or called on each invalid result. - When validity is unknown, successful and end items must have matching schemas, including Ref versus In-place.
- When every source exposes
size, the result size is the minimum source size.
map
(source transform end -- iter) Applies transform to each source item and returns the transformed iterator.- The source is converted with
toIter;transformis called through a call boundary with the current item, consumes that item, and returns one mapped item. Source references retain their mutability. - When the source produces an invalid result,
endsupplies the item returned withFALSE. A non-callableendis read as the end item; a callableendhas stack effect(-- item). It is read or called on each invalid result, not as a one-shot notification. - When validity is unknown, successful and end items must have matching schemas, including Ref versus In-place.
- If the source exposes
at, the result exposesatand appliestransformto selected items; if the source exposessize, the result forwards that size.
- Each source is converted with
toIter; a successfulnextreturns a tuple containing one item from every source andTRUE. - Each
nextadvances every source. The result is valid only when every source returnsTRUE; the tuple returned with a false flag is not meaningful. Longer sources also advance on an invalid call, including calls made after the firstFALSE. - When all sources expose
size,sizereturns the minimum; an empty source collection has size0.
unhead
(source size -- result) Removes a leading prefix from a source accepted as a View or direct Iter.- If
sourceis accepted bytoView, removes the prefix by slicing, even whensourcealso hasnext. This view conversion has precedence and includes built-inTextand tuple sources. - Otherwise,
sourcemust be a directIter; it consumes up tosizeitems and returns the remaining iterator. Convert other Iterable objects withtoIterfirst. - For an
Iter, a negative size reportsinvalid size; consumption stops when the source returnsFALSE. For aView, the size must be within the view and an invalid prefix reportssize is out of bounds.
allStatic
(iter predicate -- cond) Recursively tests whether every item from an Iter satisfies predicate.- Unlike
all, this entry expects anIter; usesource toIterbefore it. - The predicate runs through a call boundary, consumes one item, and returns one
Cond. Evaluation stops at the first false result; an exhausted iterator returnsTRUE.
Remarks
- Recursive processing must terminate during compilation. Item values, predicate results, and the final result need not be known.
anyStatic
(iter predicate -- cond) Recursively tests whether any item from an Iter satisfies predicate.- Unlike
any, this entry expects anIter; usesource toIterbefore it. - The predicate runs through a call boundary, consumes one item, and returns one
Cond. It stops at the first true result and returnsFALSEonly after exhaustion without a match.
Remarks
- Recursive processing must terminate during compilation. Item values, predicate results, and the final result need not be known.
count
(source -- count) Returns the number of items available from a source.- The source is converted with
toIter;bodyruns through a call boundary and must consume its item. The body may transform the surrounding stack; run-time traversal requires the same carried stack shape after the item is consumed. Known traversal may change that shape. - For non-static In-place tuple fields, the body receives a view whose mutability follows the tuple access path.
- Source traversal is resolved during compilation; item values may be known or unknown.
- The body is processed inline inside
eachStatic's call boundary, not in its caller's scope. Its locals do not escape to the caller. - For non-static In-place tuple fields, the inline body receives a view whose mutability follows the tuple access path and must leave the iterator recursion's carried stack shape intact.
eachStaticInternal
(iter body --) Processes an already converted iterator with a body inline until exhaustion; this is the low-level form that eachStatic delegates to.- Unlike
eachStatic, it expects anIterand does not calltoIter;eachStaticconverts its source before delegating. - Traversal is resolved during compilation; item values may be known or unknown.
- The body runs once for each valid item, must consume that item, and must preserve the recursion's carried stack shape; exhaustion returns no items.
interleave
(... source consume splice -- ...) Calls consume with each item and calls splice before each item after the first.- The source is converted with
toIter. An empty source calls neither body. consumeruns through a call boundary on each item.splicealso runs through a call boundary and must leave its item available to the followingconsumecall.- The callbacks may transform the surrounding stack; run-time traversal requires the combined step to preserve its carried stack shape.
meetsAll
(object predicates -- cond) Reports whether every predicate in predicates accepts one object.meetsAny
(object predicates -- cond) Reports whether at least one predicate in predicates accepts one object.- The source is converted with
toIter; each successful item is duplicated, passed totransformthrough a call boundary, and replaced with the transform result throughset. transformconsumes one item and returns one replacement.- A tuple
(1 2 3)transformed by[item:; item 1 +]becomes(2 3 4).
View slicing
Unknown bounds are checked at run time only when DEBUG is enabled; disabling DEBUG does not make out-of-bounds access valid.
Each slicer first converts its source with toView. Offsets are zero-based; a size of zero is valid.
offsetmust be in0..view.sizeandsizemust be in0..view.size-offset.- Invalid arguments report
offset is out of boundsorsize is out of bounds; the result is produced by the source view'sslicemethod.
range
(view offset0 offset1 -- result) Returns the subview from offset0 through the exclusive endpoint offset1.offset0must be nonnegative andoffset1must lie inoffset0..view.size.- The result has offset
offset0and sizeoffset1 - offset0; failures reportoffset0 is out of boundsoroffset1 is out of bounds.
- The result is equivalent to
0 size view.slice. sizemust be in0..view.size; otherwise the failure issize is out of bounds.
- The result starts at
view.size - sizeand has sizesize. sizemust be in0..view.size; otherwise the failure issize is out of bounds.
- The result is equivalent to
0 view.size size - view.slice. sizemust be in0..view.size; otherwise the failure issize is out of bounds.
Examples
Counting and searching
"algorithm" use
"control" use
{} () {} [
(10 20 30 40) count printStack _:;
(10 20 30 40) (20 30) contains printStack _:;
(10 20 30 40) [30 =] findOrdinal printStack _:;
] "main" exportFunction
Expected Output During Compilation
4
TRUE
2
View slicing
"algorithm" use
"control" use
{} () {} [
view: "hello" toView;
view.size printStack _:;
1 3 @view.slice.size printStack _:;
] "main" exportFunction
Expected Output During Compilation
5
3
Runtime example
"String" use
"algorithm" use
"control" use
{} Int32 {} [
("count=" (10 20 30 40) count LF
"contains=" (10 20 30 40) (20 30) contains LF
"find=" (10 20 30 40) [30 =] findOrdinal LF) printList
0
] "main" exportFunction
Expected Output
count=4
contains=TRUE
find=2