[REBOL] Re: New HTML Doc generator and recursing with refinements?
From: brett::codeconscious::com at: 31-Oct-2000 21:49
There has been a number of attempts at this and similar. The solutions are a
matter of preference.
Some of them are variations on a theme. Here's a sample.
____
1)
Do as you have done.
____
2)
Try out Ladislav's refined function found in highfun.r at www.rebol.org
____
3)
Create a special refinement on your function taking one argument.
Only use the refinement when you are making a recursive call from the
function itself.
Pass in an object that has a logic field for each refinement you want to
pass.
Downside: "none too pretty" argument handling.
____
4)
Create a special refinement on your function taking one argument and use
the refinement
(perhaps called "refinements") to pass in a block of set-word logic! pairs,
one for each "normal" refinement.
The trick now is interpreting them. You could use it as a object
specification. Like so:
test-func: function [
arg /test1 /test2 /refinements refines
] [mode] [
either refinements [
mode: make object! refines
][
mode: make object! compose [
test1: ( test1 )
test2: ( test2 )
]
]
if mode/test1 [
print "test1 success"
]
if mode/test2 [
print "test2 success"
]
]
>> test-func/refinements "a" [test1: true test2: true]
test1 success
test2 success
____
5)
Use the following function I created after I exploited paths behaviour when
they are evaluated.
Note: You really don't need the function. It just serves as a reminder that
you can use paths (though you
do need to get the path to be evaluated at the appropriate moment).
refine-function: function [
"Refines a function with the specified refinements." [catch]
'f "The function"
refinements [any-block!]
][p][
p: to-path head insert/only head copy refinements f
:p
]
Here's an example of using it.
test-func: func[ /test-a /test-b ][
print "test-func"
if test-a [ print "test-a" ]
if test-b [ print "test-b" ]
]
>> my-refined-function: refine-function test-func [test-a test-b]
== test-func/test-a/test-b
>> my-refined-function
test-func
test-a
test-b
____
6
A combined approach for a recursive function that I developed while trying
to answer your post - thus not heavily tested.
recursive-func: function [
arg [integer!]
/test-a
/test-b
/mode refined-mode [path!]
] [recursive-call refinements] [
; Lets set the "mode" it it hasn't been done already (The Overhead)
; If you didn't want the overhead, you could do this outside the
function.
if not mode [
refinements: copy [mode] ; Need mode here for the recursive call
later.
if test-a [insert tail refinements 'test-a]
if test-b [insert tail refinements 'test-b]
refined-mode: refine refinements
]
; Now form the recursive call (playing with paths).
recursive-call: refine-function recursive-func (to-block :refined-mode)
; Now the real logic of this function (with a touch of overhead)
print "test-func"
if test-a [ print "test-a" ]
if test-b [ print "test-b" ]
if greater? arg 1 [
recursive-call (subtract arg 1) (:refined-mode)
]
]
While it looks heavy, I think it is worth with especially if you have over
two refinements. It don't know how it will
fair in performance terms - it would be interesting to see. However, my main
use for this will be to aid readability
of my scripts.
____
...
No doubt there would be other schemes. I have a feeling that this was going
to get attention in the language at some point - but I could be wrong.
Brett.