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

context of a function

 [1/28] from: fsievert:uos at: 18-Aug-2000 18:31


Hi! Is there a way to get the words of the context of a function? 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? The following does not work: insert second :f reduce ['print first first :f] Because the first (and third) of a function is not bound to the functions context. I think there is no direct way to get the word with binding, I could only get the words out of functions body :( I am working at a serialize script, which also serializes contexts etc. CU, Frank

 [2/28] from: rebol:techscribe at: 18-Aug-2000 12:55


Hi Frank, 1. The Problem: To associate the word a with the context of the f function's body, you would have to use bind. The bind function requires a sample word that is boudn to the target as its second argument. Because your body block of the function is empty, there is no sample word, and therefore there is nothing to bind to. 2. The Solution: 1. If REBOL Technologies added the following ability to the fourth function, the problem would be solved: a) Like an object has a default word self defined, which is the object itself, there should be a default word self defined for a function, and that word self should be a sample word for the function's context. b) If fourth receives a function argument, it should return the default word self that is defined for the function's context. c) We don't need to worry about people defining a local word self for the function, since that word self can take over the rule of the default word self. The fourth function will return the user defined word self instead of the default word self, and that word is just as much sample word for the local context of the function, as the default word self is. d) A problem arises if the function is intended to manipulate a global word self, since the default local word self will hide the global version of self. I haven't seen anyone complain about not being able to use a global word self from within the context of an object, and therefore I doubt that anyone will complain, if the same is true for a function. e) Another solution would be to provide a default refinement /self for every function that returns a sample word for the function's context. 3. An immediate solution We can use this approach to implement our own solution. We define a cfunc function, which emulates the func function and adds a /local word self like this: cfunc: func [spec body /local found] [ either found? found: find/tail spec /local [ insert found self ][ insert tail spec [/local self] ] insert body [self] throw-on-error [make function! spec body] ] Now we can create f as a cfunc:
>> f: cfunc [a] [] >> insert tail second :f compose [print (bind 'a first second :f)]
== []
>> f 3
3 Hope this helps, At 06:31 PM 8/18/00 +0200, you wrote:
>Hi! >Is there a way to get the words of the context of a function?
<<quoted lines omitted: 12>>
>CU, >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

 [3/28] from: galtbarber:mailandnews at: 18-Aug-2000 17:21


>> f: func [a] [a] >> aa: first second :f
== a
>> clear second :f
== []
>> append second :f 'print
== [print]
>> append second :f aa
== [print a]
>> source f
f: func [a][print a]
>> f 3
3 -Galt

 [4/28] from: brian:hawley:bigfoot at: 18-Aug-2000 20:54


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 following does not work: > insert second :f reduce ['print first first :f] > >Because the first (and third) of a function is not bound to >the functions context. > >I think there is no direct way to get the word with binding, >I could only get the words out of functions body :(
During the REBOL 2 development process REBOL was changed to specifically prohibit that kind of access. This was done to keep the interpreter from crashing. It's a bad idea to do this kind of thing, as it leads to completely unstable code.
>I am working at a serialize script, which also serializes >contexts etc.
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. If you want to write solid code in REBOL, you should pretend that the function contexts are completely volatile between calls, even if the current implementation makes this not so on some occasions. The only persistent contexts you need to concern yourself with are object contexts. If you serialize any more contexts than that, people who use your code might try to depend on persistence of contexts between sessions that aren't even persistent within the same session. If you want to use persistent values within the context of a function (like static variables in C), use the technique of embedding series or object values in the code block of the function. Do you remember the recurring discussions that begin with someone new to REBOL getting tripped up because they did a: [] in function code, expecting it to behave like a: copy [] instead? Someone always calls this a bug in the language design, but used properly it can be one of REBOL's most powerful features. For example, try this: f: func [x /local a] [ a: [] append/only a x foreach x a [print x] ] This code depends on the block embedded in the function being modified by the function, and having those changes be persistent. All you would need to save here would be the spec and code blocks of the function to be saved - it doesn't depend on the context being persistent, which is good because function contexts effectively aren't. This same technique can be used with values that aren't directly representable as literals, such as hashes, lists, bitsets, functions and objects, if you create the function code block with some function like compose. For example, in this function: alphanum?: func [s /local alphanum] compose [ alphanum: ( charset [#"a" - #"z" #"A" - #"Z" #"0" - #"9"] ) parse/all s [some alphanum] ] ..., the function charset is only called once, before the function alphanum? is created. The local variable alphanum is assigned to the now literal bitset value embedded in the code of the function, rather than being recreated every time the function is called, an expensive process. You can use this technique to speed up functions that parse using local character sets, to index using local hashes, to create local functions without having to recreate them at each call - basically anywhere you need to hide persistent values from uncontrolled modification. If you are used to programming in the functional style, with closures, this is how to have persistent data. Of course, none of this will be needed when Carl gets done with REBOL modules. When that happens you will be able to use modules for all of your information-control needs and you won't need to do these more arcane closure-type hacks. Brian Hawley

 [5/28] from: ptretter:charter at: 18-Aug-2000 21:14


Your killin me. Just when I started to think I was getting this stuff down. :) I need a beer and then I will get to thinking about this one. Time for REBtris. Paul Tretter

 [6/28] from: brian:hawley:bigfoot at: 18-Aug-2000 23:20


I wrote:
>During the REBOL 2 development process REBOL was changed to >specifically prohibit that kind of access. This was done to >keep the interpreter from crashing. It's a bad idea to do >this kind of thing, as it leads to completely unstable code.
[galtbarber--MailAndNews--com] wrote:
> >> f: func [a] [a] > >> aa: first second :f
<<quoted lines omitted: 9>>
> >> f 3 >3
Well Galt, that shows me :) Looking back, I must have remembered the change to the behavior of first and second as applied to object! values. Before, you could get at the actual word and value blocks of the objects by using those functions, and changing those blocks crashed REBOL. Those functions were changed to return copies of the blocks so the crashes wouldn't happen. For some reason, I assumed that first, second and third were changed similarly for function! values, for the same reasons. After testing, it appears that only the first function returns a copy of the argument block, keeping you from being able to modify the number of arguments the function actually takes. This leads me to believe it likely that object! and function! contexts are implemented with the same data structure inside REBOL, and that the first function as applied to functions is passed on to the internal object context. What does interest me is that the second and third functions applied to function values return the _actual_ code and spec blocks of the function! This allows you to all sorts of evil tricks, such as self- modifying code, functions that take a different number of parameters than the help says they do, etc. Evil stuff. :) On the more practical side, you could use the parse function of the code and spec blocks to patch function code and help bugs in place. Otherwise you would have to worry about loose references to the old version of the function, possibly making the system unstable. Being able to modify the original code block of a function without reassigning the function word is a security hole though, as I'll explain in my next message. Brian Hawley

 [7/28] from: agem:crosswinds at: 19-Aug-2000 21:09


hey, thats tips! funally i can dump my functions after error! Thanks, Elan! .. ugly addings by me :) [REBOL [ title: "a func with dumpable context :)" author: "Elan, Volker" purpose: { [dump-func a-func] will source & dump locals, if defined with debug-func (alias Elan's cfunc). you can set func: :debug-func because there is a original-func set too. } version: 0.0.0.4 file: %/home/volker/w/rebol/dump-func.r date: 19-Aug-2000/13:32:44+1:00 ] if not value? 'original-func [original-func: :func] dump-func: func ['f1] [ do compose [source (f1)] f1: get f1 locals: copy first :f1 bind locals first second :f1 ? locals forall locals [if word? first locals [ probe first locals probe get first locals]] ] [ ;Elan, bit modified ] debug-func: func [spec body /local found] [ either found? found: find/tail spec /local [ insert found [function-self] ][ insert tail spec [/local function-self] ] insert body [function-self] make function! spec body ] print "---" f1: debug-func [a b] [] f1 "the a" "the b" dump-func f1 f2: debug-func [/local a /opt b] [a: "in f2"] f2 dump-func f2 [; or use func allways, but func: :debug-func func: :original-func ] ()] --- [rebol--techscribe--com] wrote on 18-Aug-2000/12:55:03-7:00

 [8/28] from: fsievert:uos at: 21-Aug-2000 11:21


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?
<<quoted lines omitted: 6>>
> >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

 [9/28] from: fsievert:uos at: 21-Aug-2000 12:18


On Mon, 21 Aug 2000 I wrote:
> 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.
Hmmm... thought about it again. This would not help, because refinements don't carry bindings with them. No chance to get the /hallo from func [/hallo] [] Frank

 [10/28] from: agem:crosswinds at: 21-Aug-2000 16:50


> On Mon, 21 Aug 2000 I wrote: > > This binding must be persistent. I think it would be a good idea, if
<<quoted lines omitted: 3>>
> don't carry bindings with them. No chance to get the /hallo from > func [/hallo] []
in the function it is a normal var, maybe accessing as word instaed of refinement?
> Frank >
Volker

 [11/28] 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:
<<quoted lines omitted: 31>>
>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

 [12/28] from: brian:hawley:bigfoot at: 21-Aug-2000 23:41


Elan ([rebol--techscribe--com]) wrote:
>You can easily determine which words are bound to the context of a function >by retrieving the first or third block of a function.
<<quoted lines omitted: 11>>
>] >== [a ref b]
Actually, the word local is bound to the function as well. /local is just another refinement - it's just treated in a special way by the help function. The evaluator doesn't treat it in a special way. You can preset locals like this:
>> f: func [a /local b] [add a any [b 1]] >> f/local 1 3
== 4 I don't know about you, but I found this quite amusing. All those earnest REBOL programmers thinking /local is special, when it's really just a quick, elegant hack. I love this language :-) Brian Hawley

 [13/28] from: rebol:techscribe at: 22-Aug-2000 0:06


Hi Brian, Indeed it is. I didn't investigate that throughly enough. The implementation is not exactly consistent with its intended use. I wonder whether that's a good thing ... guess it's not likely to cause any harm. With respect to the function context binding I think it makes sense to skip /local. That is consistent with the intended use of /local.
>>With exception of /local all of these words are bound to the function's >>context, as soon as the function is constructed.
<<quoted lines omitted: 18>>
>I love this language :-) >Brian Hawley
;- 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

 [14/28] from: galtbarber:mailandnews at: 22-Aug-2000 14:18


Elan, excellent demonstration of words/contexts in functions! Thank you very much!! -Galt it's starting to make a lot of sense!

 [15/28] from: fsievert:uos at: 22-Aug-2000 21:10


On Mon, 21 Aug 2000 [rebol--techscribe--com] wrote:
> 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.
Thats absolutely right.
> 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.
No, thats not possible. Example:
>> f: func [a] [a] >> make object! [a: none insert second :f 'a]
There is no way to find out, which of the a's is the one, which is bound to functions context now.
> With exception of /local all of these words are bound to the function's > context, as soon as the function is constructed.
Local (as a word) is, too.
> 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]
Not possible here: f: func [a] [] No word example -> no way to say bind. That s why we need in for functions.
> Re 3: > You can now easily determine which values the words are associated with in > the function's context:
Same problem as above.
> 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.
You could overwrite func, but I think, REBOL should support this. Its the same as in objects. To serialize functions like shown above (the one with the two a's), you need a way to find out, which of the a's are bound to functions body and which not. I would like to use "in" for that, which would be the same sollution as for objects. Greetings, Frank

 [16/28] from: galtbarber:mailandnews at: 22-Aug-2000 16:39


Brian, /local revelation! Thanks! So, you really can see that when invoked, /local is normally set to none, and all "optional switch params" following it, up to the next /switch if any, are set to none also. Somehow I never realized that MULTIPLE parameters can follow a /switch in the function definition so I thought that /local was doing something special allowing multiples, and that it had to come last. So, you could use any [parma parmb /local x /morefrickinlocals s t u] and s t u are locals that are just every bit as good as /local, and it doesn't even matter if /local is the last switch, right? The only limit is that all real params have to come before the first /switch. What did this save RT? Did they get to avoid having to use 'use inside the function to create a separate context frame with the locals local? Since they had to support the /switches anyway and they had a mechanism for that, why not bag the extra 'use and stick the locals as "unused" switch parms? was their thinking, I suppose. The one change they had to make to accept this is that /local unused switch params (local vars) are set to none like any other unused switch parms (since /local itself is not usually invoked) This is different than simply returning false when queried with value? which is how a 'use context works and how you treat global variables as well. So then locals became initialized to none rather than simply being unset values. This is kind of amusing:
>> g: func [][probe local ] >> g
** Script Error: local has no value. ** Where: probe local
>> g: function [][][probe local ] >> g
none == none
>>
-Galt p.s. Andrew, do you think of the processor for make object! [ a: blah b: blahblah ] as another dialect? That argument seems a teensy bit stronger than function-as-dialect, but what do I know?

 [17/28] from: rebol:techscribe at: 22-Aug-2000 16:58


Hi Frank,
>> 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. > >No, thats not possible. Example: > >> f: func [a] [a] > >> make object! [a: none insert second :f 'a]
You are taking issue with the terminilogy here, not with factual statement. I tend to think of words and instances of words. I tend to say: It is simple to determine which words are bound to the context of a function. We must do a little more work to determine whether an instance of the word a is bound to the context of the object or to the context of the function. You may prefer to use the terms symbol and word or token and word where I use word and instance. Then the problem could be formulated as: It is simple to determine which symbols are bound to the context of a function. We must do a little more to determine whether the word a is bound to the context of the object or to the context of the function. Or It is simple to determine which tokens are bound to the context of a function. We must do a little more to determine whether the word a is bound to the context of the object or to the context of the function. In any event, it is simple to determine which words (symbols or tokens) are bound to the context of a function, i.e. to generate a block that lists those words (symbols or tokens). It takes a little more effort to determine whether a specific instance of a word (or a word) is bound to a specific context.
>There is no way to find out, which of the a's is the one, which is bound >to functions context now. > >> With exception of /local all of these words are bound to the function's >> context, as soon as the function is constructed. > >Local (as a word) is, too.
Factually yes (see Brian's email and my response to him). Conceptually that is irrelevant, since the purpose of /local is to distinguish between words that are intended to be used locally, and words that are exposed globally (i.e. that receive an argument.) I think it would be very bad style to use /local and words declared after /local for any other purpose.
>> Re 2: >> You can easily bind the words in the function's first or third block to the
<<quoted lines omitted: 4>>
>Not possible here: > f: func [a] []
That is why I introduced the cfunc function.
>No word example -> no way to say bind. That s why we need in for >functions.
I pointed that out in my first email in this thread, where I argued that the cfunc function would take care of that, by ensuring that there was a local word self defined, which would always be the first word in the function's body.
>> Re 3: >> You can now easily determine which values the words are associated with in >> the function's context: > >Same problem as above.
That was solved.
>> 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.
>You could overwrite func, but I think, REBOL should support this. Its the >same as in objects.
I don't think it's one (REBOL should) versus the other (REBOL can support that now, if you want). I think it's a good idea that REBOL should support this. At the same time I think that the combination of cfunc, get-context-block and in-func permit you to already do that now, without modifying func, even though you could probably modify func, if you want to take it to that extreme.
>To serialize functions like shown above (the one with the two a's), you >need a way to find out, which of the a's are bound to functions body and >which not. I would like to use "in" for that, which would be the same >sollution as for objects.
I presented the in-func function which does just that. Regards, ;- 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

 [18/28] from: lmecir:geocities at: 23-Aug-2000 14:23


Hi Elan, I am not a native English speaker, but see some use for a terminological change: You wrote: {{ It is simple to determine which words are bound to the context of a function. We must do a little more work to determine whether an instance of the word a is bound to the context of the object or to the context of the function. }} I offer the following reformulation (the asterisks are marking the difference): {{ It is simple to determine whether a word *can be* bound to the context (of a function/object). We must do a little more work to determine whether a word *is* bound to the context (of the function/object). }} Regards Ladislav

 [19/28] from: brian:hawley:bigfoot at: 23-Aug-2000 13:21


Galt Barber <[galtbarber--MailAndNews--com]> wrote:
>Brian, /local revelation! Thanks! >So, you really can see that when invoked,
<<quoted lines omitted: 5>>
>so I thought that /local was doing something special >allowing multiples, and that it had to come last.
Pretty cool, huh?
>So, you could use any [parma parmb /local x /morefrickinlocals s t u] >and s t u are locals that are just every bit as good as /local, >and it doesn't even matter if /local is the last switch, right? >The only limit is that all real params have to come >before the first /switch.
All of this only matters to the help function. Any parameters or switches to your function that are after the /local switch are left undocumented by the help function. If you want undocumented switches, this is the way to do it. Keep in mind that the source function shows all of your parameters and code, so "undocumented" is a little relative here.
>What did this save RT? Did they get to avoid having >to use 'use inside the function to create a separate
<<quoted lines omitted: 3>>
>and stick the locals as "unused" switch parms? >was their thinking, I suppose.
As I recall (anybody correct me here), there didn't used to be any special treatment of /local at all. All of the formal parameters, both refinements and words, can be used as local variables. I guess that people didn't realize this so they asked for local variables. Some genius at RT (there are a lot of them) figured out that undocumented local vars would do as well, and hacked the help function. As for functions' use of contexts, all contexts are the same underneath. The only difference is in how the contexts are treated underneath and the lifespan. By lifespan, I mean during what part of the execution process the words in that context are valid. Any time outside of that lifespan, it's best to program as if that context no longer exists and you could crash the interpreter if you refer to it (mostly true). Here's a quick comparison of the different contexts. Words in a context are not initially set to a value, but some users of contexts do some initialization. Of course all of this is subject to change later by RT, particularly when modules are introduced. Global (system/words): - Created: When REBOL starts? - Lifespan: Duration of interpreter session. - Strangeness: Only context that words can be added to after it has been created. Otherwise, like Object. Use function: - Created: When the function use is called. - Lifespan: For the duration of that function call. Object! : - Created: When the object! is created. - Lifespan: For as long as the object! is referenced. - Initialization: Code block initializes object words at creation time. - Strangeness: Always has self word, can be based on prototype of other object (_not_ inheritance). Function! : - Created: Conceptually at start of function call. For real behavior, see Strangeness. - Lifespan: Conceptually until end of function call. For real behavior, see Strangeness. - Initialization: Formal parameters (the words of the context) are set to either the values of the actual parameters, or to none! if none. Missing parameters at the end are left unset. - Strangeness: Conceptually the context of a function! should be treated as if it had the duration of a use context - you shouldn't try to treat the words of the function! as variables after the function is done executing, unless you bind them to a valid context. In practice REBOL caches a single context for each function to cut down on context creation and rebinding overhead, making REBOL _much_ faster. However, this context is reused with every function call and treated as a stack frame during recursive calls, making use of the context outside of the function generally a bad idea. It is a particularly bad idea for those of us who are used to the languages Lisp or Scheme because REBOL doesn't close those variables (a Lisp term). The actual behavior of REBOL will be close enough to Scheme to make it very difficult to see where the bugs are, and won't generate a helpful error message to tell you what you did wrong. Because of these caveats, it's best to translate your closure-based code into objects until you know what to avoid doing. Any code that makes you wish that the IN function was defined for functions should be rewritten, probably to use objects or modules instead. When you really need closures, close the values yourself with compose or something. If you need static data, use a literal series embedded in the source code. Above all, treat function! contexts as if they are only valid as long as use contexts.
>The one change they had to make to accept this is >that /local unused switch params (local vars) are >set to none like any other unused switch parms >(since /local itself is not usually invoked).
They didn't need to make any changes to the creation or evaluation of functions at all. Functions are simpler than most think they are. All they changed was help.
>This is kind of amusing: > >> g: func [][probe local ]
<<quoted lines omitted: 6>>
>== none > >>
Yup! :) Brian Hawley

 [20/28] from: brian:hawley:bigfoot at: 23-Aug-2000 13:33


Ladislav wrote:
>Hi Elan, >I am not a native English speaker, but see some use for a
<<quoted lines omitted: 14>>
>function/object). >}}
You have my vote! I will try to use this terminology in the future. By the way, I am a native English speaker, to the extent that is how American English is referred to by Americans. I gather that non-Americans usually use swear words when referring to my country's dialects. :) Brian Hawley Currently in Chicago, IL

 [21/28] from: g:santilli:tiscalinet:it at: 24-Aug-2000 19:36


Hello [brian--hawley--bigfoot--com]! On 23-Ago-00, you wrote: [...] b> Functions are simpler b> than most think they are. Actually, REBOL is simpler than most think it is. This is the reason because they often complain for bugs or strange behaviour: humans have a lot of difficulty to grasp simplicity. Regards, Gabriele. -- Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/

 [22/28] from: bhandley:zip:au at: 25-Aug-2000 11:35


As far as I know, it is only humans that can give the word simple a meaning. ;) So it is humans that interpret something as simple. "When you set out to write rules for a game you will be suprised to find that a rule which seems perfectly clear to you can easily be misunderstood even by very intelligent players. The reason is that players are very rarely starting from scratch. There are other games they play and other habits they have. They may therefore interpret your rules on another basis." ["Simplicity", Edward de Bono, Penguin Books] Obviously the antidote for this malaise is clearer (less ambiguous) communication. Edward de Bono also points out that simplicity does not just happen. There is an effort seeking it. If someone has found a simple design everyone benefits when that design is communicated clearly. Brett.

 [23/28] from: al:bri:xtra at: 25-Aug-2000 15:46


Brian wrote:
> Functions are simpler than most think they are.
Gabriele wrote:
> Actually, REBOL is simpler than most think it is. This is the reason
because they often complain for bugs or strange behaviour: humans have a lot of difficulty to grasp simplicity. I totally agree. Rebol is so simple, that people willfully insert complexity into it and then try to understand it! The best way is do as Carl Sassenrath suggests in his rephrasing of my insight on page xiv of Rebol - The Official Guide, "If you know other other languages, forget them while you learn REBOL." Andrew Martin ICQ: 26227169 http://members.xoom.com/AndrewMartin/

 [24/28] from: galtbarber:mailandnews at: 25-Aug-2000 15:13


I hate to disagree with people that are smarter than me, but I seriously think you are underestimating what it takes to really understand rebol, especially for those less brilliant. I generally find that most of my knowledge of other computer systems to gain insight into rebol is quite helpful and revealing. Even having the context to say, this is like scheme or logo in rebol, but that is like some other language, etc. is all helpful. So, yes, it is true that rebol is different in important ways from other languages and therefore you will have to gain a new understanding. But this notion that you would be better off starting from a point of total ignorance and then everything would be easy is patently absurd. When I have trouble with Rebol, if I was a less knowledgeable user I would probably just give up. Being able to make some guesses about possible causes or solutions is much better. So, the best way really, is for Rebol to tell us how it works inside. When you know how rebol lists really work, and string literals and contexts and words, then you understand rebol. Ignorance or innocence isn't much help. Obviously, one should try never to allow preconceptions and prejudice to inhibit understanding, and that is true of everything, not just Rebol. I am not a stupid person, even if I am not a genius. I only got this far with Rebol because I am doggedly persistent, not because I have the pleasantly uncluttered mind of an infant. I really like and respect you Andrew, and I appreciate all the work you have done for Rebol and the members of the list. I just didn't want to let this go by yet again ... Now, this doesn't mean that I am anti-Rebol or want to be critical or whatever. We all love Rebol and want to use it as much as possible! I still don't know how forgetting everything I know is going to help me figure out just what the heck read-io really does and why timeouts dont seem to work as advertised for downloading big files... I will tell you, one of the joys of using Rebol is that it's so much nicer than other languages in many areas. If you didn't know something about them you probably would wonder what the fuss was all about when you hear people rave about Rebol! -Galt p.s. I bet Carl dreamed up Rebol, not by forgetting everything he ever knew, but by knowing so much about the current systems and their problems, and deeply pondering causes and possible solutions, and using insight gained throught deep experience and hard work.

 [25/28] from: g:santilli:tiscalinet:it at: 25-Aug-2000 20:03


Hello [bhandley--zip--com--au]! On 25-Ago-00, you wrote: b> As far as I know, it is only humans that can give the word b> simple a meaning. ;) b> So it is humans that interpret something as simple. What I was trying to say is that when we have a problem we tend to give a complex solution first, and then, only after a lot of thought, we are able to get to the simpler one. This is true when you're giving an explanation, or when you're designing something. We call genious those that are able to give the simplest solution with little thought. Regards, Gabriele. -- Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/

 [26/28] from: al:bri:xtra at: 27-Aug-2000 9:42


