• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp134
r3wp1094
total:1228

results window for this page: [start: 901 end: 1000]

world-name: r3wp

Group: Core ... Discuss core issues [web-public]
Izkata:
27-May-2009
USAGE:
    FORSKIP 'word skip-num body

Yep, the set-word gets assign to word, the [1 2 3 4] gets assigned 
to skip-num, and 2 gets assigned to body, because of the lit-word 
argument in forskip
Graham:
20-Jul-2009
>> parse next s: "ArialBoldItalic" [ some [ some non-caps [ end | 
mark: ( insert mark #" " ) skip ]] ]
== true
>> s
== "Arial Bold Italic"
Pekr:
20-Jul-2009
not sure if correct, but:

caps: charset [ #"A" - #"Z" ]
non-caps: complement caps
s: "aaaArialBoldItalic"

parse/all s [any [mark: caps (insert mark #" ") skip | skip] end]
Graham:
20-Jul-2009
>> parse next s: "ArialBoldItalicYY" [ some [ some non-caps [ end 
| mark: ( insert mark #" " ) 2 skip ]] ]
== true
>> s
== "Arial Bold Italic YY"
Graham:
20-Jul-2009
>> parse/all s: "abcArialBoldItalicsCY" [some [mark: caps (insert 
mark #" ") 2 skip | skip] end]
== true
>> s
== "abc Arial Bold Italics CY"
Ashley:
20-Jul-2009
Here's the finished code (which obtains REBOL compatable font names 
under Mac):

	fonts: copy []
	caps: make bitset! [#"A" - #"Z"]

 foreach file compose [(read %/System/Library/Fonts/) (read %/Library/Fonts/)] 
 [
		if %.dfont = suffix? file [
			s: form first parse file "."

   parse next s [any [mark: caps (insert mark #" ") 2 skip | skip] end]
			insert tail fonts s
		]
	]
	remove-each font-name fonts: sort unique fonts [

  (size-text make face [text: "A" font: make face/font [name: font-name 
  size: 10]]) =

  size-text make face [text: "A" font: make face/font [name: font-name 
  size: 12]]
	]


(the windows func to do this is http://www.reboltech.com/library/scripts/get-fonts-windows.r
)
Graham:
20-Jul-2009
Pekr, skip can always be used as the first word in the parse rule 
if you don't like next
Maxim:
28-Aug-2009
doh.... sorry... my mind mixed-up /part with /skip...
BrianH:
7-Sep-2009
In R3:
>> help swap
USAGE:
        SWAP series1 series2

DESCRIPTION:
        Swaps elements of a series. (Modifies)
        SWAP is an action value.

ARGUMENTS:
        series1 (series! gob!)
        series2 (series! gob!)
>> swap a: "abc" skip a 2 a
== "cba"
BrianH:
16-Nov-2009
Position: HEAD, TAIL, HEAD?, TAIL?, AT, SKIP, NEXT, BACK

Contents: PICK, POKE (for modifiable series), ordinals (FIRST, ..., 
LAST)

Sequence: PICK and POKE can use numbers (used to implement ordinals)

Persistent position and sequence: All of the above are repeatable, 
with no position change side effect.
Chris:
19-Nov-2009
Another, from the 'parse school:

	parse block [
		any [block: any-block! (insert block take block) :block | skip]
	] head block
Gregg:
2-Dec-2009
Even with a simple example like the one you gave, I might add a couple 
funcs to make the intent even clearer. e.g.

insert-from-tail: func [
    series [series!] 
    value  
    index  [integer!]
] [
    insert skip tail series negate abs index value
]

insert-before-tail: func [
    series [series!] 
    value  
][
    insert-from-tail series value 1
]

insert-before-tail series my-value
Maxim:
15-Jan-2010
and either in a compose is very powerfull... cause it allows conditional 
serie content creation).

; when false, an empty block is returned and compose ignores it.

draw-blk: compose [ (either gfx? [ [pen black circle 30x30 ][    
[ ]   ])]


this example is simple but when creating very complex draw blocks 
on the fly, I often have a few cascaded compose blocks, and in some 
cases, the resulting draw block is an empty block even if it takes 
100 lines to get to that.  the language will skip the nested composes 
if an outer condition is false, so in fact, its VERY fast.
Henrik:
24-Jan-2010
Cyphre made this new FORM-DECIMAL function. I've been allowed to 
share it, so it can be tested:

form-decimal: func [
	num cifre
	/local m n o p result
][
	p: ""
	result: either find num: form num #"e" [
		parse num [
			any [copy m to "." skip] copy n to "E" skip o: (
				all [
					not m
					m: n
					n: ""
				]
				if m/1 = #"-" [
					m: copy next m
					p: "-"
				]
				z: (length? m) + to-integer o
				result: to-string reduce either negative? z [
					["0." (head insert/dup copy "" "0" abs z) m n]
				][
					o: join m n
					["" o (head insert/dup copy "" "0" (z - length? o))]
				]
			)
		]
		result
	][
		num
	]
	result: parse result "."
	o: result/1
	o: skip tail result/1 -3
	while [not head? o][insert o #"." o: skip o -3]
	all [
		not result/2
		insert tail result ""
	]
	result/2: copy/part result/2 cifre
	insert/dup tail result/2 "0" cifre - length? result/2
	all [cifre > 0 insert next result ","]
	all [result/1/1 = #"0" p: ""]
	join p result
]
Pekr:
25-Jan-2010
Some time ago, I did form-decimal function too. But I am really a 
coding lamer, so dunno, if it cover at least half the cases other 
versions do. Here it is:

form-decimal: func [num /local tmp main rest sign base][

     either found? find tmp: to-string num "E" [

              parse tmp [
                 [copy main to "." 
                  skip
                  copy rest to "E"
                  |
                  copy rest to "E"
                  (main: copy "")  
                  ]
             
                 skip
                 mark: (sign: copy/part mark 1)
                 skip
                 copy base to end
               ]


        either sign = "-" [

                tmp: copy "0."

                loop ((to-integer base) - 1) [insert tail tmp "0"]
                insert tail tmp rest
        ][
                tmp: copy ""

                insert tail tmp join main rest

                loop ((to-integer base) - (length? rest)) [insert tail tmp "0"]  
                    
                           
        ] 
     
      tmp                 

     ][num] 

]
Graham:
25-Jan-2010
form-decimal: func [   num     [number!]
        cifre   [integer!]

        /local sign str poscifre int frac pow
    ][   sign: either negative? num [#"-"] [""]
        str: make string! 16
        either zero? num
        [   insert str #"0"
            if cifre > 0
            [   insert/dup
                    insert
                        tail str
                        #","
                    #"0"
                    cifre
        ]   ]
        [   num: abs num
            num: form
                add
                    multiply
                        power 10 cifre
                        to-decimal num
                    0,5

                        ; mainly WINE bug workaround - might also work for larger numbers 
                        on Windows
                        if find num "E"

                        [       parse num [copy int to "." skip copy frac 15 to "E" skip 
                        copy pow to end]
                                pow: to integer! pow
                                either pow >= 0
                                [       insert/dup
                                                insert/part

                                                        insert clear num int
                                                        frac

                                                        skip frac pow
                                                #"0"

                                                pow - length? frac
                                ]
                                [       num: "0"]
                        ]
            clear any [find num "." ""]
            poscifre: skip  tail num  negate cifre
            insert/part insert str sign num
                num: skip num
                    1 + remainder
                        subtract
                            index? poscifre
                            2
                        3
            while [(index? poscifre) > (index? num)]
            [   insert/part
                    insert
                        tail str
                        #"'"
                    num
                    num: skip num 3
            ]
            if empty? str [insert str #"0"]
            if not tail? poscifre
            [   insert
                    insert/dup
                        insert
                            tail str
                            #","
                        #"0"
                        cifre - length? poscifre
                    poscifre
            ]
        ]
        str
    ]
Gregg:
27-Jan-2010
forskip+: func [
        "Like FORSKIP, but with local FIRST? and LAST? support."
        [throw catch]

        'word [word!] {Word set to each position in series and changed as 
        a result}
        skip-num [integer!] "Number of values to skip each time"
        body [block!] "Block to evaluate each time"
        /local orig result
    ][

        if not positive? skip-num [throw make error! join [script invalid-arg] 
        skip-num]
        if not any [
            series? get word
            port? get word
        ] [

            throw make error! {forskip/forall expected word argument to refer 
            to a series or port!}
        ]
        orig: get word
        use [first? last?] [
            first?: true
            last?:  false
            body: bind/copy body 'first?

            while [any [not tail? get word (set word orig false)]] [
                if tail? skip get word skip-num [last?: true]
                set/any 'result do body
                set word skip get word skip-num
                first?: false
                get/any 'result
            ]
        ]
    ]
BrianH:
30-Jan-2010
collect-words: func [

 "Collect unique words used in a block (used for context construction)."
	block [block!]
	/deep "Include nested blocks"
	/set "Only include set-words"
	/ignore "Ignore prior words"
	words [object! port! block!] "Words to ignore"
	/local rule word blk w
][

 deep: either deep [[path! | set-path! | lit-path! | into rule]] [any-block!]
	word: either set [set-word!] [any-word!]
	blk: []
	parse block rule: [
		set w word (insert tail blk to-word to-string w) | deep | skip
	]
	also either ignore [
		unless block? words [words: words-of words]
		difference blk intersect blk words
	] [
		unique blk
	] (clear blk set [block words] none)
]
; Note: In R3 this is native, called by MAKE OBJECT!

;   The words are not supposed to be bound, thus the to-word to-string.
BrianH:
30-Jan-2010
invalid-utf?: funct [

 "Checks for proper UTF encoding and returns NONE if correct or position 
 where the error occurred."
	data [binary!]
	/utf "Check encodings other than UTF-8"
	num [integer!] "Bit size - positive for BE negative for LE"
] compose [
	ascii: (charset [#"^(00)" - #"^(7F)"])
	utf8+1: (charset [#"^(C2)" - #"^(DF)"])
	utf8+2: (charset [#"^(E0)" - #"^(EF)"])
	utf8+3: (charset [#"^(F0)" - #"^(F4)"])
	utf8rest: (charset [#"^(80)" - #"^(BF)"])
	switch/default any [num 8] [
		8 [ ; UTF-8
			unless parse/all/case data [(pos: none) any [
				pos: ascii | utf8+1 utf8rest |
				utf8+2 2 utf8rest | utf8+3 3 utf8rest
			]] [as-binary pos]
		]
		16 [ ; UTF-16BE
			pos: data
			while [not tail? pos] [
				hi: first pos
				case [
					none? lo: pick pos 2 [break/return pos]
					55296 > w: hi * 256 + lo [pos: skip pos 2]  ; #{D800}
					57343 < w [pos: skip pos 2]  ; #{DFFF}
					56319 < w [break/return pos]  ; #{DBFF}
					none? hi: pick pos 3 [break/return pos]
					none? lo: pick pos 4 [break/return pos]
					56320 > w: hi * 256 + lo [break/return pos]  ; #{DC00}
					57343 >= w [pos: skip pos 4]  ; #{DFFF}
				]
				none
			] ; none = valid, break/return pos = invalid
		]
		-16 [ ; UTF-16LE
			pos: data
			while [not tail? pos] [
				lo: first pos
				case [
					none? hi: pick pos 2 [break/return pos]
					55296 > w: hi * 256 + lo [pos: skip pos 2]  ; #{D800}
					57343 < w [pos: skip pos 2]  ; #{DFFF}
					56319 < w [break/return pos]  ; #{DBFF}
					none? lo: pick pos 3 [break/return pos]
					none? hi: pick pos 4 [break/return pos]
					56320 > w: hi * 256 + lo [break/return pos]  ; #{DC00}
					57343 >= w [pos: skip pos 4]  ; #{DFFF}
				]
				none
			] ; none = valid, break/return pos = invalid
		]
		32 [ ; UTF-32BE
			pos: data
			while [not tail? pos] [
				if any [
					4 > length? pos
					negative? c: to-integer pos
					1114111 < c  ; to-integer #{10FFFF}
				] [break/return pos]
			]
		]
		-32 [ ; UTF-32LE
			pos: data
			while [not tail? pos] [
				if any [
					4 > length? pos

     negative? c: also to-integer reverse/part pos 4 reverse/part pos 
     4
					1114111 < c  ; to-integer #{10FFFF}
				] [break/return pos]
			]
		]
	] [
		throw-error 'script 'invalid-arg num
	]
]

; Note: Native in R3, which doesn't support or screen the /utf option 
yet.

; See http://en.wikipedia.org/wiki/Unicodefor charset/value explanations.
Oldes:
19-Feb-2010
What's the best name for such a function?

f: func[words data][forall words [insert data make set-word! words/1 
 data: skip data 2] make object! head data]
Oldes:
19-Feb-2010
or this one:

f: func[words data][forall words [insert data words/1  data: skip 
data 2] head data]
Steeve:
20-Feb-2010
Oldes, I have them but in R3.

the first one in an aternative way to make objects.

as-object: func [w d][set w: bind? use w reduce [:first w] d w]

>>as-object [a b c][1 2 3]
== make object! [
    a: 1
    b: 2
	c: 3
]

I named the second one Mixin, with a slightly different code too.

mixin: funco [a [series!] b [series!] /local v][
    parse a: copy a [some [skip if (v: first+ b) insert v] a:]]
    head clear a
]

>>mixin "12345" "abcdefgh"
=="1a2b3c4d5e"

>>mixin [1 2 3 4 5 ] "abcdefgh"
==[1 #"a" 2 #"b" 3 #"c" 4 #"d" 5 #"e"]
Gregg:
20-Feb-2010
I have ALTERNATE and MERGE at the lower levels. The first combines 
two series and returns a new series. The second merges one series 
into another, with a /SKIP refinement. I have TO-SPEC-BLOCK , since 
that's such a useful and common need. I avoided using AS- in the 
past, thinking more standard non-copying coercion funcs would make 
them confusing. Those haven't appeared, so I do use AS- sometimes 
now.
BrianH:
28-Feb-2010
This means that SKIP is a pure function for series, returning a reference 
to a new position - while it is modifying when applied to ports, 
changing the internal position. Same with the other position functions 
like AT, HEAD and TAIL.
Andreas:
16-Apr-2010
cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] 
[
    mask: skip to-binary (shift -1 32 - bits) 4
    (mask and to-binary address) = (mask and to-binary network)
]
Steeve:
16-Apr-2010
See that weird one :)


cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] 
[
    mask: to-tuple skip to-binary (shift -1 32 - bits) 4
    mask and address xor network = .0.
]
BrianH:
9-May-2010
Use SORT/compare with an integer argument for the index of the records 
you want compared, and don't forget /skip for the record length. 
Like this:
>> sort/skip/compare [1 5 2 4 3 3 4 2 5 1] 2 2
== [5 1 4 2 3 3 2 4 1 5]
Sunanda:
9-May-2010
You mean using /skip and /compare to sort a series in sets?
s: [1 2 8 a   1 2 6 b   1 2 7 c]    ;; three sets of four items
sort/skip/compare s 4 [3]        ;; sort on the third item
== [1 2 6 b 1 2 7 c 1 2 8 a]
Sunanda:
9-May-2010
Yes you can:
sort/skip/compare s 4 [1 2 4 3]
== [1 2 8 a 1 2 6 b 1 2 7 c]
amacleod:
11-May-2010
BrainH asked: Didn't know you could put the /compare index in a block. 
Can you specify more than one index?

Sunanda says: Yes you can:
sort/skip/compare s 4 [1 2 4 3]
== [1 2 8 a 1 2 6 b 1 2 7 c]


That's great but can you do that with a block of blocks of  data....

example: 
s: [
	[1 2 8 a]
	[1 2 6 b] 
	[1 2 7 c]]
]
Sunanda:
17-May-2010
You could tweak something like this:
    res: make block length? blk
    while [ind: find blk 23]
         [print blk append res index? ind blk: skip blk last res]
    blk: head blk
    probe res


But remember the first rule of REBOL Code Golf: parse always wins.....We're 
now just waiting for a parse guru to show us how :)
Ladislav:
17-May-2010
indices?-1: func [
	series [series!]
	value
	/local result
] [
	result: make series 0
	while [series: find series value] [
		append result index? series
		series: next series
	]
	result
]

indices?-2: func [
	series [series!]
	value
	/local result
] [
	result: make series 0
	parse series [

  any [1 1 value series: (append result subtract index? series 1) | 
  skip]
	]
	result
]
>> time-block [indices?-1 blk 23] 0,05
== 0.000006591796875

>> time-block [indices?-2 blk 23] 0,05
== 0.000005645751953125
Pekr:
17-May-2010
A bit adapted Lad's version (does not use substraction):

indices?-4: func [
	series [series!]
	value
	/local result
] [
	result: make series 0
	parse series [
		any [series: 1 1 value (append result index? series) | skip]
	]
	result
]


>> time-block [indices?-2 blk 23] 0,05
== 0.000003936767578125

>> time-block [indices?-4 blk 23] 0,05
== 0.000003753662109375
Pekr:
17-May-2010
Replacing "1 1 value" by "quote (value)" as variant 5:

indices?-5: func [
	series [series!]
	value
	/local result
] [
	result: make series 0
	parse series [

  any [series: quote (value) (append result index? series) | skip]
	]
	result
]

>> time-block [indices?-1 blk 23] 0,05
== 0.0000047607421875

>> time-block [indices?-2 blk 23] 0,05
== 0.000003936767578125

>> time-block [indices?-3 blk 23] 0,05
== 0.0000059814453125

>> time-block [indices?-4 blk 23] 0,05
== 0.00000372314453125

>> time-block [indices?-5 blk 23] 0,05
== 0.000003692626953125
Terry:
17-May-2010
>> a

== [23 43 55 28 345 99 320 48 22 23 95 884 1000000 999999 999998 
999997 999996 999995 999994 999993 999992 999991 999990 999989 999...
>>

(a is a block with 1, 000,012  integers) 


ind: func[series value x][


	st: now/time/precise
		
	while [x > 0][
		
		result: make series 0
		series: head series

  parse series[any [series: 1 1 value (append result index? series) 
  | skip]] 
		x: x - 1
	]
	et: now/time/precise
	fin: et - st
	print fin
	result 
]

feach: func[series value x][

	result: make series 0 
	st: now/time/precise
	
	while [x > 0][

  foreach[s p v] series [if s = value [append result reduce [s p v]]]
		x: x - 1
	]
	et: now/time/precise
	fin: et - st
	print fin
	result 
]

>> ind a 23 10
0:00:01.249
== [1 10 999990]
>>

>> feach a 23 10
0:00:01.01

== [23 43 55 23 95 884 23 43 55 23 95 884 23 43 55 23 95 884 23 43 
55 23 95 884 23 43 55 23 95 884 23 43 55 23 95 884 23 43 55 23 9...
>>

10 iterations each.. 


foreach is the winner speed wise.. as a bonus, If i use foreach, 
I don't need the index?
Tomc:
20-May-2010
while[here: find/skip here key 2][insert tail result second here 
here: at here 2]
Ladislav:
3-Jul-2010
Simplification:

past?: func [
	"Returns TRUE if a series index is past its tail."
	series [series! gob! port!]
][
	not same? :series skip :series 0
]

; Note: INDEX? doesn't stay consistent with past-tail references 
in R2.
BrianH:
3-Jul-2010
The not same? :series skip :series 0 line works well enough, afaict. 
Do you have a case for which it doesn't work and the larger test 
is required?
Ladislav:
3-Jul-2010
Yes, but skip :series 0 auto-adjusts still, but, as I said, I do 
not mind
Graham:
24-Jul-2010
In the same way 'for does ... where there is a skip counter from 
1 .. n
Graham:
25-Jul-2010
Anyway, I can't see that' it's any different from skip ... or other 
such
Gregg:
26-Jul-2010
traverse [
    all blk-n
    each [a b] blk-a
    skip blk-x 2
    each e blk-e
][
    ;...
]
Graham:
19-Aug-2010
>> help find
USAGE:

    FIND series value /part range /only /case /any /with wild /skip size 
    /match /tail /last /reverse
DideC:
25-Aug-2010
I have a question about 'unique that could become a feature request.

Somebody ask (on the french Rebol forum) how he could remove the 
duplicate records from this dataset :
database: [
	a "b" "c 1" "d"
	a "b" "c 2" "d" 
	a "b" "c 3" "d"
	a "b" "c 2" "d" ;ligne 4 to delete
	a "b" "c 5" "d" 
	a "b" "c 6" "d" 
	a "b" "c 7" "d" 
	a "b" "c 2" "d" ;ligne 8 to delete
]

My first though was "use 'unique func". But it turns out that it 
can't do what I though.

As usual, the doc tells nothing about that (in fact it ells pretty 
nothing on the func), but with the /skip refinment, it seems it only 
checks the first value at each skip position (so the 'a in this dataset), 
not all the values of the record.
Izkata:
25-Aug-2010
'unique appears to be using the entire record with the /skip refinement 
- if it was just the first value ('a), then there would only be 1 
record remaining (2.7.6)
BrianH:
26-Aug-2010
Here's the R2 version:
extract: func [
	"Extracts a value from a series at regular intervals."
	[catch]
	series [series!]
	width [integer!] "Size of each entry (the skip)"
	/index "Extract from an offset position"
	pos "The position" [number! logic! block!]
	/default "Use a default value instead of none"

 value "The value to use (will be called each time if a function)"

 /into "Insert into a buffer instead (returns position after insert)"
	output [series!] "The buffer series (modified)"
	/local len val
][

 if zero? width [return any [output make series 0]]  ; To avoid an 
 infinite loop
	len: either positive? width [  ; Length to preallocate
		divide length? series width  ; Forward loop, use length
	][

  divide index? series negate width  ; Backward loop, use position
	]
	unless index [pos: 1]
	either block? pos [

  if empty? pos [return any [output make series 0]] ; Shortcut return
		parse pos [some [number! | logic! | set pos skip (

   throw-error 'script 'expect-set reduce [[number! logic!] type? get/any 
   'pos]
		)]]
		unless into [output: make series len * length? pos]
		if all [not default any-string? output] [value: copy ""]
		; R2 PARSE doesn't work well for binary!, so spoof a string!.
		if binary? series [series: as-string series]
		forskip series width [forall pos [
			if none? set/any 'val pick series pos/1 [set/any 'val value]
			output: insert/only output get/any 'val
		]]
	][
		unless into [output: make series len]
		if all [not default any-string? output] [value: copy ""]
		; R2 PARSE doesn't work well for binary!, so spoof a string!.
		if binary? series [series: as-string series]
		forskip series width [
			if none? set/any 'val pick series pos [set/any 'val value]
			output: insert/only output get/any 'val
		]
	]
	either into [output] [head output]
]
BrianH:
26-Aug-2010
Here's the R3 version:
extract: func [
	"Extracts a value from a series at regular intervals."
	series [series!]
	width [integer!] "Size of each entry (the skip)"
	/index "Extract from an offset position"
	pos "The position(s)" [number! logic! block!]
	/default "Use a default value instead of none"

 value "The value to use (will be called each time if a function)"

 /into "Insert into a buffer instead (returns position after insert)"
	output [series!] "The buffer series (modified)"
	/local len val
][  ; Default value is "" for any-string! output

 if zero? width [return any [output make series 0]]  ; To avoid an 
 infinite loop
	len: either positive? width [  ; Length to preallocate
		divide length? series width  ; Forward loop, use length
	][

  divide index? series negate width  ; Backward loop, use position
	]
	unless index [pos: 1]
	either block? pos [

  unless parse pos [some [number! | logic!]] [cause-error 'Script 'invalid-arg 
  reduce [pos]]
		unless output [output: make series len * length? pos]
		if all [not default any-string? output] [value: copy ""]
		forskip series width [forall pos [
			if none? set/any 'val pick series pos/1 [set/any 'val value]
			output: insert/only output :val
		]]
	][
		unless output [output: make series len]
		if all [not default any-string? output] [value: copy ""]
		forskip series width [
			if none? set/any 'val pick series pos [set/any 'val value]
			output: insert/only output :val
		]
	]
	either into [output] [head output]
]
Pekr:
15-Sep-2010
Also - is there any way of how to easily find out, if the block is 
unique? Should I apply 'unique, and compare the length before and 
after? Pity 'unique has /skip refinement, but does not have /compare 
one (as 'sort has), so that I can't set, when I have e.g. record 
of 5 items, I want to 1) set the record size (/skip) 2) select fields, 
upon which we want to define uniquess - could be an integer offset, 
or a block of positions [1 3] ... 'sort allows at least the offset 
via /compare
Pekr:
15-Sep-2010
Can I somehow get a difference of two blocks, with different sizes? 
Trying to avoid loops, but I will use loop most probably anyway ...

blk1 structure: [contract user tarif]
blk2 structure: [contract user street town tarif]


I know there are functions like intersect/difference, they even have 
/skip refinement, but those most probably can't treat different record 
sizes?
Maxim:
15-Sep-2010
I really think, again, that  'append-or-insert-only-if-the-item-does-not-exist-already 
 should be a native in R3.


its a function MOST of us would use on a frequent basis.  it would 
be very usefull and its very powerfull with a /skip refinement
Maxim:
19-Sep-2010
statement: skip post -2
change find statement 'fixed 'changed

?
Izkata:
19-Sep-2010
Using 'forall with 'remove will skip the element after a removed 
one (in R2 at least, don't know if it changed in R3)

>> X: [1 1 2 2 3 3 4 4 5 5 6 6 7 7]
== [1 1 2 2 3 3 4 4 5 5 6 6 7 7]
>> forall X [if odd? X/1 [remove X]]
== [7]
>> X
== [1 2 2 3 4 4 5 6 6 7]
Group: !REBOL3-OLD1 ... [web-public]
Henrik:
29-Apr-2009
http://www.rebol.net/r3blogs/0194.html

SELECT/SKIP behavior discussion needed now.
shadwolf:
29-Apr-2009
select/skip b 3 returning 20  only is an aberation ... that's not 
what we expect ...
BrianH:
29-Apr-2009
It's what I expected, but I've never used SELECT/skip in R2. The 
R2 behavior sounds better to me.
Maxim:
29-Apr-2009
but the skip becomes pretty useless, as you can get the inner records 
of the skip.
Maxim:
29-Apr-2009
the /skip in many functions are implied records... and the reason 
they are there... not getting the record as a return values... is 
an oxymoron IMHO
Maxim:
29-Apr-2009
the R3 return sort of alleviates the point of the /SKIP refinement 
no?
BrianH:
29-Apr-2009
So am I. I wasn't saying I preferred it, just that I expected it. 
I think this is why I've never used select/skip :(
Henrik:
29-Apr-2009
The R2 method is much more flexible. The R3 method is identical to 
"first select/skip", and I doubt there would be that much gained 
by having a specific alternative function for the R3 method.
Maxim:
29-Apr-2009
its like sort/skip there is a simple consistency in the implied records 
which I always like... other languages will have a framework just 
for that...
Maxim:
29-Apr-2009
but find will trip if records ands content can have the same datatypes... 
wich is why the /skip refinement makes sense.
BrianH:
29-Apr-2009
Sorry, FIND/skip
Henrik:
29-Apr-2009
Maxim, yes. I'd say that if every single REBOL function used /SKIP 
consistently, you could do flat block databases and rely on /SKIP 
without getting your records screwed up.
Maxim:
29-Apr-2009
its almost the case now... sort/skip  find/skip  select/skip
Henrik:
29-Apr-2009
hey, here's a fun one:

a: [1 2 3 4 5 6 7 8]

select/skip a 5 -4

hangs.
Maxim:
29-Apr-2009
(in regards to /skip)  post order makes my last post a bit out of 
context
Henrik:
29-Apr-2009
select/skip issue submitted to curecode.
Henrik:
29-Apr-2009
it seems FIND/SKIP does the same thing. :-)
Henrik:
29-Apr-2009
7 reports with /SKIP issues.
BrianH:
29-Apr-2009
Clearly we are going to need a /SKIP doc in R3/Language/Options.
BrianH:
29-Apr-2009
I wrote MOVE, so talk to me. How should MOVE with negative skip work? 
Allowed or denied?
Maxim:
29-Apr-2009
should say move is like skip
BrianH:
29-Apr-2009
move: make function! [[
    "Move a value or span of values in a series."
    source [series!] "Source series"
    offset [integer!] "Offset to move by, or index to move to"
    /part "Move part of a series"
    length [integer!] "The length of the part to move"
    /skip "Treat the series as records of fixed size"
    size [integer!] "Size of each record"
    /to {Move to an index relative to the head of the series}
][
    unless length [length: 1]
    if skip [
        offset: offset * size: max 1 size
        length: length * size
    ]
    part: take/part source length
    insert either to [at head source offset] [
        system/words/skip source offset
    ] part
]]
Henrik:
29-Apr-2009
BrianH, do we want consistency across all /SKIP or not? That is a 
big issue. Personally I would like it.
Henrik:
29-Apr-2009
OK. The solution would be to generate an out of range error for skip 
<= 0. DIFFERENCE does that correctly.
BrianH:
29-Apr-2009
I wrote the other standard option specs after much discussion. We 
need that discussion before I can write the /SKIP spec.
Maxim:
29-Apr-2009
I would really like the /skip to be consistent as "implied fixed 
record" it would make flat record management and "explicit" feature 
of REBOL.
Maxim:
29-Apr-2009
the partial (last) record consistency is part of the /SKIP feature 
set wich must not be forgotten.
Maxim:
29-Apr-2009
IMO a partial record is valid, until you try an option which would 
break the /skip alignment... so sort/skip with inclomplete records 
would always be invalid.
Maxim:
29-Apr-2009
so sorting an incomplete /skip would add nones into the block?
BrianH:
29-Apr-2009
So the question is whether we want /skip < 1 to be an out of range 
error, like DIFFERENCE, or to constrain to 1 silently, like MOVE.
Maxim:
29-Apr-2009
I say it should react the same as skip > length of series.
BrianH:
29-Apr-2009
Not the same thing. If you have skip > length of the series, it will 
only do one iteration and your access to the results off the end 
will usally be none, unless you constrain it yourself. The question 
is whether negative skip should be silently constrained or generate 
an error, as a general rule.
Maxim:
29-Apr-2009
the algorythm using the /skip is responsible for ensuring that it 
treats the unaligned first value in any case... but the algorythm 
will much simple to write if the offset which is returned by the 
use of /skip doesn't change.
Maxim:
29-Apr-2009
brian: any reflections on my post regarding the /skip past start?
BrianH:
29-Apr-2009
/skip is a length, not a index or an offset. I'm not sure what effect 
/skip past start should have.
Maxim:
29-Apr-2009
hum... implementing an example to show, I realise that using skip 
should return an error in the case of series, cause alignment is 
broken, just like sort.
Maxim:
29-Apr-2009
ex:

a: next "1234567890"

probe head move/skip a 4 2

== "1456789023"
Maxim:
29-Apr-2009
this sort of stumps me philosophically on how to manage the /skip 
in either direction when you go past bounds.
Maxim:
29-Apr-2009
I guess the best action to take is to specify explicitely that /skip 
is meant to handle records when they are aligned. results of un-aligned 
/skip operations are un-defined at best.
Maxim:
29-Apr-2009
to create an empty record set of 30 records would be as easy as:

rs: move/skip [] 30 3
BrianH:
29-Apr-2009
OK, Maxim, the MOVE/skip example you specify is not an error in MOVE, 
it is an error in the code calling MOVE in that example. MOVE was 
specifically designed to do something useful in that case, rather 
than generate an error.


The whole reason that MOVE takes one position and one offset is because 
that limit gets rid of a host of potential aliasing errors. MOVE 
is designed to be the most efficient and safe solution to the problem 
of moving stuff, and it should *never fail* unless the series is 
protected from changes. MOVE is a DWIM function: Do What I Mean. 
This goes for treating negative /skip lengths as an error too - having 
it magically constrain the /skip length to 1 or greater was a deliberate 
design choice, the result of a lot of discussion.


So the question is whether the error of having /skip lengths being 
less than 1 is worth worrying about, worth the overhead of generating 
an error and checking for that error every time you use the function. 
Don't be fooled, that overhead is really significant.


We've already changed other functions so they don't generate errors 
anymore, and just DWIM, like FIRST not complaining about bounds and 
acting like PICK 1 now. These changes have made these functions faster, 
and better to use. Generating an error is considered something to 
do when it is really important, as it sometimes is. How important 
is the /skip < 1 error?
Maxim:
29-Apr-2009
you have been talking about the actual /skip parameter value, and 
all along I was talking about the effect of using /skip which causes 
the function to go outside of bounds of the series based on the skip 
size... 

doh!   hahahaha
BrianH:
29-Apr-2009
The behavior that Henrik is concerned with is /skip lengths < 1. 
MOVE was designed to just up that to one, DWIM.
Maxim:
29-Apr-2009
but *I* didn't get your point  ;-)

/skip size < 1 should effectively just be bound to 1


as long as its explicitely documented.   there is no real use in 
/skip < 1
BrianH:
29-Apr-2009
The problem is that DIFFERENCE/skip < 1 generates an error, and every 
other function /skip < 1 hangs. So the question is whether they should 
*all* be changed to act like MOVE (silently DWIM), or all be changed 
to act like DIFFERENCE (generate an error).
Henrik:
5-May-2009
and almost all skip bugs too
BrianH:
5-May-2009
Except MOVE/skip - I did that one :)
Henrik:
5-May-2009
we are generally ending up with error for skip < 1?
901 / 122812345...89[10] 111213