Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Refinements

 [1/11] from: robert::muench::robertmuench::de at: 12-Nov-2002 17:48


Hi, I have a bunch of functions that have the same two refinements: /left /right How can I propagate refinements from a function when calling an other function? Example: my-func1: func [param /left /right][ either left [side: ??][side: ??] my-func2/side ?? ] my-func2: func [param /left /right][ ] Robert

 [2/11] from: jan:skibinski:sympatico:ca at: 12-Nov-2002 14:03


Hi Robert, I am sure there are many ways of approaching this task. Here is one: Provided are three functions: 'f1, 'f2 and refine. F2 is a worker, 'f1 is your caller and 'refine is a dispatching utility. Example:
>> f1 "Robert"
== "Robert is in the middle"
>> f1/left "Robert"
== "Robert is on the left"
>> f1/right "Robert"
== "Robert is on the right" Regards, Jan ------------------------------------------------------- f1: func [ x /left /right /local f ][ either left [ f: refine/left :f2 ][ either right [ f: refine/right :f2 ][ f: refine :f2 ] ] comment { Do what you need to do here and finally call your f2 with a preselected refinement} f x ] f2: func [ x /left /right ][ either left [ rejoin ["" x " is on the left"] ][ either right [ rejoin ["" x " is on the right"] ][ rejoin ["" x " is in the middle"] ] ] ] refine: func [ {Select a refinement /left /right or none for a function 'f} f [any-function!] /left /right /local result ][ pipe: func[fs][make function! [x] append copy fs 'x] either left [ result: pipe [f/left] ][ either right [ result: pipe [f/right] ][ result: pipe [f] ] ] :result ] Robert M. Muench wrote:

 [3/11] from: greggirwin:mindspring at: 12-Nov-2002 12:02


Hi Robert, RMM> Hi, I have a bunch of functions that have the same two refinements: RMM> /left /right RMM> How can I propagate refinements from a function when calling an other RMM> function? There is no easy, native, way that I know of. Ladislav has a REFINED function in his highfun.r script, if that will work for you. Sometimes I've added a refinment which allows me to specify a block of custom options (i.e. refinements) for easy propagation. Here's the basic idea: my-func: func [/with options [any-block!] /local ?opt] [ either with [ attempt [ ;<< ATTEMPT requires beta release or patch if find options 'a [print "option A specified"] if options/b [ print ["option B specified. Value =" options/b] ] ] ][ print "no options" ] ] my-func my-func/with [a] my-func/with [b 2] my-func/with [a b 2] Not nearly as clean as native refinements, but much easier to propagate. -- Gregg

 [4/11] from: robert:muench:robertmuench at: 13-Nov-2002 8:37


> -----Original Message----- > From: [rebol-bounce--rebol--com] [mailto:[rebol-bounce--rebol--com]]
<<quoted lines omitted: 4>>
> I am sure there are many ways of approaching this task. > Here is one:
Hi Jan, thanks for the info. I'm going to try it. This makes it possible to have the refinement-check-code in the beginning of a function and avoid execution-code dublication. Robert

 [5/11] from: lmecir:mbox:vol:cz at: 13-Nov-2002 14:06


Hi Robert, have a look at my APPLY function, that can be found in http://www.rebolforces.com/~ladislav/highfun.r Some suggested usages: apply/n :subtract [value2: 1 value1: 2] ; == 1 test-fn: func [a b /ref-c c /ref-d d] [ print ["A:" a] print ["B:" b] if ref-c [ print ["C:" c] ] if ref-d [ print ["D:" d] ] ] apply/r/n :test-fn [ref-d ref-c] [d: 1 c: 2 b: 3 a: 4] A: 4 B: 3 C: 2 D: 1 etc. -L

 [6/11] from: joel:neely:fedex at: 13-Nov-2002 17:07


Hi, Robert, Just one more idea to throw into the discussion (I think! ;-) Robert M. Muench wrote:
> Hi, I have a bunch of functions that have the same two refinements: > /left /right
<<quoted lines omitted: 7>>
> my-func2: func [param /left /right][ > ]
I assume we want to avoid something like ... my-func2: func [param /left /right] [ either left [ either right [ my-func2/left/right twiddle param ][ my-func2/left twiddle param ] ][ either right [ my-func2/right twiddle param ][ my-func2 twiddle param ] ] ] my-func2: func [param /left /right] [ ;... ] ... for several reasons: 1) It's too easy to make a typo in all that "boilerplate"; 2) It's too hard to maintain; 3) It doesn't scale well (every added refinement doubles the amount of code required) 4) There's a time penalty for all of the "glue" that doesn't add useful computing. In addition, something like ... turn: func [n [integer!] /left /right /around][ if left [prin "turn left and then "] if right [prin "turn right and then "] if around [prin "turn around and then "] print ["walk" n "steps"] ] march: func [/left /right /around /local action activity][ action: copy [turn] activity: [10] if left [append action 'left] if right [append action 'right] if around [append action 'around] do head insert/only copy activity to-path action ] ... has the overhead of assembling the block to be DOne on every evaluation. That leads me to wonder about giving each refinement an explicit logical value, which can be passed on easily (with a bit of typing effort, to be sure) ... my-func2: func [ param /left leftparam [logic!] /right rightparam [logic!] ][ my-func2/left/right twiddle param leftparam rightparam ] my-func2: func [ param /left leftparam [logic!] /right rightparam [logic!] ][ ;... ] ... where LEFTPARAM and RIGHTPARAM take the place of the "flag-like" /LEFT and /RIGHT from before. Your thoughts? -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446

 [7/11] from: jan:skibinski:sympatico:ca at: 13-Nov-2002 18:43


