Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Series Index Discussion (Was: Core 2.5.5. Beta)

 [1/9] from: carl:s:rebol at: 25-Feb-2003 11:31


WRT the series discussion that pops up every year on this list: 1. Typically, this discussion is between the same three people who discuss the merits of other indexing methods and theories. It's a good discussion, but most developers are too busy writing programs to care. 2. The current series index implementation is based on performance, not strict theory. Such tradeoffs are necessary in all language implementations. In other words, there are good reasons why we are not all writing code in LISP and Smalltalk today, despite the beauty of both languages, which we know well. 3. We seriously doubt (but remain open minded) that any change can make the implementation of series indexing "faster" internally (as stated in prior messages). Indexing as implemented in REBOL today is very high speed, which is why there is no penalty for writing code that uses HEAD, HEAD?, TAIL, TAIL?, INDEX?, LENGTH?, PICK, etc. They all have identical performance: fast (unlike a language like C for instance). So, beware of other claims. 4. We treat "going past the end" of a series as an exception. Fundamental natives like PICK handle it by returning NONE. Secondary natives handle it by causing an error (e.g. FIRST, SECOND, THIRD, etc.). This is done so you don't have to write special code every time you use FIRST, because if you did, you might as well use PICK or LENGTH?. The FIRST native would not offer a coding advantage. 5. It has been proposed that there are three functions that would provide a more flexible method of indexing series. We are willing to make these into Natives if that is possible (that is, they don't require changes to existing datatype formats, they don't require special static storage per series that must be managed and garbage collected, and they can be applied to all series datatypes, not just blocks and strings, but also to hashes, lists, ports). To make this happen, send us a concise description and algorithm of each native function (such as a mezz function that does it). We will take a look at them. Please use REBOL naming conventions for function names (e.g. verb first, obvious names, etc.). We'll let you know what we decide. -Carl Sassenrath REBOL's Designer PS: it is considered good mail list netiquette to change the subject line for long running discussions that are off the original topic.

 [2/9] from: maarten:koopmans:surfnet:nl at: 25-Feb-2003 21:51


Amen ;-) --Maarten

 [3/9] from: nitsch-lists:netcologne at: 25-Feb-2003 22:13


Carl Sassenrath wrote: [snip]
> 4. We treat "going past the end" of a series as an exception. > Fundamental natives
<<quoted lines omitted: 15>>
> datatypes, not just > blocks and strings, but also to hashes, lists, ports).
i like the effect of returning 'none when out of series. allows stuff like face/text: any[ pick data index "default string"] but i think the out-of-range trick is a bit hidden. could it make sense to have versions with and without error-checking, 'pick and 'pick? or something, to code more specific?

 [4/9] from: greggirwin:mindspring at: 25-Feb-2003 16:21


Hi Volker, VN> i like the effect of returning 'none when out of series. VN> allows stuff like VN> face/text: any[ pick data index "default string"] VN> but i think the out-of-range trick is a bit hidden. VN> could it make sense to have versions with and without error-checking, VN> 'pick and 'pick? or something, to code more specific? I agree. I just want an easy, and consistent, way to get values out of a series reliably. Most of the time, the current model is great for me. It avoids error handling code in lots of places where it would add bloat, without affecting reliability or robustness, and let's me work without thinking very hard. There are occasions where I have to think about things a bit more (e.g. am I getting NONE because it's out of range or because the value in the series is really NONE, what construct or syntax is best suited to account for that in the current context, etc.). That's often when I want some method of checking the validity of a series index (e.g. INDEX? returns NONE) without having to worry about triggering an error - which of course we can do with a mezzanine or by wrapping it in an ATTEMPT. In any case, I want things that make writing code easier for the general case. -- Gregg

 [5/9] 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

 [6/9] from: g:santilli:tiscalinet:it at: 27-Feb-2003 9:56


Hi Ladislav, On Wednesday, February 26, 2003, 5:42:55 PM, you wrote: LM> I am trying to summarize the proposals before I send them to LM> the feedback. My goal was to find a formulation, that will be LM> as close to the existing functions as possible, while yielding LM> maximum of useful informations (hoping, that Volker and Gregg LM> would be satisfied, I am not sure about Joel and Gabriele, LM> though). I still don't understand why there's a need to have PICK/ALL, but as long as I don't have to use it, that's fine for me. ;-) BTW, since the only way to create "before head" series is the new #[...] construct, should it be considered a bug in the parser? Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [7/9] from: lmecir:mbox:vol:cz at: 27-Feb-2003 11:17


Hi, Gabriele wrote: ...
> BTW, since the only way to create "before head" series is the new > #[...] construct, should it be considered a bug in the parser?
Not at all, the ability to create and examine series like that is contained in my proposition Ciao -L

 [8/9] from: joel::neely::fedex::com at: 27-Feb-2003 9:19

Open Letter [was: Series Index Discussion]


