• 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: 1001 end: 1100]

world-name: r3wp

Group: !REBOL3-OLD1 ... [web-public]
Rebolek:
6-May-2009
Ah, #460 is not fixed because maximum-of doesn't work at all. This 
should be first line in the 'maximum-of function: "if not skip [size: 
1]"
Steeve:
6-May-2009
add/skip or multiply/skip not enough ?
Lol
Henrik:
6-May-2009
I can only emphasize the importance of submitting Curecode reports. 
Curecode is the only place Carl looks, and he personally thanked 
me for submitting the /SKIP reports, which are now all fixed.
Maxim:
15-May-2009
we should skip R4 and go directly to R10  or should it be ... RX 
 ;-)
Henrik:
24-May-2009
you can always use skip -n if you want to jump relatively in a series.
Oldes:
27-May-2009
Steeve, it's not working..
>> str: to-string #{C49BC5A1C48DC599C5BEC3BDC3A1C3ADC3A9313278}
== "ešcržýáíé12x"

>> parse str [some [copy tmp 1 skip (probe tmp)]]
c
ž
á
é
2
x
== true
Oldes:
27-May-2009
but you can see, that the skip is not working as expected.
Ladislav:
4-Jul-2009
try this in R3


>> do http://www.rebol.org/download-a-script.r?script-name=identity.r
Script: "Identity.r" Version: none Date: 7-May-2009/8:59:07+2:00
Script: "Contexts" Version: none Date: 12-May-2006/15:58+2:00
Script: "Closure" Version: none Date: 11-May-2009/19:13:51+2:00
Script: "Apply" Version: none Date: 7-May-2009/9:25:31+2:00
== make function! [[
    "finds out, if the VALUE is mutable"
    value [any-type!] /local r
][
    parse head insert/only copy [] get/any 'value [

        any-function! | error! | object! | port! | series! | bitset! |
        struct! | set r any-word! (
            either bind? :r [r: none] [r: [skip]]
        ) r
    ]
]]

>> a: [z] append/only a a
== [z [...]]

>> b: [z [z]] append/only second b second b
== [z [...]]

>> c: [z [z]] append/only second c c
== [z [z [...]]]

>> equal-state? a a
== true

>> equal-state? a b
== true

>> equal-state? a c
== true
Geomol:
6-Jul-2009
Ladislav, I've tested random some more. The equal sign, =, is used 
to test in the end of RANDOM, if the result should be changed to 
0.0. This will change more values, than if =? was used. I use =? 
in my test. My test goes like this:

REBOL [
	Title:		"Random distribution test"
	Author:		"John Niclasen"
]

random/seed now
dist: clear []	; distribution
tt62: to integer! 2 ** 62
a: tt62 - 1024
loops: 100000
loop loops [
	i: random 1024
	if i > 512 [i: i + a]	; test close to 0.0 and close to 1.0
	y: i - 1 / tt62 * 1.0
	if y =? 1.0 [y: 0.0]	; the result of random 1.0
	y: form y
	either find dist y [
		dist/:y: dist/:y + 1
	][
		repend dist [y 1]
	]
]
while [not tail? dist] [
	dist/1: load dist/1		; change strings back to decimals
	dist: skip dist 2
]
dist: head dist
sort/skip dist 2	; sorting distribution
print dist
mean: 0.0
foreach [value count] dist [
	mean: value * count + mean
]
mean: mean / loops	; calculating the mean value
print mean	; this should be 0.5


The test is testing values close to 0.0 and close to 1.0. Notice 
the high count of 0.0 result compared to other low values. Also notice, 
how the mean value is close to 0.25, where it should be 0.5. Try 
out-comment the change of y to 0.0. Then the result will be much 
better.
Geomol:
26-Aug-2009
They aren't in series! because they don't have position

What do you mean?

>> t: 11.22.33.44.55.66.77.88.99.00
== 11.22.33.44.55.66.77.88.99.0
>> t/5
== 55
>> third t
== 33

Some series stuff works with tuples, but not all like SKIP.
Maxim:
11-Sep-2009
but the loading actually does a re-encoding.  utf-8 is compact, buts 
its slow because you cannot skip unless you traverse the string char 
by char.  which is why they are internally converted to 8 or 16 bit 
unicode chars... it seems strings become 16 bits a bit too often 
(maybe a change in later releases, where they are always converted 
to 16 bits for some reason).
BrianH:
22-Sep-2009
EITHER doesn't need to skip past |, so pick another name. It will 
be prefix. Suggest it in the 249 blog.
shadwolf:
23-Sep-2009
Howerver when you don't know what you can put and what you can skip 
you end with a ugly code full of useless things
Steeve:
27-Sep-2009
I came with something existing, and said: Now, how can i do this 
more rebolish...

parse/case opcode [
	any [
		start: 
		| "nn" end: (change/part start get-byte end)
		| "+d" end: (change/part start get-d end)
		| "e" end: (change/part start get-e end)
		| skip
	]
]
Steeve:
27-Sep-2009
Because change still doesn't work , the best i can do is that:

parse/case opcode [
    any [
          "nn" remove -2 (new: get-word) insert new
        | #"n" remove -1 (new: form get-byte) insert new
        | "+d" remove -2 (new: get-d) insert new
        | #"e" remove -1 (new: get-e) insert new
        | skip
    ]
]

What the gain ? nothing...
Steeve:
27-Sep-2009
Forget CHANGE for the moment. Even with INSERT and REMOVE commands, 
i see things i don't like.

What i should able to write is that:

parse/case opcode [
    any [
          remove "nn" insert get-word
        | remove #"n" insert get-byte
        | remove "+d" insert get-d
        | remove #"e" insert get-e 
        | skip
    ]
]

Wich means:

- Remove "nn" if  "nn" is matched and insert the result of the function 
get-word.
or  Remove "n" ..
or  remove "+d" ...
or remove "e" ..
Steeve:
27-Sep-2009
When Change will work, I expect to be able to write:

parse/case opcode [
    any [
          change "nn" get-word
        | change #"n" get-byte
        | change "+d" get-d
        | change #"e" get-e 
        | skip
    ]
]
BrianH:
27-Sep-2009
First of all, Steeve, what you are suggesting is the original INSERT, 
CHANGE and REMOVE proposals. Which Carl said were infeasible to implement, 
which is why we have the new ones. Besides that, your example code 
is still too awkward. Try this:

parse/case opcode [
    any [ start:
          "nn" remove start insert (get-word)
        | #"n" remove start insert (form get-byte)
        | "+d" remove start insert (get-d)
        | #"e" remove start insert (get-e)
        | skip
    ]
]


If you are worried about change not working yet, don't be. It is 
still planned.
BrianH:
27-Sep-2009
The change version of the above would be this:

parse/case opcode [
    any [ start:
          "nn" change start (get-word)
        | #"n" change start (form get-byte)
        | "+d" change start (get-d)
        | #"e" change start (get-e)
        | skip
    ]
]
Steeve:
27-Sep-2009
I don't understant, the following parsings should be equal but it's 
not, why ???

