AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 134 |
r3wp | 1094 |
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 / 1228 | 1 | 2 | 3 | 4 | 5 | ... | 9 | 10 | [11] | 12 | 13 |