Galt wrote:
> I hate to disagree with people that are smarter than me, but I seriously
think you are underestimating what it takes to really understand rebol, especially for those less brilliant. I don't think I'm that smart, Galt. Even though I did take a online IQ test recently and it assigned me a score of 150 for IQ (I think the test is broken).
> I generally find that most of my knowledge of other computer systems to
gain insight into rebol is quite helpful and revealing. Even having the context to say, this is like scheme or logo in rebol, but that is like some other language, etc. is all helpful. This doesn't help much for Rebol. Unless you've examined as many languages as Carl has.
> So, yes, it is true that rebol is different in important ways from other
languages and therefore you will have to gain a new understanding. But this notion that you would be better off starting from a point of total ignorance and then everything would be easy is patently absurd. I was hindered by my knowledge of other languages. Coming from a point of view of innocence, knowing only human languages, is better I feel.
> When I have trouble with Rebol, if I was a less knowledgeable user I would
probably just give up. Being able to make some guesses about possible causes or solutions is much better.
> So, the best way really, is for Rebol to tell us how it works inside.
When you know how rebol lists really work, and string literals and contexts and words, then you understand rebol. Ignorance or innocence isn't much help. I disagree. The model that Rebol is based on is close to natural human language. Knowing that and knowing nothing of computer languages is the best way to learn Rebol. Rebol works literally as it is. Discussing in depth, contexts and how they work are almost meaningless, particularly when some parts of Rebol are still buggy and need to fixed. I thinking of the GC bug, hopefully that's fixed in the experimental builds.
> Obviously, one should try never to allow preconceptions and prejudice to
inhibit understanding, and that is true of everything, not just Rebol. Change can be hard, but after the change, you wonder, what was the trouble?
> I am not a stupid person, even if I am not a genius. I only got this far
with Rebol because I am doggedly persistent, not because I have the pleasantly uncluttered mind of an infant. You're basically trying hard to learn the detail, without knowing rebol.
> I really like and respect you Andrew, and I appreciate all the work you
have done for Rebol and the members of the list. I just didn't want to let this go by yet again...
> Now, this doesn't mean that I am anti-Rebol or want to be critical or
whatever. We all love Rebol and want to use it as much as possible! I still don't know how forgetting everything I know is going to help me figure out just what the heck read-io really does and why timeouts don't seem to work as advertised for downloading big files... There's no need to learn 'read-io. We're encouraged not to as it's only a temporary cure. As for timeouts, this is again a problem with the Rebol implementation, not the perfect Rebol.
> I will tell you, one of the joys of using Rebol is that it's so much nicer
than other languages in many areas. If you didn't know something about them you probably would wonder what the fuss was all about when you hear people rave about Rebol!
> -Galt > > p.s. I bet Carl dreamed up Rebol, not by forgetting everything he ever
knew, but by knowing so much about the current systems and their problems, and deeply pondering causes and possible solutions, and using insight gained through deep experience and hard work. Yes. He basically states that in the intro to The Official Guide. But do you and I have time to do this? Remember this?
> I am confused. Consider this small script: > REBOL []
<<quoted lines omitted: 6>>
> >> > I guess I have to use 'bind or 'use somewhere, but I'm not sure which and
how. What's wrong with this method? REBOL/View 0.9.9.3.1 1-Jun-2000 Copyright 2000 REBOL Technologies. All rights reserved. Type DEMO to run demo if it is disabled
>> block: ["a" "b" "c"]
== ["a" "b" "c"]
>> code: [print member]
== [print member]
>> foreach member block code
a b c
>>
It seems to do directly what you intend and is simpler too. =============================== For this line: foreach member block [do code] the writer has used their experience in other languages to their disadvantage. The writer has imagined that the "[]" around "do code" are like "{}" around C/C++ code. By forgetting this knowledge, then:
>> block: ["a" "b" "c"]
== ["a" "b" "c"]
>> code: [print member]
== [print member]
>> foreach member block code
becomes obvious and simple. That's basically all that Rebol is, words and blocks (with the occasional parenthesis). :-) Andrew Martin ICQ: 26227169 http://members.xoom.com/AndrewMartin/

 [27/28] from: lmecir:geocities at: 27-Aug-2000 11:47