parse a: "abcdef" [
    any [
          "b" remove -1
        | "cd" remove -2
        | skip
    ]
]
print a
parse a: "abcdef" [
    any [start: 
          "b" remove start 
        | "cd" remove start
        | skip
    ]
]
print a
PeterWood:
30-Sep-2009
In the past Carl seemed to skip building the "big" alpha releases 
for OSX and Linux until the Windows has been tested. I would guess 
that we'll see a84 or a 85 for OSX.
Graham:
12-Jan-2010
where is the skip occuring to advance thru the from-file?
Graham:
12-Jan-2010
Does the skip occur automatically on a file port?
Robert:
14-Jan-2010
Editors choke on this as well because these are to stupid to skip 
braces in strings. So the balance function is mostly not correctly 
working.
Group: !Cheyenne ... Discussions about the Cheyenne Web Server [web-public]
Dockimbel:
28-Jan-2010
The only thing I touch in %my.cnf is skip-networking (when uncommented) 
and skip-innodb (when commented).
Dockimbel:
28-Jan-2010
Brian: I'm using mainly FIND, NEXT, BACK, SKIP to navigate in hash! 
values. Hash! type is supposed to be a block! (inheriting all series 
navigation capabilities) with fast lookup times, so I've always used 
it like a block!. That's why I feel like I've lost something with 
map!.
Kaj:
10-May-2010
--- mod-userdir.r.original	2010-05-09 19:28:10.000000000 +0200
+++ mod-userdir.r	2010-05-11 00:45:24.000000000 +0200
@@ -12,40 +12,81 @@
 	on-started: does [do boot-code]
 	on-reload:  does [clear boot-code]
 	
