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

[REBOL] context of a function Re:(3)

From: rebol:techscribe at: 21-Aug-2000 19:06

Hi Frank, I think you are speaking about three distinct, albeit related tasks: 1. Determining which words are bound to the context of a function. 2. Binding words that are bound in the context of a function to that context. 3. Determining which values these words are associated with. Re 1: You can easily determine which words are bound to the context of a function by retrieving the first or third block of a function.
>> f: func [a /ref /local b] [ a ] >> first :f
== [a /ref /local b]
>> third :f
== [a /ref /local b] With exception of /local all of these words are bound to the function's context, as soon as the function is constructed.
>> fblock: foreach word first :f [
if word <> /local [ append [] to word! word ] ] == [a ref b] Re 2: You can easily bind the words in the function's first or third block to the function's context:
>> bind fblock first second :f
== [a ref b] Re 3: You can now easily determine which values the words are associated with in the function's context: Becase the function has not been evaluated yet:
>> reduce fblock
** Script Error: a has no value. ** Where: a ref b Once the function is evaluated with some argument:
>> f "this is some arg"
== "this is some arg" The new value binding for a is reflected in the fblock
>> reduce fblock
== ["this is some arg" none none] Conclusion: This approach only works if there is at least one word that is local to the function's context available at a known index in the function's body. In this example it was the word "a" in the first position in the function's body.
>> source f
f: func [a /ref /local b][a] My previous proposal to provide an enhanced function constructor was intended to provide a uniform word, that is known to be local to the function and is guaranteed to be available at a known, predefined location. To refresh your memory cfunc: func [spec body] [ "Defines a user function with given spec and body and adds the word self." [catch] spec [block!] {Help string (opt) followed by arg words (and opt type and string)} body [block!] "The body block of the function" either found? find spec /local [ insert tail spec 'self ][ insert tail spec [/local self] ] insert body 'self throw-on-error [make function! spec body] ] A few convenience functions: get-context-block: func ['f /local block] [ either all [ function? get :f (pick second get :f 1) = 'self ] [ fblock: make block! length? first get :f foreach word first get :f [ if not :word = /local [ append fblock to word! word ] ] return bind fblock first second get :f ][ return none ] ] Now, given the cfunc
>> cf: cfunc [arg /ref /local local-word] []
I can say:
>> cb: get-context-block f
== [arg ref local-word self] The words are already bound to the context, but because the function has not been evaluated the have not been assigned any values yet. Therefore trying to get their values fails with an error:
>> reduce cb
** Script Error: arg has no value. ** Where: arg ref local-word self However, if the function is evaluated with some argument:
>> cf "this is an argument passed to cf."
== none we can determine which values have been associated with the words:
>> reduce cb
== ["this is an argument passed to cf." none none none] Hope this helps At 11:21 AM 8/21/00 +0200, you wrote:
>On Fri, 18 Aug 2000 [brian--hawley--bigfoot--com] wrote: > >> Frank Sievert ([fsievert--uos--de]) wrote: >> >Is there a way to get the words of the context of a function? >> >> Not directly. >> >> >Example: >> > f: func [a] [] >> > g: func [a] [print a] >> > >> >Does anyone know a way to change function f AFTER its definition >> >in that way, that it will work like function g? >> >> f: :g > >;) > >> The contexts of functions are not properly persistent. While >> REBOL does save a context for each function, it only does so >> for the purpose of reuse. The values of the words in that >> context are trounced with every call to the function. > >I don't want to get the context, Or the value of the word. I want to get >a word bound to the context of the function. That is a difference. > > make-fun: func [/local a] [ > f: func [a] [a] > append second :f 'a > ] > > >> make-fun > >> probe :f > func [a] [a a] > >To serialize function "f" I must have a chance to find out, which of >the words are bound to function "f"s context and which not. > >This binding must be persistent. I think it would be a good idea, if >make function! would bind the third and first of the function to functions >context. > >Greetings, >Frank >
;- Elan [ : - ) ] author of REBOL: THE OFFICIAL GUIDE REBOL Press: The Official Source for REBOL Books http://www.REBOLpress.com visit me at http://www.TechScribe.com