Joel,
> That leads me to wonder about giving each refinement an explicit > logical value, which can be passed on easily (with a bit of typing > effort, to be sure) ...
I have recently come to a similar conclusion, but for a bit different reason: one cannot do direct logical operations on refinements. For example, in the type checker I work on I have two refinements: /debug and /step: the former is for me as a developer, the later for a user to show step-by-step reductions. But there are cases where I would like to print the same mesage for either refinement. I ended up defining the corresponding local logical variables instead, so I can or- them together if needed. Moreover, I removed the refinements from a worker function, and just call it with explicit arguments 'debug and 'step. The worker is not to be used directly (unless for a testing), so it does not make much sense to maintain the refinements at that very low level. Jan

 [8/11] from: rotenca:telvia:it at: 14-Nov-2002 16:58


Hi Jan,
> I ended up defining the corresponding local logical variables > instead, so I can or- them together if needed. Moreover, I removed > the refinements from a worker function, and just call it with > explicit arguments 'debug and 'step. The worker is not to > be used directly (unless for a testing), so it does not make much > sense to maintain the refinements at that very low level.
Sometime i make: context [ foo: func [left right ][print [left right]] system/words/foo: func [/left /right ][foo left right] ] --- Ciao Romano

 [9/11] from: joel:neely:fedex at: 14-Nov-2002 9:48


Hi, Jan, RDOIT! (REBOL Does Its Own Thing!) See below... Jan Skibinski wrote:
> Joel, > > That leads me to wonder about giving each refinement an explicit
<<quoted lines omitted: 4>>
> I ended up defining the corresponding local logical variables > instead, so I can or- them together if needed...
Although OR is picky about the types of its arguments (for no good reason that I can understand, as IF and EITHER allow NONE to proxy for FALSE), you can use ANY instead as a "generalized OR", and ALL as a "generalized AND" with either LOGIC! or NONE values ... tester: func [/ref0 /ref1] [ print [ "ref0 was" either ref0 ["set"]["absent"] newline "ref1 was" either ref1 ["set"]["absent"] newline either any [ref0 ref1] [ either all [ref0 ref1] [ "both were set" ][ "one was set" ] ][ "neither was set" ] ] ] ... which behaves as ....
>> tester
ref0 was absent ref1 was absent neither was set
>> tester/ref0
ref0 was set ref1 was absent one was set
>> tester/ref1
ref0 was absent ref1 was set one was set
>> tester/ref0/ref1
ref0 was set ref1 was set both were set HTH! -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446

 [10/11] from: jan:skibinski:sympatico:ca at: 14-Nov-2002 11:29


Hi Joel,
> RDOIT! (REBOL Does Its Own Thing!)
RDIOT? Hmm.. A danger of acronyms :-) Once during development of a big numerical library for a language Xyz we have been tagging our documentation by XyzNUM- tags. Hundreds of such words. And one day a bored person from their marketing department caused us to change them all to XyzMATH because of possible association with XyzDUMB. Afraid that global search and replace would not work properly we had to do it on file by file basis.
> Although OR is picky about the types of its arguments (for no good > reason that I can understand, as IF and EITHER allow NONE to proxy > for FALSE), you can use ANY instead as a "generalized OR", and ALL > as a "generalized AND" with either LOGIC! or NONE values ...
I should have thought about it. Thanks. BTW, since I sort of feel uncomfortable with the NONE business (depending on the context) I often end up with doing "either not none? any xs [][]" . Jan

 [11/11] from: jan:skibinski:sympatico:ca at: 14-Nov-2002 12:03


Hi Romano, Thanks for the tip Jan

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted