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

[REBOL] Words, Bindings and Contexts. (8)

From: lmecir:geocities at: 29-Jul-2000 9:56

The last part was about the behaviour of Rebol Functions. The present behaviour can be called "Computed Quasi Static Binding with Dynamic Recursion Patch." Interesting about the "Computed Quasi Static Binding" is, that it can handle recursion even without the "Dynamic Recursion Patch", as can be seen in the next model: ; Model of Context creation: ; ************************** make-context: func [ {create a Context containing given Words} words [block!] /local context-init result ] [ ; this implementation has got an issue: ; the created Context always contains 'Self words: difference/only words [self] context-init: make block! 4 * length? words foreach word words [ append context-init to set-word! word append context-init none append context-init :unset append context-init to lit-word! word ] result: make object! context-init unset in result 'self result ] { The following version of Same-context? uses Make-context to look more natural: } same-context?: func [ {find out, if the given Words are the Words of the same Context} word1 [word!] word2 [word!] ] [ either special-context? word2 [ special-context? word1 ] [ same? word1 bind in make-context reduce [word1] word1 word2 ] ] ; Model of CQSB function: ; ***************************** cqsb-function!: make object! [ ; every cqsb function has got a Spec attribute spec: none ; every cqsb function has got a Body attribute body: none ] ; Model of CQSB Func function: ; ********************************* cqsb-func: func [ {create a CQSB-function!} spec [block!] body [block!] /local spec-too body-too ] [ spec-too: copy spec body-too: copy/deep body make cqsb-function! [ spec: spec-too body: body-too ] ] ; Model of the CQSB function body execution: ; ******************************************* ; the same as for Sim-function do-body: func [body] [do body] ; Model of CQSB function Evaluation: ; *********************************** cqsb-evaluate: func [ {evaluate a sim-function contained in a block with its arguments} block [block!] /local cqsb-f new-context actual-values ] [ ; evaluate the arguments block: reduce block ; the executed cqsb-function is first cqsb-f: first block ; create a new Context new-context: make-context cqsb-f/spec ; give new Context words the supplied values set/any bind/copy cqsb-f/spec in new-context 'self next block ; execute the function body and return the result return do-body bind/copy cqsb-f/body in new-context 'self ] ; Some tests: ; ************** blk: copy [] probeblk: func [] [ prin mold blk prin ": " print mold reduce blk ] recfun: cqsb-func [x] [ append blk 'x either x <= 1 [ probeblk ] [ cqsb-evaluate [recfun x - 1] ] ] cqsb-evaluate [recfun 3] probeblk { Results:
>> cqsb-evaluate [recfun 3]
[x x x]: [3 2 1]
>> probeblk
[x x x]: [3 2 1] This shows, that "Pure CQSB" looks better than "CQSB with DRP". Recursion is not the only case, where "Pure CQSB" looks better. For another example, see this: } f: func [x] ['x] y: f 1 z: f 2 get y { Results:
>> get y
== 2 While Pure CQSB yields: } f: cqsb-func [x] ['x] y: cqsb-evaluate [f 1] z: cqsb-evaluate [f 2] get y { and the results:
>> get y
== 1 But, as always, everything has got its price. Pure CQSB is more demanding (every call needs a new Context/Binding). Moreover, the above implementation is not GC-bug proof. } to be continued...