Passing refinements to sub functions.
[1/7] from: bhandley::zip::com::au at: 8-Aug-2000 22:05
Hi list,
Often I have a function built on another. Sometimes the lower function has
refinement that I want to surface on the higher function. If there is one
refinement I just use an either. If there are more this approach becomes a
real pain.
I've come up the solution of creating an object with the refinements as
fields and passing that. But I still have a bit of code creating the object
in the first place. An alternative is using a block with set words and
values, but I haven't figured how to use this effectively (that is I suspect
I need
bind but I haven't got it working yet).
Has anyone an elegant solution for passing multiple refinements down the
line?
Brett.
--
>> my-rebol-stuff
== http://www.zipworld.com.au/~bhandley/rebol
[2/7] from: jelinem1:nationwide at: 8-Aug-2000 8:39
I haven't come up with an 'simple,elegant' solution to this. The more i
tried to automate this, the more work it became until in the end it was
easier just to deal with all if the refinement cases manually. I did create
a passable solution in which I'm able to pass all of the values of a set of
refinements to a lower-level function as a block of logic! with only a line
or two of code in the high-level function. I can dig it back up if you're
interested.
- Michael Jelinek
[bhandley--zip--com--au] on 08/08/2000 07:05:12 AM
From: [bhandley--zip--com--au] on 08/08/2000 07:05 AM
Please respond to [list--rebol--com]
To: [list--rebol--com]
cc:
Subject: [REBOL] Passing refinements to sub functions.
Hi list,
Often I have a function built on another. Sometimes the lower function has
refinement that I want to surface on the higher function. If there is one
refinement I just use an either. If there are more this approach becomes a
real pain.
I've come up the solution of creating an object with the refinements as
fields and passing that. But I still have a bit of code creating the object
in the first place. An alternative is using a block with set words and
values, but I haven't figured how to use this effectively (that is I
suspect
I need
bind but I haven't got it working yet).
Has anyone an elegant solution for passing multiple refinements down the
line?
Brett.
--
>> my-rebol-stuff
== http://www.zipworld.com.au/~bhandley/rebol
[3/7] from: jelinem1:nationwide at: 8-Aug-2000 10:35
Well since I know you're thinking about asking for the solution I had come
up with, I'll go all out and post it here. The actual solution to loop
through the function items (refinements) is not much code, but is tedious
and messy-looking. I feel like I'm going through alot of trouble to hide
this and save a few characters in the "high-level" function, but the result
is a little easier on the eye and made me learn about contexts and 'bind.
; Say you have a high-level function (main-func) with a list of
refinements, and you want to pass all of these refinements to a lower-level
function (sub-func). The bare parameter-passing code is:
main-func: function [/va /vb /vc][this-code refine-values r][
this-code: make-code "main-func" "sub-func"
bind this-code 'some-global bind this-code 'refine-values
do this-code
]
sub-func: function [param-list][va vb vc][
set [va vb vc] param-list
print ["va:" va]
print ["vb:" vb]
print ["vc:" vc]
]
; Resulting in:
>> main-func/va/vc
va: true
vb: none
vc: true
; To support this you must define the following globally:
some-global: none
make-code: function [hi-func [string!] lo-func [string!]][code][
code: copy {
refine-values: make block! []
foreach r first :hi-func [
if (refinement? r) and (r <> /local) [
append refine-values get bind to-word r 'refine-values
]
]
lo-func refine-values
}
replace/all code "hi-func" hi-func
replace/all code "lo-func" lo-func
return(to-block code)
]
- Michael Jelinek
[bhandley--zip--com--au] on 08/08/2000 07:05:12 AM
From: [bhandley--zip--com--au] on 08/08/2000 07:05 AM
Please respond to [list--rebol--com]
To: [list--rebol--com]
cc:
Subject: [REBOL] Passing refinements to sub functions.
Hi list,
Often I have a function built on another. Sometimes the lower function has
refinement that I want to surface on the higher function. If there is one
refinement I just use an either. If there are more this approach becomes a
real pain.
I've come up the solution of creating an object with the refinements as
fields and passing that. But I still have a bit of code creating the object
in the first place. An alternative is using a block with set words and
values, but I haven't figured how to use this effectively (that is I
suspect
I need
bind but I haven't got it working yet).
Has anyone an elegant solution for passing multiple refinements down the
line?
Brett.
--
>> my-rebol-stuff
== http://www.zipworld.com.au/~bhandley/rebol
[4/7] from: bhandley:zip:au at: 12-Aug-2000 19:20
Thanks for your response Michael.
Now that's an interesting idea.
I think your approach is good at getting the refinements of the
higher-function processed as a set, but it obscures what happens after that.
My latest approach has been to use an additional refinement on the
sub-function called /refinements. This has an argument of type block that
contains pairs of refinement-name and refinement-value.
Inspired by your work I produced this.
main-func: function [/va /vb /vc][this-code refine-values r][
sub-func/refinements refinements-to-block :main-func va
]
sub-func: function [/refinements refine-list][va vb vc][
do bind refine-list 'va
print ["va:" va]
print ["vb:" vb]
print ["vc:" vc]
]
refinements-to-block: function [
hi-func
'sample-refinement
][refinement-block][
refinement-block: copy []
foreach r first :hi-func [
if (refinement? r) and (r <> /local) [
append refinement-block to-set-word r
append/only refinement-block to-paren bind reduce [to-word r]
:sample-refinement
]
]
compose refinement-block
]
It results in this:
>> main-func/vb/vc
va: none
vb: true
vc: true
Of course it doesn't handle any refinement arguments.
Brett.
[5/7] from: bhandley:zip:au at: 13-Aug-2000 16:51
Rooting around Rebol sources as the official guide book recommends, I came
across the following function (which would make my /refinements refinement
unnecessary. Now to get it to work....
>> help refined
USAGE:
REFINED f refinements
DESCRIPTION:
Create a function doing the same thing as a function with given
refinements does
REFINED is a function value.
ARGUMENTS:
f -- (Type: any-function)
refinements -- (Type: block)
(SPECIAL ATTRIBUTES)
catch
[6/7] from: lmecir:geocities at: 20-Aug-2000 22:04
Hi,
back from holiday.
You might not notice, but Refined is a function defined in
www.rebol.org/advanced/highfun.r
It was my reaction to Michael's problem, but he pointed out, that
he didn't want to use it because of its overhead...
Regards
Ladislav
[7/7] from: bhandley:zip:au at: 21-Aug-2000 10:20
That's funny. I should have checked the scripts I load by default before
checking the sources.
Now what other little gems have I unwittingly loaded?.... :)
Brett.