Hi Michael,

here's another idea:

1. Use refine-func instead of func to create a function.
2. Use call-with-refine to call a function with refinements.

Example:

Given the function f:
f: func [/a /b /c][if a [print 'a] if b [print 'b] if c [print 'c]]

You can create a calling function g:
g: refine-func [/a /b /c] [ call-with-refine f refinements ]

Such that:
>> g
== false
>> g/a
a
== false
>> g/b
b
== false
>> g/c
c
== false


Here are the two functions refine-func and call-with-refine:


refine-func: func [spec body /local refinements] [
  refinements: make block! length? spec
  foreach word spec [
    if all [
             refinement? word 
             word <> /local
           ]
    [
      append refinements to word! word
    ]
  ]
  insert body compose/deep [
    refinements: make block! 0 
    foreach word [(refinements)] [
      if get :word [ append refinements word ] 
    ]

  ]
  either found? find spec /local [
    append spec 'refinements
  ][
    append spec [/local refinements]
  ]
  return func spec body
]

call-with-refine: func [:f ref-block [block!] /local g] [
  g: make path! compose [f (ref-block)]
  g
]

Oh, by the way, the function defined as

g: refine-func [/a /b /c] [ call-with-refine f refinements ]

ends up looking like this:

>> source g
g: func [/a /b /c /local refinements][
    refinements: make block! 0
    foreach word [a b c] [
        if get :word [append refinements word]] call-with-refine f
refinements]
>>

At 12:50 PM 5/24/00 -0700, you wrote:
>A while back a message was posted to the list (can't find it now) about
>wanting to loop on the refinements specified to a function, without an 'if
>for each one. I've finally come up with a reason to do something similar: I
>want to pass all of the given refinements to another function. That is:
>
>- I call func A, giving some refinements
>- func A calls func B with all of the refinements given to func A
>
>I have been doing the 'if thing on each possible refinent of A and
>performing a different (hard-coded) call of B with each different
>refinement, but this would get messy if I were to specify more than one
>refinement at a time. I have found an "automatic" way of building the
>funcname/refinement string, but I haven't found any "slick" way of doing it.
>BTW the code below could be improved by recognizing only refinement! from
>the first func block. However, I haven't decided whether I even want to use
>it.
>
>f1: function [/a /b /c][local1 local2 local3][
>       ; Calls function F2 with the refinements given to this function
>       ; MUST define [local1 local2 local3] (exactly) as locals to this
>function
>       local3: :f1
>       do bind refine 'local1
>       do join "f2" local1
>]
>
>f2: func [/a /b /c][if a [print "a"] if b [print "b"] if c [print "c"]]
>
>; Then, somewhere in the code specify the block:
>refine: [
>       local1: make string! length? first :local3
>       ; Assume that no other parameters were specified
>       repeat local2 length? first :local3 [
>               if true = get bind to-word pick first :local3 local2 'local1
>                       [append local1 join "/" pick first :local3 local2]
>       ]
>]
>
>; Example use:
>>> f1/b
>b
>== none
>>> f1/b/c
>b
>c
>- Michael Jelinek
>
>
>

;- Elan >> [: - )]

Reply via email to