Hi, Carl, I hardly know how to reply, but as I have actively participated in the disussion, I assume I am one of "the same three people" and feel obligated to try. Carl Sassenrath wrote:
> WRT the series discussion that pops up every year on this list: >
I searched using eScribe with the terms "series" and "index?". We've certainly had various discussions about series values in the past, but I didn't find a discussion of the issue at hand. This discussion was stimulated by the fact that the Core 2.5.5 beta changes the behavior associated with "off the end" series references. I've always understood the release of beta product (whether to the general public or to a specific group of users, such as this list) as an invitation to discuss the changes/bugs discovered in the release. (That's certainly what I've meant by beta releases of software I've written.) As the Core 2.5.5 beta announcement was made to this list, it seemed to be the right place to have that conversation. I can't speak for the other two (of "the same three" ;-) but that's what I thought we were doing.
> 1. Typically, this discussion is between the same three people > who discuss the merits of other indexing methods and theories. >
The discussion wasn't about "other indexing methods". It was about what might be a better (as in "more easily usable") way to handle out-of-bounds series references than the change that showed up in the Core 2.5.5 beta.
> 2. The current series index implementation is based on > performance, not strict theory... >
The discussion hasn't been about performance (nor theory) but about the possible problems of having a series reference that seems to change its INDEX? value as a side-effect of changes to a different reference to the same series. AFAICT, none of the ideas pitched in for discussion would have significant effects on performance.
> 5. It has been proposed... > Please use REBOL naming conventions for function names (e.g. > verb first, obvious names, etc.). >
Although I wasn't aware that (as of your post) any proposals had been made, I can summarize my expressed POV succinctly. I'm *not* proposing names here, for two reasons: 1) Without questioning the value of good naming, I'm more concerned at the moment with functionality, and am quite happy to discuss naming issues have subsequently (e.g. "name follows function") 2) In this discussion (not proposal) among professional programmers, I think we can talk about ideas that apply to many cases without having to give specific examples of each possible application. That said, here's the POV I was suggesting: * Allow expressions to ask for the true INDEX? of any series, * Allow programmers to test that value against whatever criteria are appropriate in each case, and take the appropriate actions. In more detail: 1) It should always be possible to ask for the INDEX? of a series, and the result should be the actual position of that reference (whether in bounds or not). 2) It should always be possible to ask for contents from a series. If the request is out of bounds, the result should be NONE. This is exactly how PICK, FIND, and SELECT work currently, AFAIK, with NONE representing the "no answer" case. This is also similar in idea to the value of e.g. IF and SWITCH which evaluate to NONE if the controlling expression/value causes them to gracefully do nothing. 3) In cases where the series ref may not be in bounds, having INDEX? behave as in (1) allows us easy options when trying to retrieve content: 3a) If NONE is an acceptable value in the current case, simply write the obvious expression (PICK, FIRST, etc.) 3b) If NONE is not an acceptable value in the current case, (e.g. summing a collection of numbers), then write the surrounding expression to handle gracefully the "no answer" case, as in bonuses: [ "Tom" 25.00 "Myrtle" 50.00 "Alice" 75.00 "Harry" 15.00 ] total: 0 foreach name ["Tom" "Dick" "Harry"] [ total: total + any [select bonuses name 0.00] ] 3c) If the surrounding expression depends on an series reference having an in-bounds position), then that could be explicitly tested given (1), as in here: index? ser-ref either all [1 <= here here < length? head ser-ref] [ something: first ser-ref ][ ; handle the out-of-bounds situation ] or (using an appropriate definition of IN-BOUNDS? either as mezzanine or native) either in-bounds? ser-ref [ something: first ser-ref ][ ; handle the out-of-bounds situation ] either of which seems to me as easy to write/understand as the present if error? try [something: first ser-ref] [ ; handle the out-of-bounds situation ] None of these ideas would seem to require more state data in a series value, nor would they have a negative effect on performance; in fact ordinal fetches (FIRST, SECOND, et al) would actually be faster. (AFAIK, but I have no knowledge of the inside details of the REBOL interpreter ;-) In overall response to your post, let me just add this. I'm truly sorry that you seem to have been offended/annoyed by the discussion. I truly don't feel that you responded to questions that were raised along the way (why INDEX? should give different values, why PICK _ 1 and FIRST should not mean the same thing, etc.) when those questions were raised in a good-faith effort to understand the intent of past and (apparently forthcoming) REBOL design. I'm sad that it is so easy to dismiss sincere questions or concerns with condescending remarks about "theory". As a working programmer who works with other programmers of various skill levels, I have little time to spend trying to look out for special cases (or changes) in behavior of the language I use (especially the undocumented special cases or changes). Whenever I can say (or read, or remember for myself) statments like foo does blah-blah-blah and know that that's the whole story, it's easier to learn/use FOO than when the true statement is more like foo does blah-blah-blah unless so-and-so, in which case yadda-yadda-yadda, and unless such-and-such, in which case bow-wow-wow, and unless you've previously done ... This is not an issue of "theory". It is an issue of how easy it is to learn/use a language effectively. REBOL has many useful qualities and worthwhile ideas. I'd like to see it succeed. These comments are offered with that goal in mind. -jn-

 [9/9] from: riacht::freenet::de at: 28-Feb-2003 20:05

Re: Series Index Discussion (Was: Core 2.5.5. Beta)


Maarten Koopmans wrote:
> Amen ;-) > > --Maarten
Wow! Thanks, Maarten! S.

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted