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

[REBOL] Re: Elegant way to reference a function?

From: joel:neely:fedex at: 4-Dec-2001 8:50

Hi, Patrick, pat665 wrote:
> Hi Chaz, > > I did not know what a context was so I went for the doc. It > reads "This is a shortcut for MAKE OBJECT!. ". So a context > is an other name for an object. I'm afraid I don't understand > how it will help me. Do you have more on this ? >
Unfortunately the context to Chaz referred is not the CONTEXT word pre-defined to the interpreter. curmudgeonly-opinion: { Of all the examples of nearly-useless redundant words, creating a "shortcut" for the two-word phrase MAKE OBJECT! (thus saving a whole 4 keystrokes!) is The Worst Example of A Bad Idea, most especially because it overloads what is already a barely-documented concept central to understanding REBOL. } Here's the meaning of "context" (the idea, not the so-called shortcut...) by comparison/contrast with other languages: In many programming languages, variables are just names for addresses in memory into which one may store data. The job of the compiler was to generate code by translating variable names into the corresponding memory addresses. Once we programmers started breaking programs into idea-sized chunks (such as FORTRAN subroutines -- this is a very old issue in programming ;-), we had to deal with the idea of the "scope" of a variable, which was the portion of the source code within which a particular name had a particular address associated with it. Languages such as C are the endpoint of that evolutionary path, with various keywords to control the visibility and lifetime of these names and the associated memory addresses. In a radical departure from this model, LISP introduced the idea that symbols/names in a program were more like words in a dictionary; to find the value associated with a name, you look that name up in an appropriate dictionary and take the corresponding value found there. (Most of the LISP literature calls these dictionaries "environments".) This opened the possibility that there could be multiple dictionaries, with one or more of them being relevant for a particular range of time or code. A REBOL "context" is such a dictionary, and there are several features of REBOL which cause contexts to be created: defining a function, evaluating a USE expression, and making an object all do that. Consider this example:
>> generate-pairs: func [n [integer!] /local pair-with result] [
[ result: clear [] [ pair-with: func [m [integer!] n [integer!] /local result] [ [ result: clear [] [ repeat i n [repend/only result [m i]] [ ] [ repeat i n [append result pair-with i n] [ ]
>> result: "this is some other thing"
== "this is some other thing"
>> generate-pairs 3
== [[1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]]
>> result
== "this is some other thing" (not written for maximum efficiency, but to make a point) The word RESULT appears many times in the above transcript, but in one sense there are three words named "result". There's a global context which includes the following mapping 'result --> "this is some other thing" a context associated with GENERATE-PAIRS which includes (at the end) the mappings 'result --> [[1 1][1 2][1 3][2 1][2 2][2 3][3 1][3 2][3 3]] 'pair-with --> (...a function value...) and a context associated with that last function value above which includes (at the end) 'result --> [[3 1][3 2][3 3]] These hidden dictionaries are central to the behavior of REBOL, but their nature is for the most part undocumented. About the only semi-explicit appearance they make in REBOL is through the BIND native, which causes one or more words to become associated with a different context, based on a word from that context. Evaluating a REBOL word doesn't mean looking at a corresponding memory address fixed at compile time. Instead it means checking the context to which that word is bound, and seeing what value is associated with that word in the context "dictionary". (And there's more that may happen, depending on the type of the value that is found there, but that's a different discussion.) AFAICT (and there are many wizards on this list who will correct me if I'm wrong), one can imagine something like this: 'generate-pairs ---+ | V (global context) +----------------+---+ : ... : : 'result ----> +----------------+---+ | result | *------> "this is some other thing" +----------------+---+ | generate-pairs | *------> +----------- +----------------+---+ | ... whatever a function! : ... : : | looks like inside the +----------------+---+ | REBOL interpreter... | * +-|--------- | +--------------------------+ 'pair-with ---+ | | | V V (context for GENERATE-PAIRS) 'result ----> +-----------+---+ | result | *------> [[1 1]...] +-----------+---+ | pair-with | * | +-----------+-|-+ | V +----- | ...whatever a function! | looks like inside the | REBOL interpreter... | * +-|--- V ... you get the idea... What value you get for the symbol 'result depends on which dictionary you look it up in. Finally, since an object has a context, somebody decided that the word CONTEXT could be used as a "shortcut" for the two-word phrase MAKE OBJECT! thus providing an opportunity to confuse the two meanings. HTH! -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;