-	get-ugid: func [name [string!] /local file uid gid][
-		if none? attempt [file: read %/etc/passwd][
+	get-ugid: func [name [string!] /local file line uid gid][
+		unless attempt [file: read/lines %/etc/passwd][
 			log/error "accessing /etc/passwd failed"
 			return none
 		]
-		unless parse/all file [
-			thru name 2 [thru col]
-			copy uid to col skip
-			copy gid to col
-			to end
-		][
-			log/error "reading /etc/passwd failed"
+		foreach line file [
+			if all [line: find/case/match line name  col = first line][
+				return either parse/all next line [
+					thru col
+					copy uid to col skip
+					copy gid to col
+					to end
+				][
+					reduce [to-integer uid to-integer gid]
+				][
+					log/error "invalid format reading /etc/passwd !"
+					none
+				]
+			]
+		]
+		log/error "user not found in /etc/passwd"
+		none
+	]
+	
+	get-gid: func [name [string!] /local file line gid][
+		unless attempt [file: read/lines %/etc/group][
+			log/error "accessing /etc/group failed"
 			return none
 		]
-		reduce [to-integer uid to-integer gid]
+		foreach line file [
+			if all [line: find/case/match line name  col = first line][
+				return either parse/all next line [
+					thru col
+					copy gid to col
+					to end
+				][
+					to-integer gid
+				][
+					log/error "invalid format reading /etc/group !"
+					none
+				]
+			]
+		]
+		log/error "group not found in /etc/group"
+		none
 	]
 	
-	change-id: func [id [word! integer!] /user /group][
-		if word? id [
-			if none? id: get-ugid mold id [return none]
-			id: pick id to-logic user

+	change-id: func [id [string! integer!] /user /group /local gid][
+		either string? id [
+			unless id: get-ugid id [return none]
+			set [id gid] id
+		][
+			gid: id
 		]
-		either user [
+		if group [setgid gid]
+		if user [
 			;logger/file.log: join logger/file ["-" id %.log]
 			setuid id
-		][setgid id]
+		]
+	]
+	
+	change-gid: func [id [string! integer!]][
+		if string? id [
+			unless id: get-gid id [return none]
+		]
+		setgid id
 	]
 	
 	words: [
 		user: [word! | integer!] in globals do [
-			repend boot-code ['change-id/user to-lit-word args/1]

+			repend boot-code either word? args/1 [['change-id/user/group 
mold args/1]] [['change-id/user args/1]]
 		]
 		group: [word! | integer!] in globals do [
-			repend boot-code ['change-id/group to-lit-word args/1]
+			unless empty? boot-code [change boot-code [change-id/user]]

+			insert boot-code reduce ['change-gid either word? args/1 [mold 
args/1][args/1]]
 		]
 	]
 ]
\ No newline at end of file
Kaj:
7-Sep-2010
--- mod-userdir.r.original	2010-05-09 19:28:10.000000000 +0200
+++ mod-userdir.r	2010-05-11 00:45:24.000000000 +0200
@@ -12,40 +12,81 @@
 	on-started: does [do boot-code]
 	on-reload:  does [clear boot-code]
 	
-	get-ugid: func [name [string!] /local file uid gid][
-		if none? attempt [file: read %/etc/passwd][
+	get-ugid: func [name [string!] /local file line uid gid][
+		unless attempt [file: read/lines %/etc/passwd][
 			log/error "accessing /etc/passwd failed"
 			return none
 		]
-		unless parse/all file [
-			thru name 2 [thru col]
-			copy uid to col skip
-			copy gid to col
-			to end
-		][
-			log/error "reading /etc/passwd failed"
+		foreach line file [
+			if all [line: find/case/match line name  col = first line][
+				return either parse/all next line [
+					thru col
+					copy uid to col skip
+					copy gid to col
+					to end
+				][
+					reduce [to-integer uid to-integer gid]
+				][
+					log/error "invalid format reading /etc/passwd !"
+					none
+				]
+			]
+		]
+		log/error "user not found in /etc/passwd"
+		none
+	]
+	
+	get-gid: func [name [string!] /local file line gid][
+		unless attempt [file: read/lines %/etc/group][
+			log/error "accessing /etc/group failed"
 			return none
 		]
-		reduce [to-integer uid to-integer gid]
+		foreach line file [
+			if all [line: find/case/match line name  col = first line][
+				return either parse/all next line [
+					thru col
+					copy gid to col
+					to end
+				][
+					to-integer gid
+				][
+					log/error "invalid format reading /etc/group !"
+					none
+				]
+			]
+		]
+		log/error "group not found in /etc/group"
+		none
 	]
 	
-	change-id: func [id [word! integer!] /user /group][
-		if word? id [
-			if none? id: get-ugid mold id [return none]
-			id: pick id to-logic user

+	change-id: func [id [string! integer!] /user /group /local gid][
+		either string? id [
+			unless id: get-ugid id [return none]
+			set [id gid] id
+		][
+			gid: id
 		]
-		either user [
+		if group [setgid gid]
+		if user [
 			;logger/file.log: join logger/file ["-" id %.log]
 			setuid id
-		][setgid id]
+		]
+	]
+	
+	change-gid: func [id [string! integer!]][
+		if string? id [
+			unless id: get-gid id [return none]
+		]
+		setgid id
 	]
 	
 	words: [
 		user: [word! | integer!] in globals do [
-			repend boot-code ['change-id/user to-lit-word args/1]

+			repend boot-code either word? args/1 [['change-id/user/group 
mold args/1]] [['change-id/user args/1]]
 		]
 		group: [word! | integer!] in globals do [
-			repend boot-code ['change-id/group to-lit-word args/1]
+			unless empty? boot-code [change boot-code [change-id/user]]

+			insert boot-code reduce ['change-gid either word? args/1 [mold 
args/1][args/1]]
 		]
 	]
 ]
\ No newline at end of file
Oldes:
28-Sep-2010
hm.. maybe I could just skip to the directory in the init.d script.
amacleod:
8-Feb-2012
#[object! [ code: 303 type: script id: expect-arg arg1: copy arg2: 
range arg3: [#[datatype! number!] #[datatype! series!] #[datatype! 
port!] #[datatype! pair!]] near: [cmd: copy/part skip header 2] where: 
on-task-received ]]
Group: !CureCode ... web-based bugtracking tool [web-public]
james_nak:
9-Oct-2010
Each day I get an rsp error in the head.rsp file:
** Script Error : Invalid argument: 2 
	** Where: rsp-script 
	** Near:  [foreach [id prj] head sort/skip/compare skip]

I am running Cheyenne and Curecode on a server at home and then have 
another PC as my normal workstation. So each day when I go to Curecode, 
it throws this error. All I have to do to fix it is to go to the 
server, refresh the curecode page from there and it works on the 
remote machine again. 
Anyone else seen this and have a fix?
Group: Profiling ... Rebol code optimisation and algorithm comparisons. [web-public]
Maxim:
17-May-2010
just for Terry.....


rebol []


feach: func[
	series 
	value
	i "iterations"
	/local result st
][
	prin "feach(): "
	st: now/precise
	x: length? series
	
	while [i > 0][
		prin i
		prin "."
		result: make series 0 

  foreach[s p v] series [if s = value [append result reduce [s p v]]]
		i: i - 1
	]
	prin join " -> " difference now/precise st
	print ["  " (length? result) / 3 "matches found"]
	result 
]


find-fast: func [
	series
	value
	record-length
	i "iterations"
	/local result st s
][
	prin "find-fast(): "
	st: now/precise
	while [i > 0][
		prin i
		prin "."
		result: clear [] ;length? series
		s: head series
		until [
			not all[
				s: find/tail s value
				either 0 =  ( (-2 + index? s ) // record-length) [
					insert tail result copy/part series record-length
					not tail? s: skip s record-length
				][
					not tail? s: next s
				]
			]
		]
		i: i - 1
	]
	
	prin join " -> " difference now/precise st
	print ["  " (length? result) / record-length "matches found"]
	
	head result
]


find-really-fast: func [
	series
	keys
	value
	record-length
	i "iterations"
	/local result st s
][
	prin "find-really-fast(): "
	st: now/precise
	while [i > 0][
		prin i
		prin "."
		result: clear [] ;length? series
		s: head keys
		until [
			not all [
				s: find/tail s value

    insert tail result copy/part at series (record-length * ( -1 + index? 
    s )) record-length
			]
		]
		i: i - 1
	]
	
	prin join " -> " difference now/precise st
	print ["  " (length? result) / record-length "matches found"]
	
	head result
]

test-size: 2000000 ; number of records
iterations: 5
rsize: 3


print "preparing sparse data"
dataset: make block! test-size 
loop test-size [
	; we exclude 9 from dataset
	loop rsize [
		dataset: insert dataset random 8
	]
]
dataset: head dataset
insert at dataset (100 * rsize + 1) 9
insert at dataset (2000 * rsize + 1) 9
insert at dataset (50000 * rsize + 1) 9
insert at dataset (10000 * rsize + 1) 9
insert at dataset (20000 * rsize + 1) 9

probe length? dataset
print "sparse tests:"
feach dataset 9 iterations
print "----------------"
find-fast dataset 9 rsize iterations
print "----------------"
keys: extract dataset rsize
find-really-fast dataset keys 9 rsize iterations
print "----------------"


print "^/dense match with key/value collisions"
dataset: make block! test-size 
loop test-size [
	; we include 9 in the dataset
	loop rsize [
		dataset: insert dataset random 9
	]
]
dataset: head dataset
probe length? dataset
feach dataset 9 iterations
print "----------------"
find-fast dataset 9 rsize iterations
print "----------------"
keys: extract dataset rsize
find-really-fast dataset keys 9 rsize iterations
print "----------------"


print "^/dense match without key/value collisions"
dataset: make block! test-size 
loop test-size [
	; we include 9 in the dataset
	dataset: insert dataset random 9
	loop (rsize - 1) [
		dataset: insert dataset 10 + random 100000 
	]
]
dataset: head dataset
probe length? dataset
feach dataset 9 iterations
print "----------------"
find-fast dataset 9 rsize iterations
print "----------------"
keys: extract dataset rsize
find-really-fast dataset keys 9 rsize iterations
print "----------------"

ask "done"
Maxim:
17-May-2010
the series was being skipped one too many (since I'm using /tail 
on the find, as suggested by andreas)

find-fast: func [
	series
	value
	record-length
	i "iterations"
	/local result st s
][
	prin "find-fast(): "
	st: now/precise
	while [i > 0][
		prin i
		prin "."
		result: clear [] ;length? series
		s: head series
		until [
			not all[
				s: find/tail s value
				either 0 =  ( (-2 + index? s ) // record-length) [
					insert tail result copy/part series record-length
					not tail? s: skip s record-length
				][
					not tail? s: next s
				]
			]
		]
		i: i - 1
	]
	
	prin join " -> " difference now/precise st
	print ["  " (length? result) / record-length "matches found"]
	
	head result
]
Maxim:
18-May-2010
in the code... 


rsize: 3   is the record size...  like the /skip value in most series 
handlers  

my two funcs will adapt, since you provide it the record size


but ... ehehe, I just realized that find HAS the /skip attribute... 
doh!!! the above can be made MUCH faster still, especially by removing 
the need for the keys (which take a bit of time to generate on large 
lists).
Maxim:
18-May-2010
using find/skip and an index for what item to search for in the record... 
we get by FAR the fastest search... if you count the fact that generating 
the keys for find-very-fast often takes as long as the search itself, 
in dense searches.

ultimate-find below gives the results of this new function


preparing sparse data
6000005
sparse tests:
feach(): 5.4.3.2.1. -> 0:00:04.89   4 matches found
----------------
find-fast(): 5.4.3.2.1. -> 0:00:00.719   4 matches found
----------------
find-really-fast(): 5.4.3.2.1. -> 0:00:00.234   4 matches found
----------------
ultimate find(): 5.4.3.2.1. -> 0:00:00.594   4 matches found
----------------

dense match with key/value collisions
6000000
feach(): 5.4.3.2.1. -> 0:00:13.343   221606 matches found
----------------
find-fast(): 5.4.3.2.1. -> 0:00:14.813   221606 matches found
----------------

find-really-fast(): 5.4.3.2.1. -> 0:00:07.718   221606 matches found
----------------
ultimate find(): 5.4.3.2.1. -> 0:00:06.735   221606 matches found
----------------

dense match without key/value collisions
6000000
feach(): 5.4.3.2.1. -> 0:00:13.969   222405 matches found
----------------
find-fast(): 5.4.3.2.1. -> 0:00:09.812   222405 matches found
----------------

find-really-fast(): 5.4.3.2.1. -> 0:00:07.672   222405 matches found
----------------
ultimate find(): 5.4.3.2.1. -> 0:00:06.531   222405 matches found
----------------
done
Maxim:
18-May-2010
ultimate-find: func [
	series
	value

 index "field you want to search on, should be (1 <= index <= record-length)"
	record-length
	i "iterations"
	/local s st result
][
	prin "ultimate find(): "
	st: now/precise
	while [i > 0][
		prin i
		prin "."
		result: clear [] ;length? series
		s: at series index
		until [
			not all [
				s: find/skip s value record-length

    insert tail result copy/part skip s (-1 * index + 1) record-length
				s: skip s 3
			]
		]
		i: i - 1
	]
	
	prin join " -> " difference now/precise st
	print ["  " (length? result) / record-length "matches found"]
	
	head result
]
Pekr:
18-May-2010
Max - just a question - wouldn't using parse be faster than find/skip?
Maxim:
18-May-2010
I didn't do any parse test tweaks... but find/skip is very fast so 
far, we can skip over 100 million records within a millisecond.  
not sure parse can beat that
Maxim:
19-May-2010
ah   yes.... ususally a hash will have to skip over  elements which 
return the same hash key.


so if your table has a few thousand similar items, you aren't benifiting 
from the hashing... and its quite possible that looking up a hash 
itself is actually longer when it has to skip over and over (comparing 
data on top of the hash).


though one could argue, that the speeds should be a bit slower than 
using a block, not this slower...  possibly related to the implementation 
itself.
Group: !REBOL3 Schemes ... Implementors guide [web-public]
Steeve:
8-Jan-2010
It's clearly explain in the link you pointed.

Note B

OPEN is called twice. It is moded. The mode is determined by the 
existence of the IP address. If the IP address is not known, the 
LOOKUP happens, otherwise the CONNECT happens. This also means that 
if you do an OPEN of a port where you provide the IP address, no 
lookup is done; you skip directly to CONNECT. If it is necessary 
to determine if the IP address is known (a rare situation), use QUERY 
-- which can be called at any time and is very fast.
Graham:
8-Jan-2010
Does parse skip spaces automatically in r3 ?
Group: !REBOL3 ... [web-public]
Dockimbel:
19-Jan-2010
If you're not using innodb, you should switch it off by uncommenting 
skip-innodb in /etc/mysql/my.cnf (default place for the config file). 
This will save you ~70MB. For the remaining 49MB, I don't know, I 
guess that a good part of that is used by caches.
Graham:
5-Feb-2010
Graham:R3/Mezzanines>> 6843
#6843: skip from ladislav 3h ago:
Ashley:
8-Feb-2010
>> system/version
== 2.100.96.2.5

>> to decimal! 1%
== 0.01
>> to binary! 0.01
== #{3F847AE147AE147B}
>> to binary! 1%
** Script error: invalid argument: 1%
** Where: to
** Near: to binary! 1%

>> to binary! %a 
** Script error: invalid argument: %a
** Where: to
** Near: to binary! %a

>> to binary! 0x0
** Script error: invalid argument: 0x0
** Where: to
** Near: to binary! 0x0


I think pair! should be binary! encoded/decoded something like this 
(in R2 it was to-binary formed):

to-raw-pair!: make function! [[
	pair [pair!]
	/local x y
][
	x: to binary! pair/x
	y: to binary! pair/y
	while [all [zero? first x zero? first y]][remove x remove y]
	append x y
]]

to-rebol-pair!: make function! [[
	pair [binary!]
	/local length
][

 to pair! reduce [to integer! copy/part pair length: (length? pair) 
 / 2 to integer! skip pair length]
]]

>> to-raw-pair! 0x255 
== #{00FF}
>> to-raw-pair! 0x256 
== #{00000100}
Pekr:
8-Feb-2010
let's try to compare following for R2 vs R3: 


 parse "abc^/def^/ghi^/" [start: any [end: newline (print copy/part 
 start end) start: | skip]]
Pekr:
8-Feb-2010
s: now/time/precise loop 1000000 [parse "abc^/def^/ghi^/" [start: 
any [end: newline start: | skip]]] now/time/precise - s

Three consecutive runs:
R2:
0:00:03.11
0:00:02.941
0:00:03.089

R3:
0:00:01.732
0:00:01.679
0:00:01.724
Pekr:
8-Feb-2010
the above code does not run in R3. Dunno if "end" is forbidden or 
became a keyword, but I get following error, if I don't change end: 
to en:


>> s: now/time/precise loop 1000000 [parse "abc^/def^/ghi^/" [start: 
any [end: n
ewline start: | skip]]] now/time/precise - s
** Script error: PARSE - command cannot be used as variable: end:
** Where: parse loop
** Near: parse {abc
def
ghi
} [start: any [end: newline start: | skip...
Pekr:
8-Feb-2010
>> start: now/time/precise loop 1000000 [parse "abc^/def^/ghi^/" 
[s: any [e: newline (append blk copy/part s e) s: | skip]]] now/time/precise 
- start
== 0:00:05.359
Claude:
10-Feb-2010
rebol[
	file: %carte-db-joueur.r
]


db-joueur: make object! [
	table: 't_joueurs
	oo: make joueur []
	
	
	list: func[
		o[object!]
		/local
		fields-in-file
		where
		test-nom
		test-prenom
	][
		fields-in-file: select my-db/tables :table
		where: copy []

  if all[(not o/id = 0) (not none? o/id) (not empty? o/id)]  [append 
  where compose [id = (o/id)]]

  if all[(not none? o/nom) (not empty? o/nom)] [append where compose 
  [find nom (o/nom)]]

  if all[(not none? o/prenom) (not empty? o/prenom)] [append where 
  compose [find prenom (o/prenom)]]

   return self/find-where fields-in-file compose/deep [all [(where)]]
	]
	
	find-obj: func[
		o[object!]
		/local
		fields-in-file
		where
	][
		fields-in-file: select my-db/tables :table
		obj: none
		where: copy []
		
		foreach field fields-in-file [
			if not none? o/:field [
				append where compose/deep [(field) = (o/:field)]
			]
		]

  return self/find-where fields-in-file compose/deep [all [(where)]]
	]
	
	find-where: func [
		fields-in-file [block!]
		where[block!]
		/local
		return-list
		data
		obj
	][
		return-list: copy []
		data: copy []	
		obj: none
		either not empty? where [
			data: (db-select/where * :table :where)
		][
			data: (db-select * :table )
		]
		do compose/deep [
			foreach [(fields-in-file)]  [(data)] [
				obj: make oo []
				set obj reduce [(fields-in-file)]
				append return-list obj
			]
		]
		return return-list

	]
	
	insert: func[
		o[object!]
	][
		db-insert :table compose [next (skip get o 1)]
	]
	
	update: func[
		o[object!]
	][
		do compose/deep [db-update/where (table) 
			[(skip select my-db/tables :table 1)]
			[(skip get o 1)]
			compose[id = (o/id)]
		]
	]
	
	delete: func[
		o[object!]
	][
		db-delete/where :table compose[id = (o/id)]
	]

	commit: func[
	][
		db-commit :table
	]
]
Gregg:
18-Feb-2010
flatten: func [block [any-block!]] [
        parse block [

            any [block: any-block! (change/part block first block 1) :block | 
            skip]
        ]
        head block
    ]
Steeve:
19-Feb-2010
here's mine:

flatten: funco [data [block!] /deep][
    deep: if deep [[:data]]
    parse data [
        while [to block! data: change skip data/1 deep]
    ] 
    head data
]
>>flatten [[[1]] [[2]][[3]]]
== [[1] [2] [3]]
>>flatten/deep [[[1]] [[2]][[3]]]
==[1 2 3]
BrianH:
28-Feb-2010
As parse rules go, it wouldn't be difficult. Try this:
>> hex: charset [#"0" - #"9" #"a" - #"f" #"A" - #"F"]
== make bitset! #{000000000000FFC07E0000007E}

>> parse a: "paul%40tretbase.com" [any [to "%" [b: skip copy x 2 
hex (b: change/part b to-char first debase/base x 16 3) :b | skip]]] 
a
== "[paul-:-tretbase-:-com]"

Now that is a modifying method, but it should be easy to adapt that 
to a copying method.
BrianH:
28-Feb-2010
With the full change rule it would be this:

>> parse a: "paul%40tretbase.com" [any [to "%" [change [skip copy 
x 2 hex] (to-char first debase/base x 16) | skip]]] a
Paul:
6-Mar-2010
Chris, I had an issue where I was putting data into a block dynamically 
and then had a skip pattern over it so that every other word was 
turned into a set-word and then passed to construct.
Steeve:
19-Mar-2010
By example, the refinement /index has absolutly no interest.

The obvious and regular way with rebol, is to use SKIP or AT as a 
prefetch.
BrianH:
23-Mar-2010
The only problem that might need Ladislav's proposal is that you 
can't use the word 'self as a parameter of functions or closures: 
A duplicate arg error is thrown. And since you can't use that field 
as a function argument, Ladislav is suggesting that it shouldn't 
be there at all. While I am suggesting that MAKE function! can just 
skip that field when checking function arguments at function creation 
time - a solution that wouldn't require any changes to the internal 
data model of all contexts.
Steeve:
20-Apr-2010
Wow, what a fuss :)

What prevents you to adjust the size of the binary to fit the chosen 
size ?

>>(skip to-binary 1022 6) or #{8000}
==#{8324}
Pekr:
20-Apr-2010
Steeve: I understand your example, no problem about it, but try to 
adapt it to my  (non-existant yet :-) possible R3 cell phone implementation, 
which will use 32 bit integers (not sure if it would ever happen). 
Then, if you want your code being cross platform, your code complicates, 
no?

>>(skip to-binary 1022 6) or #{8000}
==#{8324}
Pekr:
21-Apr-2010
IIRC originally we had following specs: read file /part size /skip 
len
BrianH:
28-Apr-2010
Yes, plus it took a lot of space (it adds up). Plus the objects that 
didn't have that field behaved badly - such objects were created 
to serve as function contexts, or by functions like USE and FOREACH. 
Since all of the code that worked on objects had to skip past the 
first field ('self), if the first field wasn't 'self it was still 
skipped. Plus the 'self field was writeable, which made code injection 
attacks possible when running untrusted code - not really a concern 
for R2 with its known insecurity in such situations, but for R3 it's 
a design criterium to be able to sandbox code. It is really better 
to not have the field at all, and just make it a keyword in certain 
limited circumstances (imo).
BrianH:
7-May-2010
I like to think that FOR works in indexes like AT, instead of offsets 
like SKIP. So that seems like good behavior to me.
Andreas:
18-May-2010
just call the "missing" function UPSERT and be done with it. will 
also fit nicely, if you add special treament of "keyed" records to 
it (using the usual /skip and /part refinements).
Henrik:
1-Jul-2010
>> a: [a 1 2 b 3 4 c 5 6 d 7 8]
== [a 1 2 b 3 4 c 5 6 d 7 8]

>> head move/to/skip find copy a 'd 1 3
== [a 1 d 7 8 2 b 3 4 c 5 6]


Looks like a bug to me. [d 7 8] should be at offset 1 rather than 
3. This is also present in R2 forward.
BrianH:
1-Jul-2010
When /to is not specified and /skip is, offsets are multiplied by 
the record length, so you are counting in records. This is intentional, 
to allow you to work with fixed records without messing them up. 
If we keep that behavior then the index will be the record index, 
not the series index. It's not a difficult trick, but it should be 
noted.
BrianH:
1-Jul-2010
The source is there already in case you need to use it before the 
next version comes out. The R3 version is:
move: func [
	"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" ;; SKIP redefined
	size [integer!] "Size of each record"

 /to "Move to an index relative to the head of the series" ;; TO redefined
][
	unless length [length: 1]
	if skip [
		if 1 > size [cause-error 'script 'out-of-range size]
		offset: either to [offset - 1 * size + 1] [offset * size]
		length: length * size
	]
	part: take/part source length
	insert either to [at head source offset] [
		system/contexts/exports/skip source offset
	] part
]
Gregg:
18-Aug-2010
This was used with small pieces of XML, rather than entire documents, 
but might be a starting point for you.


xml-get-field: func [input name /local xml-field= data other-name] 
[
	xml-field=: compose/deep [ 
		some [

   (rejoin ["<" name ">"]) copy data to (rejoin ["</" name ">"]) to 
   end
			| skip ;(to paren! [prin '.])
		]
	]
	either parse input xml-field= [data] [none]
]
BrianH:
26-Aug-2010
Would it be alright to skip the /skip option? Then we can use a map! 
to do the work without too much overhead.
BrianH:
26-Aug-2010
The problem with the /skip is that we would have to write our own 
hash function, or copy/part every record at least once, or go n^2.
BrianH:
7-Oct-2010
Here's a low-level function to parse and process script headers, 
which shows how many features are built into the base script model 
in R3:

load-script: funct [
	"Decode a script into [header-obj script-ref body-ref]"

 source [binary! string!] "Source code (string will be UTF-8 encoded)"
	/header "Return the header object only, no script processing"

 ;/check "Calculate checksum and assign it to the header checksum 
 field"
	/original "Use original source for Content header if possible"
] compose [
	data: either string? source [to-binary source] [
		unless find [0 8] tmp: utf? source [ ; Not UTF-8
			cause-error 'script 'no-decode ajoin ["UTF-" abs tmp]
		]
		source
	]

 ; Checksum all the data, even that before the header or outside the 
 block
	;sum: if check [checksum/secure data]  ; saved for later
	
	if tmp: script? data [data: tmp] ; Find the start of the script
	
	; Check for a REBOL header
	set/any [hdr: rst:] transcode/only data
	unless case [
		:hdr = 'rebol [ ; Possible REBOL header
			set/any [hdr rst] transcode/next/error rst
			block? :hdr ; If true, hdr is header spec
		]
		:hdr = [rebol] [ ; Possible script-in-a-block
			set/any [hdr rst] transcode/next/error rst
			if block? :hdr [ ; Is script-in-a-block
				unless header [ ; Don't decode the rest if /header
					data: first transcode/next data
					rst: skip data 2
				]
				true
			] ; If true, hdr is header spec
		]
	] [ ; No REBOL header, use default
		hdr: [] rst: data
	]
	; hdr is the header spec block, rst the position afterwards

 ;assert/type [hdr block! data [binary! block!] rst [binary! block!]]
	;assert [same? head data head rst]
	
	; Make the header object, or fail if we can't

 unless hdr: attempt [construct/with :hdr system/standard/header] 
 [
		cause-error 'syntax 'no-header data
	]
	; hdr is a correct header object! here, or you don't get here

 ;if check [append hdr 'checksum  hdr/checksum: sum]  ; calculated 
 earlier

 ;assert [sum =? select hdr 'checksum]  ; Should hdr/checksum be reserved?
	

 if header [return hdr] ; If /header, no further processing necessary

 ; Note: Some fields may not be final because post-processing is not 
 done.
	
	; Skip any whitespace after the header

 ws: (charset [1 - 32]) ; For whitespace skipping (DEL not included)
	if binary? rst [parse rst [any ws rst:]] ; Skip any whitespace
	
	; Check for compressed data and decompress if necessary
	case [
		; Magic autodetection of compressed binary
		tmp: attempt [decompress rst] [
			data: rst: tmp  ; Use decompressed data (no header source)
			append hdr 'compressed  hdr/compressed: true ; Just in case
		]
		; Else not directly compressed (without encoding)
		(select hdr 'compressed) != true [] ; Not declared, do nothing
		; Else it's declared to be compressed, thus should be
		binary? rst [ ; Regular script, check for encoded binary
			set/any [tmp rst] transcode/next/error rst
			either tmp: attempt [decompress :tmp] [
				data: rst: tmp  ; Use the decoded binary (no header source)
				hdr/compressed: 'script  ; So it saves the same way
				; Anything after the first binary! is ignored
			] [cause-error 'script 'bad-press -3] ; Else failure
		]
		; Else it's a block, check for script-encoded compressed binary
		tmp: attempt [decompress first rst] [

   data: rst: tmp  hdr/compressed: 'script  ; It's binary again now
		]
		; Else declared compressed but not compressed, so fail
		'else [cause-error 'script 'bad-press -3]
	]
	
	; Save the script content in the header if specified
	if :hdr/content = true [
		hdr/content: either original [source] [copy source]
	]
	

 ;assert/type [hdr object! data [binary! block!] rst [binary! block!]]
	;assert [same? head data head rst]

 reduce [hdr data rst]  ; Header object, start of source, start of 
 body
]


Note all the commented assert statements: they are for testing (when 
uncommented) and documentation. Also, I later removed the checksum 
calculation from this code because it was the wrong place to put 
it, at least as far as modules are concerned. However, Carl didn't 
know this because he was working on it while I was offline for a 
few days.
BrianH:
7-Oct-2010
Here is the corresponding function in the code reorg, renamed. The 
friendly empty lines and comments haven't been added yet.

load-header: funct/with [
	"Loads script header object and body binary (not loaded)."

 source [binary! string!] "Source code (a string! will get UTF-8 encoded)"

 no-decompress [logic!] "Skip decompression of body (because we want 
 to look at header mainly)"
][
	; This function decodes the script header from the script body.

 ; It checks the 'checksum, 'compress and 'content fields of the header.

 ; It will set the 'content field to the binary source if 'content 
 is true.

 ; It will set the 'compress field to 'script for compressed embedded 
 scripts.

 ; If body is compressed, it will be decompressed (header required).

 ; Normally, returns the header object and the body text (as binary).

 ; If no-decompress is false and the script is embedded and not compressed
	; then the body text will be a decoded block instead of binary.
	; Errors are returned as words:
	;    no-header
	;    bad-header
	;    bad-checksum
	;    bad-compress
	; Note: set/any and :var used - prevent malicious code errors.
	case/all [
		binary? source [data: assert-utf8 source]
		string? source [data: to binary! source]
		not data: script? data [return reduce [none data]] ; no header

  set/any [key: rest:] transcode/only data none ; get 'rebol keyword

  set/any [hdr: rest:] transcode/next/error data none ; get header 
  block

  not block? :hdr [return 'no-header] ; header block is incomplete

  not attempt [hdr: construct/with :hdr system/standard/header][return 
  'bad-header]

  :hdr/content = true [hdr/content: data] ; as of start of header (??correct 
  position??)
		:key = 'rebol [ ; regular script

   rest: any [find rest non-ws rest] ; skip whitespace after header

   ;rest: any [find rest #[bitset! [not bits #{7FFFFFFF80}]] rest] ; 
   skip whitespace
			case/all [

    all [:hdr/checksum :hdr/checksum != checksum/secure rest] [return 
    'bad-checksum]

    no-decompress [return reduce [hdr rest]] ; decompress not done

    :hdr/compress = 'script [set/any 'rest first transcode/next rest]
			] ; rest is now suspect, use :rest
		]

  :key = [rebol] [ ; embedded script, only 'script compression supported
			case/all [
				:hdr/checksum [return 'bad-checksum] ; checksum not supported

    no-decompress [return reduce [hdr rest]] ; decompress not done

    rest: skip first transcode/next data 2 none ; decode embedded script

    :hdr/compress [hdr/compress: unbind 'script  set/any 'rest first 
    rest]
			] ; rest is now suspect, use :rest
		]

  :hdr/compress [rest: attempt [decompress :rest]] ; :rest type-checked 
  by decompress

  not :rest [return 'bad-compress] ; only happens if above decompress 
  failed
	]

 ;assert/type [hdr object! rest [binary! block!]] ; just for documentation
	reduce [hdr rest]
][
	non-ws: charset [not 1 - 32]
]

Notes:

- The other half of the CASE/all style is a lot of explicit shortcut 
RETURN statements, whenever the normal flow differs.

- Errors are returned as a word from the error catalog, which is 
later passed to CAUSE-ERROR.

- Carl redid the checksum calculation so that scripts can verify 
against a checksum in their header, to detect corruption.

- The checksum in the header probably can't be used for the module 
checksum because the header itself matters for modules.

- Compressed scripts lost a couple minor, unimportant features that 
we are likely better without. Quiz: What features?

- Part, but not all of the reason the code is shorter is because 
the doc comments haven't been added yet. The CASE/all style helps 
though.
Maxim:
12-Oct-2010
here my simple but effective r3 search function:

;------------------------------------------------------------
search-body: funct [
	data [object! block! function!] "what to search"
	word [word!] "what to find"
	/paths "only returns paths, not their values"
	/indents i "how many tabs when listing?"
	/into blk "Add matches to this block"
	/path pth [lit-path!] "keep track of path"
][
	
	i: any [i 0]
	
	unless into [
		set 'searched-objects copy [] ; will set in "globals"
	]
	
	either block? :data [
		b: data
	][
		b: body-of :data
	]
	
	
	; locals
	item: none
	match?: false
	blk: any [blk copy []]
	pth: any [all [pth copy pth] to-lit-path ""]
	last-set-word: none
	counter: 0
	
	foreach item :b [
		counter: counter + 1
		
		result: switch/default type?/word :item [
			set-word! [
				last-set-word: :item
				false
			]
			object! [
				; prevent endless cycles on self or inter references.
				unless find searched-objects :item [
					append searched-objects :item
					either block? data [

      search-body/indents/into/path :item word i + 1 blk append copy pth 
      counter
					][

      search-body/indents/into/path :item word i + 1 blk append copy pth 
      to-word last-set-word
					]
				]
				true
			]
			function! [
				either word = to-word last-set-word [
					; adds the definition OF the searched item

     append/only blk to-lit-path append/only copy pth last-set-word
					append/only blk mold :item
				][
					if search-body/indents/into/path :item word i + 1 blk pth [
						; adds a function WITH the searched item in it

      append/only blk to-lit-path append/only copy pth last-set-word
						append/only blk mold :item
					]
				]
				true
			]
			integer! tuple! string! [
				if last-set-word [
					if word = to-word last-set-word [

      append/only blk to-lit-path append/only copy pth last-set-word
						append/only blk  :item
					]
				]
				true
			]
			block! [

    search-body/indents/into/path :item word i + 1 blk append copy pth 
    counter
				true
			]
			
			; this is what we search for
			word! [
				either :item = word [
					match?: true
				][
					false
				]
			]
			
		][
			; these types are not specifically managed by the search
			false
		]
	]
	either into [
		match?
	][
		set 'quiet-search? false
		new-line/skip blk true 2
	]
]
;----------------------------------------------
Maxim:
12-Oct-2010
oops ... the end of the function should be replaced by:

	either into [
		match?
	][
		either paths [
			blk: extract blk 2
			new-line/all blk true
		][
			new-line/skip blk true 2
		]
	]
Andreas:
19-Oct-2010
As far as I remember, there are blocks with a length field, and blocks 
without (where you'll need to skip thru encoded the characters).
Andreas:
9-Dec-2010
As mentioned by Christian and Jerry, CLEAR works for truncation:

>> write %test.txt to-binary "foobar"
>> print to-string read %test.txt
foobar
>> f: open %test.txt
>> skip f 3
>> clear f
>> close f
>> print to-string read %test.txt 
foo
Cyphre:
13-Jan-2011
not sure how fast is this, but you can use vector for diffferent 
int conversions...like:

>> uint16: make vector! [unsigned integer! 16 1]
== make vector! [unsigned integer! 16 1 [
0
]]

>> uint16/1: 300 skip to-binary uint16/1 6
== #{012C}
Kaj:
26-Jan-2011
; Extended Merge Sort, originally by Ladislav Mecir, 2004

context [
	set 'msort func [
		table [series!]
		/skip size [integer!]
		/compare columns [integer! block!]
		/reverse
	][
		unless skip [size: 1]

		if size < length? table [sort table  ; > 1 slot
			copy table
			(length? table) / size
			size
			either integer? columns [reduce [columns]] [columns]
			reverse
		]
		table
	]

	do-compare: func [
		row1 row2
		columns
		/local column a b
	][
		foreach column columns [
			unless equal? a: pick row1 column  b: pick row2 column [
				return all [b  any [not a  a < b]]
			]
		]
		true  ; Equal
	]

	sort: func [
		table shadow
		length [integer!]
		size
		columns
		reverse
		/local half middle
	][
		either length < 4 [  ; 2 or 3 slots

   if length = 3 [sort skip shadow size  skip table size  2  size columns 
   reverse]


   merge table  shadow 1  skip shadow size  length - 1  size columns 
   reverse
		][
			middle: size * half: make integer! length / 2
			sort shadow table half size columns reverse

   sort skip shadow middle  skip table middle  length: length - half 
    size columns reverse
			merge table
				shadow half
				skip shadow middle  length
				size columns reverse
		]
	]

	merge: func [
		table  shadow length  shadow2 length2
		size
		columns
		reverse
	][
		until [

   either either reverse [do-compare shadow2 shadow columns] [do-compare 
   shadow shadow2 columns] [
				table: change table  copy/part shadow size
				shadow: skip shadow size
				-- length
				zero? length
			][
				table: change table  copy/part shadow2 size
				shadow2: skip shadow2 size
				-- length2
				zero? length2
			]
		]
		change change table
			copy/part shadow  length * size
			copy/part shadow2  length2 * size
	]
]
Steeve:
27-Jan-2011
Got an iterative msort-do for R3:

msort: func [s l /local mid end rest step][
    forskip s 2 [
        unless (compare s/1 s/2) [swap s next s]
    ]
    step: 2
    loop -1 + log-2 l [
        rest: forskip s step * 2 [
            merge s             step 
                  skip s step   step
            s
        ]
        unless empty? end: skip rest step [
            merge rest      step
                  end       length? end
        ]
        step: step * 2
    ]
]

Not fully tested though...sorry
Maxim:
2-Feb-2011
is carl even aware that there is a cURL binding right now and that 
maybe he can skip this for now?
GrahamC:
3-Feb-2011
possible? worthile?

foreach [ a b c 3 d e ] list [ ... 3 = skip 3 elements ]
GrahamC:
4-Mar-2011
How bad would it be to have a strict  version of rebol vs a relaxed 
version.  I'm thinking of things like skip which require an integer 
and choke on none ...
Pekr:
5-Mar-2011
http://www.rebol.net/wiki/Ports
http://www.rebol.net/wiki/Port_Examples

http://www.rebol.net/r3blogs/0130.html- More about Port layers - 
the OSI Model

http://www.rebol.net/r3blogs/0129.html- Simple TCP example: HTTP 
web page transfer
http://www.rebol.net/r3blogs/0128.html- Skip and Seek on ports
http://www.rebol.net/wiki/TCP_Port_Details
BrianH:
10-Apr-2011
Andreas, by %user.r, I mean a file that would be loaded from the 
user's home directory or some subdirectory of it (.rebol, %appdata%\REBOL, 
whatever), and which could be manually writeable by the user when 
REBOL isn't running (or else its syntax wouldn't need to be human-readable 
and writeable). If you decide to skip any of those constraints, you 
can secure it despite the limited security models of most the OSes 
we support.
Maxim:
27-Apr-2011
don't know if it works in R3 though....

	;------------------------------------------------------------
	;- DATE STUFF
	;------------------------------------------------------------
	; use this to prevent having to supply a spec all the time.
    ; the /default option of date-time sets this.
	default-date-time-spec: "YYYY/MM/DD-hh:mm:ss"
	                             
	
	;--------------------
	;-    date-time()
	;--------------------
	date-time: func [
		""
		/with spec ; specify

  /using thedate [string! date! time!] ; specify an explicit date instead 
  of now()
		/default
		/local str date-rules thetime
	][
		vin/tags ["date-time()"] [date-time]
		
		str: copy ""
		
		
		either spec [
			if default [
				default-date-time-spec: spec
			]
		][
			spec: default-date-time-spec
		]
		
		unless thedate [
			thedate: now/precise
		]
		
		
		if thedate/time [
			thetime: thedate/time
		]
		
		filler: complement charset "YMDHhmspP"
		;spec: "YYYY/MM/DD-H^^hmmP"
		;error: spec
		itime: true
		
		unless parse/case spec [
			some [
				here:
				(error: here)
				["YYYY" (append str thedate/year)] | 

    ["YY" (append str copy/part at to-string thedate/year 3 2)] | 
				["MM" (append str zfill thedate/month 2)] |
				["DD" (append str zfill thedate/day 2)] |
				["M" (append str thedate/month)] |
				["D" (append str thedate/day)] |

				["hh" (append str zfill thetime/hour 2)] |
				["mm" (append str zfill thetime/minute 2)] |
				["ss" (append str zfill to-integer thetime/second 2)] |

    ["rrrr" (append str fill/with/right/truncate (remainder thetime/second 
    1 4) "0" )] |
				
				["P" (append str "#@#@#@#")] | 
				["p" (append str "[--:--]@[--:--]")] | 
				["H" (
					itime: remainder thetime/hour 12
					if 0 = itime [ itime: 12]
					append str itime
					itime: either thetime/hour >= 12 ["PM"]["AM"]
					)
				] |
				["h" (append str thetime/hour)] |
				["m" (append str thetime/minute)] |
				["s" (append str to-integer thetime/second)] |
				["r" (append str remainder thetime/second 1)] |
				["^^" copy val skip (append str val)] |
				
				[copy val some filler (append str val)]
				
			]
			(replace str "#@#@#@#" any [to-string itime ""])
			(replace str "[--:--]@[--:--]" lowercase any [to-string itime ""])
		][
			print ["date-time() DATE FORMAT ERROR: " spec]
			print ["  starting at: "  error ]
			print ["  valid so far: " str ]
		]
		vout/tags [date-time]
		str
	]
onetom:
28-Apr-2011
here is my ObjectID routine a'la mongodb.

wondering how much simpler could it be in r3?...  not that i could 
use r3 any time soon for production stuff, but i would love to, of 
course

  rejoin probe reduce [
    to-hex date-to-epoch now

    enbase/base copy/part checksum/method system/network/host 'md5 3 
    16
    skip to-hex access-os 'pid 4
    skip to-hex random/secure to-integer #ffffff 2
  ]
Jerry:
24-May-2011
Why does SKIP accept LOGIC! and PAIR! as its OFFSET parameter? Thanks.
Geomol:
24-May-2011
About logic, I guess, it's related to a wish to use PICK with logic 
argument. It works like this for SKIP:

>> skip [a b] true
== [a b]
>> skip [a b] false
== [b]

and you can use PICK instead of EITHER sometimes like:

value: pick [1 2] b > 1

instead of

value: either b > 1 [1] [2]
Jerry:
24-May-2011
SKIP with TRUE as its 2nd argument, which made me think it DID skip. 
SKIP with FALSE as its 2nd argument, which made me think it DIDN'T 
skip. With your PICK example, now I understand.
Endo:
24-May-2011
SKIP with LOGIC value seems reverse,  because it doesn't convert 
logic to integer before use it:
>> to-integer true
== 1
Geomol:
26-May-2011
I agree on distinguish between closures and functions, but maybe 
those whould be the only two, and then skip native and action. I 
remember being a bit confused about especially action! types, when 
I started on REBOL.
Geomol:
6-Jun-2011
In R3, BACK doens't behave as SKIP ... -1.

>> s: [1 2 3 4]
== [1 2 3 4]
>> t: skip s 3
== [4]
>> remove/part s 3
== [4]

Now it takes 3 x BACK t to see anything:

>> back back back t
== [4]

while it only takes 2 x skip -1:

>> skip skip t -1 -1
== [4]

I'm not sure, if this is known or desired behaviour.
BrianH:
6-Jun-2011
In R2, indexes are constrained to the bounds of the series they reference, 
so if you shorten the series you lose your position. In R3 your position 
is preserved for most of the standard operations, just in case you 
add back to the series later. The operations that can't possibly 
work for those out-of-bounds references trigger errors (mostly modifying 
operations), and the ones that could work if you consider series 
bounds to be an implementation detail and out-of-bounds values to 
be just not there return none (data access functions). SKIP is an 
exception, afaik, to allow you to sync up with the bounds - useful, 
but I don't remember whether it was intentional or a happy accident.
>> a: "abc"
== "abc"
>> c: skip a 2
== "c"
>> remove/part a 2
== "c"
>> index? skip c 0
== 2
>> index? c
== 3
Geomol:
6-Jun-2011
Desiding what to do with block indexes out of range is a tough call, 
I think. I understand the argument not to cause errors, if it can 
be handled somehow, but I'm not sure, handling out-of-range problems 
is always good. What if it's a user bug in the code, that made the 
index get out of range? Then the user won't easily find that bug, 
as it causes no error.


It's not possible to index a block lower than 1 (first element). 
It's only possible to index out of range in the other end of the 
block, getting past the tail. And that can only be done by having 
an index there, and then remove something from earlier in the block. 
When the index is beyond the tail, then it has to be desided what 
to do with
	insert, remove, skip, next, back, pick, select, append
used on that index. (and maybe more like TAIL?, INDEX?, ...)

What does other languages do?
BrianH:
6-Jun-2011
Only the part with the behavior of SKIP might be an accident. The 
rest was the result of a blog discussion over two years ago, which 
iirc happened while Ladislav was taking a break from REBOL.
Ladislav:
6-Jun-2011
In my opinion, this is clearly unsettled (BACK vs. SKIP), and was 
not discussed before
BrianH:
6-Jun-2011
No, SKIP wasn't discussed. The rest was.
BrianH:
6-Jun-2011
I think so, but it was in that private world where Carl's GUI for 
R3 was being worked on with Henrik and me. It looks like INSERT works 
like SKIP.
BrianH:
6-Jun-2011
Or we could just say that INSERT, APPEND, SKIP, AT and LENGTH? are 
constrained to bounds, while PICK, POKE, and the ordinals and path 
accesses that are based on them are not.
Ladislav:
6-Jun-2011
regarding the incompatibility of SKIP -1 and BACK - I am not sure, 
whether that is good to have.
BrianH:
6-Jun-2011
I think that the incompatibility of NEXT and BACK is more important, 
and definitely an error, and an accident.
>> a: [1 2 3]
== [1 2 3]
>> b: skip a 2
== [3]
>> remove/part a 3
== []
>> index? b
== 3
>> index? next b

== 3  ; constrained to the argument index, not even the series bounds
>> index? back b
== 2 ; not constrained to the series bounds
>> index? back a
== 1 ; constrained to the head
Geomol:
7-Jun-2011
I noticed a funny thing, when inserting a series in the same series 
with the /only refinement.

>> s: [a b c]
== [a b c]
>> length? skip s 2
== 1				; makes sense
>> insert/only s skip s 2
== [a b c]
>> s

== [[...] a b c]		; reference to the same series is shown this way, 
ok
>> length? s/1
== 2				; unexpected

Wouldn't it be more logical, if that last result were 1?
It's the same in R2.
1001 / 122812345...910[11] 1213