Hi, Galt:
> > I generally find that most of my knowledge of other computer
systems to
> gain insight into rebol is quite helpful and revealing. Even
having the
> context to say, this is like scheme or logo in rebol, but that
is like some
> other language, etc. is all helpful. > > > So, yes, it is true that rebol is different in important ways
from other
> languages and therefore you will have to gain a new
understanding. But this
> notion that you would be better off starting from a point of
total ignorance
> and then everything would be easy is patently absurd. > > > When I have trouble with Rebol, if I was a less knowledgeable
user I would
> probably just give up. Being able to make some guesses about
possible causes
> or solutions is much better. > > So, the best way really, is for Rebol to tell us how it works
inside.
> When you know how rebol lists really work, and string literals
and contexts
> and words, then you understand rebol. Ignorance or innocence
isn't much
> help. > > > Obviously, one should try never to allow preconceptions and
prejudice to
> inhibit understanding, and that is true of everything, not just
Rebol.
> > I am not a stupid person, even if I am not a genius. I only
got this far
> with Rebol because I am doggedly persistent, not because I have
the
> pleasantly uncluttered mind of an infant. > > I really like and respect you Andrew, and I appreciate all the
work you
> have done for Rebol and the members of the list. I just didn't
want to let
> this go by yet again... > > > Now, this doesn't mean that I am anti-Rebol or want to be
critical or
> whatever. We all love Rebol and want to use it as much as
possible! I
> still don't know how forgetting everything I know is going to
help me figure
> out just what the heck read-io really does and why timeouts
don't seem to
> work as advertised for downloading big files... >
Andrew:
> I was hindered by my knowledge of other languages. Coming from a
point of
> view of innocence, knowing only human languages, is better I
feel.
> I disagree. The model that Rebol is based on is close to natural
human
> language. Knowing that and knowing nothing of computer languages
is the best
> way to learn Rebol. Rebol works literally as it is. Discussing
in depth,
> contexts and how they work are almost meaningless, particularly
when some
> parts of Rebol are still buggy and need to fixed. I thinking of
the GC bug,
> hopefully that's fixed in the experimental builds. > > Change can be hard, but after the change, you wonder, what was
the trouble?
> You're basically trying hard to learn the detail, without
knowing rebol.
Ladislav: Rebol differs from human languages in some respects. One of them can be found comparing Rebol Values vs. Human Values (see http://www.geocities.com/lmecir.geo/evaluation.txt). This may be a surprise for both experienced and inexperienced programmer, because that fact is hidden in other programming languages to some extent. Another difference can be found comparing the behaviour of Rebol (CQSB/DRP) functions with the behaviour of their Pure CQSB counterparts (see http://www.geocities.com/lmecir.geo/contexts.txt). A set of the differences can be found studying the behaviour of code - modifying functions like Repeat, Make Object!, Use, Foreach, ... The latter difference can be considered a bug, of course, but it is present in Rebol nowadays. My personal point of view is, that my previous experience with other programming languages helped me to understand Rebol and appreciate its advantages.

 [28/28] from: galtbarber:mailandnews at: 28-Aug-2000 13:21


Andrew, you must be religious. You believe in the Perfect Rebol! I don't care what feature it is or whether it's working broken or just weird, you have to understand it and imagining the perfect rebol won't do me a bit of good. Also, I find the claim that Rebol is significantly like a human language to be a bunch of marketing bull. It is true that dialects may prove to be powerful and helpful, but they still don't make much difference regarding a natural human language. Rebol is not and never will be like a human language. I don't mind that actually, and I am not surprised. Unless RT plans to invent AI that really works, there is no way any computer could understand a natural human language. Also, frankly, for the kind of work most of us do, we prefer the precision of our computers following a correct recipe to the powers and foibles of a human language. People invent special languages all the time for a certain domain where they need precision. Some mathematical languages are great for math but nobody would call them natural languages... Anyway, that gets tiresome. Believe what you will about Reb and nat lang. If you think Rebol is especially confusing to C programmers, that's too bad. I think it's pretty much confusing to everybody, but a little lisp or logo or scheme may be more help than harm. Actually, since the implementors of Rebol are swimming mentally in C code all day long, it may sometimes affect their thinking and first impulses, but how could that be helped? Well, keep the faith!!! -Galt

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