Paths
[1/2] from: lmecir::mbox::vol::cz at: 22-Nov-2000 18:58
Hi Rebols,
here is a polished version of Do-path, which behaves better in a lot of
circumstances.
Regards
Ladislav
Rebol [
Title: "Do-path"
File: %do-path.r
Author: "Ladislav Mecir"
Email: [lmecir--mbox--vol--cz]
Date: 22/11/2000
Purpose: {
A referentially transparent way to invoke paths in Rebol
}
Category: [General]
]
do-path: function [
{
A referentially transparent way
to invoke a path.
Usage:
do-path [something /r1 /r2 ... /end-path a1 a2 ...]
/end-path can be omitted, if no args are supplied.
Values between Something and /end-path are ignored,
if they don't evaluate to refinements.
}
[throw]
blk [block!]
] [something path ref] [
set/any [something blk] do/next blk
path: make path! reduce [
either word? get/any 'something [something] ['something]
]
until [
any [
empty? blk
(
set/any [ref blk] do/next blk
if refinement? get/any 'ref [
not if /end-path <> ref [
insert tail :path to word! ref
]
]
)
]
]
do head insert/only copy blk :path
]
{
;Joel's examples:
bunchanums: [3 1 35 8 4 5 52 42 19 13 32 43 81 2 6 34 46]
tally: make object! [
tot: 0
zero: does [tot: 0]
up: func [/by n [number!]] [tot: tot + either by [n] [1]]
down: func [/by n [number!]] [tot: tot - either by [n] [1]]
now?: does [tot]
]
; Joel's example #1:
use [evens odds] [
evens: make tally []
odds: make tally []
foreach num bunchanums [
do-path [either even? num [evens] [odds] /up /by /end-path num]
]
print ["evens:" do-path [evens /now?] " odds:" do-path [odds /now?]]
]
; Result:
; evens: 226 odds: 200
; Joel's example #2:
use [diffs] [
diffs: make tally []
foreach num bunchanums [
do-path [diffs either even? num [/up] [/down] /by /end-path num]
]
print ["net sum:" do-path [diffs /now?]]
]
; Result:
; net sum: 26
; Example #3:
do-path [now /time /second]
; Example #4:
probe head do-path [:insert if find ask "Only?(y/n) " "y" [/only] /end-path
copy [] [1]]
}
[2/2] from: lmecir:mbox:vol:cz at: 22-Nov-2000 21:07
Hi,
sorry for posting "the same thing" twice,
but I realized, that the program shall not ignore integers as refinements.
Regards
Ladislav
Rebol [
Title: "Do-path"
File: %do-path.r
Date: 23/11/2000
Author: "Ladislav Mecir"
Email: [lmecir--mbox--vol--cz]
Purpose: {
A referentially transparent way to invoke paths in Rebol
}
Category: [General]
]
do-path: function [
{
A referentially transparent way
to invoke a path.
Usage:
do-path [something /r1 /r2 ... /end-path a1 a2 ...]
/end-path can be omitted, if no args are supplied.
Values between Something and /end-path are ignored,
if they don't evaluate to refinements or integers.
}
[throw]
blk [block!]
] [something path ref] [
set/any [something blk] do/next blk
path: make path! reduce [
either word? get/any 'something [something] ['something]
]
until [
any [
empty? blk
(
set/any [ref blk] do/next blk
if any [
refinement? get/any 'ref
integer? get/any 'ref
] [
not if /end-path <> ref [
insert tail :path either refinement? ref [
to word! ref
] [
ref
]
]
]
)
]
]
do head insert/only copy blk :path
]
{
;Joel's examples:
bunchanums: [3 1 35 8 4 5 52 42 19 13 32 43 81 2 6 34 46]
tally: make object! [
tot: 0
zero: does [tot: 0]
up: func [/by n [number!]] [tot: tot + either by [n] [1]]
down: func [/by n [number!]] [tot: tot - either by [n] [1]]
now?: does [tot]
]
; Joel's example #1:
use [evens odds] [
evens: make tally []
odds: make tally []
foreach num bunchanums [
do-path [either even? num [evens] [odds] /up /by /end-path num]
]
print ["evens:" do-path [evens /now?] " odds:" do-path [odds /now?]]
]
; Result:
; evens: 226 odds: 200
; Joel's example #2:
use [diffs] [
diffs: make tally []
foreach num bunchanums [
do-path [diffs either even? num [/up] [/down] /by /end-path num]
]
print ["net sum:" do-path [diffs /now?]]
]
; Result:
; net sum: 26
; Example #3:
do-path [now /time /second]
; Example #4:
probe head do-path [:insert if find ask "Only?(y/n) " "y" [/only] /end-path
copy [] [1]]
; Example #5:
a: [1 2 3]
do-path [a 1 + 1]
}