[REBOL] Re: Series Index Discussion (Was: Core 2.5.5. Beta)
From: lmecir:mbox:vol:cz at: 26-Feb-2003 17:42
Thanks, Carl,
I am trying to summarize the proposals before I send them to the feedback. My goal was
to find a formulation, that will be as close to the existing functions as possible, while
yielding maximum of useful informations (hoping, that Volker and Gregg would be satisfied,
I am not sure about Joel and Gabriele, though).
1) A variant of the INDEX? function
==========================
A) The name of the function
-----------------------------
Two variants compatible with Rebol naming philosophy as I see it are:
i) Introduce a new /ALL refinement to the INDEX? function, (similarly as for the MOLD/ALL).
Usage:
index?/all :series
ii) Use a new name for a new native. The INDEX-ALL? seems to be compatible with the Rebol
naming philosophy. Usage:
index-all? :series
B) Description
----------------
The INDEX-ALL? function should return an integer value for any series and for any open
port.
For closed ports it should fire the "Port not open" error.
For lists it should yield the same value as
index? :series
For open ports, blocks, lit-paths, hashes, parens, set-paths and for any-strings the
returned value shall have the following "stability" property:
index-all? :series
should yield the same value as
(insert tail :series #"1" index-all? :series)
C) A mezzanine for View 1.2.8.3.1
----------------------------------------------------
index-all?: function [
{return the series index number}
[catch]
series [series! port!]
] [orig-tail result] [
if list? :series [return index? :series]
if all [
port? :series
error? result: try [index? :series]
result: disarm result
result/id = 'not-open
] [throw make error! "Port not open"]
orig-tail: tail :series
while [error? try [result: index? :series]] [
insert insert tail :series #"1" head :series
]
clear :orig-tail
result
]
The above algorithm is not suitable for a native implementation. It is only a "work around"
working for existing "past tail" series. It cannot work for "past head" series.
2) A variant of the PICK function
=======================
A) The name of the function
-----------------------------
i) Introduce a new /ALL refinement to the PICK function, (similarly as for the MOLD/ALL).
Usage:
pick/all :series rel
ii) The new native can be called PICK-ALL. Usage:
pick-all :series rel
B) Description
---------------
For closed ports it should fire the "Port not open" error.
For open ports and series it should fire an "Out of range" error, if
(index-all? :series) + rel - 1
is either less than 1 or it exceeds
length? head :series
In any other case it should yield the following value:
pick head :series (index-all? :series) + rel - 1
C) Implementation (a mezzanine for View 1.2.8.3.1)
-----------------------------------------------------
pick-all: function [
{Returns the value at the specified position in a series.}
[catch]
series [series! port!]
rel [integer!]
] [result] [
if all [
port? :series
error? result: try [index? :series]
result: disarm result
result/id = 'not-open
] [throw make error! "Port not open"]
result: (index-all? :series) + rel - 1
if any [
result < 1
result > length? head :series
] [throw make error! "Out of range"]
pick head :series result
]
3) A variant of the AT function
=======================
A) The name
--------------
i) Introduce a new /ALL refinement to the AT function, (similarly as for the MOLD/ALL).
Usage:
at/all :series rel
ii) The new native can be called AT-ALL. Usage:
at-all :series rel
B) Description
---------------
For closed ports it should fire the "Port not open" error.
For open ports and series it should return a port/series, for which:
index-all? at-all :series rel
is equal to:
(index-all? :series) + rel - 1
if possible. I think, that e.g. for blocks this is always possible, at least for any
positive REL value. In the cases, when this isn't possible, like e.g. for lists, the
function should fire an "Out of range" error.
Regards
-L