World: r3wp
[Core] Discuss core issues
older newer | first last |
[unknown: 5] 22-Mar-2008 [9446] | ;Here is a handy skip function: skip+: func [ {Returns a series matching the skip sequence} series [series!] "Series to return skip values from." interval [integer!] "Skip interval" start [integer!] "Series index to start skipping from." /local blk][ blk: copy [] series: at series start while [not tail? series][ if (index? series) = start [insert tail blk first series start: start + interval] series: next series ] series: head series if empty? blk [return none] blk ] |
Henrik 22-Mar-2008 [9447] | hmm... can you give some examples of the skip+ function? |
[unknown: 5] 22-Mar-2008 [9448x2] | >> blk: [1 2 3 4 5 6 7 8 9 10] == [1 2 3 4 5 6 7 8 9 10] >> skip+ blk 2 1 == [1 3 5 7 9] >> blk: ["paul" "john" "ringo" "george" "michael" "ted" "hans" "linda" "sue"] == ["paul" "john" "ringo" "george" "michael" "ted" "hans" "linda" "sue"] >> skip+ blk 3 1 == ["paul" "george" "hans"] |
It allows you to start at any index position in a series and begin returning values that match the skip interval. | |
Geomol 22-Mar-2008 [9450x2] | You can use EXTRACT for that: >> extract blk 3 == ["paul" "george" "hans"] >> extract next blk 3 == ["john" "michael" "linda"] |
REBOL has so many cool functions already build in. Look here for them sorted by area of use: http://www.rebol.com/docs/dictionary.html | |
Henrik 22-Mar-2008 [9452] | Geomol, it reminds me that R3's help function must provide hints to relevant functions. I've fallen into this trap many times. |
[unknown: 5] 22-Mar-2008 [9453x6] | LOL geomol, I was looking all over for a function in REBOL that did that. |
My skip function is a bit more efficient though. Maybe we should replace extract with it: | |
>> a == [1 2 3 4 5 6 7 8 9 10] >> stats/evals/clear == [2 1 2] >> b: extract/index a 2 1 == [1 3 5 7 9] >> stats/evals == [218 107 33] >> stats/evals/clear == [219 108 34] >> b: skip+ a 2 1 == [1 3 5 7 9] >> stats/evals == [187 90 39] | |
Looks like extract is also a bit buggy | |
>> a == [1 2 3 4 5 6 7 8 9 10] >> b: extract a 2 22 == 22 >> b: extract/index a 2 22 == [none none none none none] | |
But for what I'm doing I think extract will be fine since it is built in. Will save me a few lines of code in my script. | |
Henrik 22-Mar-2008 [9459] | I don't see a bug in any of those entries. |
[unknown: 5] 22-Mar-2008 [9460] | Probably not a bug but does we really want none to be returned? |
Henrik 22-Mar-2008 [9461] | yes, that's on purpose. in 2.7.6 you can define a different default value to be returned. |
[unknown: 5] 22-Mar-2008 [9462] | So how is it not a bug if you tell it to start at index 22 and there is no index 22 and it is returning none? |
Henrik 22-Mar-2008 [9463x4] | >> a/22 |
sorry | |
>> a/22 == none | |
in 2.7.6: >> b: extract a 2 == [1 3 5 7 9] >> b: extract/index a 2 22 == [none none none none none] >> b: extract/index/default a 2 22 'potato == [potato potato potato potato potato] | |
[unknown: 5] 22-Mar-2008 [9467] | I know that a/22 is none but shouldn' t it instead react like other REBOL entries in this regard and say "out of range"? |
Henrik 22-Mar-2008 [9468] | if it did that, we'd have hundreds of cases where we'd need extra error handling. in fact, R3 produces more cases where it returns none, than R2 does. it's just simpler. |
[unknown: 5] 22-Mar-2008 [9469] | Not a fan of how it returns values. |
Henrik 22-Mar-2008 [9470x2] | the error checking you could do, would be to check for the range first and then pick your value, if the index is in range. |
well, you'd have to write a lot more code, if it returned an error. | |
[unknown: 5] 22-Mar-2008 [9472x2] | I don't have to do none of that with skip+ |
>> a == [1 2 3 4 5 6 7 8 9 10] >> skip+ a 2 22 == none | |
Henrik 22-Mar-2008 [9474] | I can see you are worried about whether the returned none! is a value in your block or if it's out of range. |
[unknown: 5] 22-Mar-2008 [9475] | exactly |
Henrik 22-Mar-2008 [9476x2] | another reason extract does this, is to keep the block datatype for output. again you need to produce much more code, if the datatype is changed in the output. |
you don't have to worry if you just check if the index is in range first. | |
[unknown: 5] 22-Mar-2008 [9478] | skip+ keeps the output in a block as well: >> skip+ a 2 3 == [3 5 7 9] |
Henrik 22-Mar-2008 [9479] | not when it's out of range :-) |
[unknown: 5] 22-Mar-2008 [9480x2] | exactly. I wouldn't want it to more often then I would |
much easier to do: to-block skip+ a 2 3 then to determine if a none is an actual value being returned of my series. | |
Henrik 22-Mar-2008 [9482] | but... anyway, it's just two different principles. I prefer to do the error checking before doing operations in the series: a: [1 2 3 4] b: 7 either tail? at a b [print "whoa!"][extract a b] |
[unknown: 5] 22-Mar-2008 [9483x2] | That is defeating the purpose of a mezz. The mezzanines are so we don't need to use more code. |
Makes me think we should have a poll for mezzanine changes. Let the community decide. Could be very beneficial to REBOL. | |
Henrik 22-Mar-2008 [9485] | how will you do error checking with less code in the example above? |
[unknown: 5] 22-Mar-2008 [9486] | I'm saying with skip+ it is already done for me. I can tell if something is out of range if it returns none. |
Henrik 22-Mar-2008 [9487] | sure. that's why I think is impractical for cases like: foreach val skip+ a 2 3 [do-something] you will get a crash, when it returns none, and you will still need to do some type of range check to avoid the crash. |
[unknown: 5] 22-Mar-2008 [9488x3] | i'm going to use extract for what I'm doing since I already am doing error checking on the front side in my scripts where I'm going to use extract but I'm only going to use it since it is built in. But I'd rather see something similiar to the returns that skip+ provides instead. |
Lastest Makedoc draft of TRETBASE for public download: http://www.mediafire.com/?x8yu1mrl724 | |
sorry wrong group | |
RobertS 23-Mar-2008 [9491x2] | ; I liked this feature of ICON/UNICON where a func can have an initially block so I have this in REBOL initial: func [wd [word!] /list /local functions] [ functions: [] if list [return functions] f: find functions wd either (found? f) [return false] [append functions wd return true] ] initially: func ['wd [lit-word!] blk [block!]][ if (initial wd) [do blk] ] ; and to test initially test: func [str [string!] /local prefix [string!]][ prefix: "" initially 'test [prefix: "tested "] print [prefix str] ] ; which runs as, say test "this" ; first time giving "tested this" and thereafter "this" ; thoughts on whether useful enough to go into the org library ? |
; of course initial itself test more simply >> initial 'append == true >> initial 'append == false | |
BrianH 23-Mar-2008 [9493x2] | Paul, the changes to EXTRACT are part of a whole series of subtle changes to REBOL that are based on 3 ideas: - NONE is a value that denotes no value, like UNSET but not an error - sort of like SQL NULL. - Out of range isn't necessarily an error - you can choose to treat it as such as you like, or not. Boundaries are really an implementation detail in a language with autoexpanding series. The choice to have fixed boundaries is left to the developer. - There is no difference between a NONE in the middle of a series and a NONE off the end. It's a missing value either way. REBOL worked this way already in many cases, so we're making it more consistent. |
Creating, evaluating, throwing and catching those error! values is really expensive - nones are much faster. Also, these error! values are generated in many cases now where the situation isn't really erroneous, which is a little presumptuous. | |
[unknown: 5] 23-Mar-2008 [9495] | I just don't like it Brian. Like Henrik noticed I have a problem with it because it returns none as a value inside of the series. I rather have it report none as a none! When it is reported as it is currently in extract it isn't a none! datatype it is a 'none word value. |
older newer | first last |