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


 [1/4] from: hallvard:ystad:helpinhand at: 20-Sep-2001 13:26

How is this possible:
>> source dummy
dummy: func [][ return-value: "1" append return-value "1" return-value ]
>> print dummy
>> print dummy
>> print dummy
>> print dummy
>> print dummy
Why doesn't dummy yield "11" all the time? ~H

 [2/4] from: koopmans:itr:ing:nl at: 20-Sep-2001 13:48

OK, I'll try.... You create a value and a word in the function context. You append "1" to the value. The function context lives as long as the function is defined, not as long as the invocation lasts. So the next time you call dummy, you append "1" to the value. If you understand pointers in C, think of return-value as a pointer and 1 of the value the pointer points to. You change the latter every invocation for the (changed) value "1". If you change "1" to copy "1" it will work as you expect, because you allocate new memory (a new value). Redeclaring return-value does not create a new pointer to a new value, as that pointer already existed in this context. The trick is that a string value is unique in the value domain, thus if you use a value, and change it, you actually redefine the value. Changing the value of a value in a context or so ;-) Although the above explanation is not 100% correct, the C analogy helps me most of the time. (and Rebil is written in ANSI C ). HTH, Maarten

 [3/4] from: joel::neely::fedex::com at: 20-Sep-2001 2:07

Hi, Hallvard, You've stumbled upon the Great Literal Misconception, which most serious programmers encounter in their REBOL career! ;-) The key is that literal values don't behave as you think they do, if you're used to using them in other languages. Hallvard Ystad wrote:
> How is this possible: > >> source dummy
<<quoted lines omitted: 15>>
> >> > Why doesn't dummy yield "11" all the time?
Taking a simpler case (to focus on the "literal" issue apart from the behavior of functions), we have
>> foo: [val: "1" append val "1" val]
== [val: "1" append val "1" val]
>> foo
== [val: "1" append val "1" val]
>> do foo
== "11" The result is as expected, but now look at FOO ...
>> foo
== [val: "11" append val "1" val] ... which keeps on happening.
>> do foo
== "111"
>> foo
== [val: "111" append val "1" val] Here's a clue, if you're the type who wants to figure out things by yourself.
>> foreach item foo [print [(type? :item) "^-" (:item)]]
set-word val string 111 word append word val string 1 word val Here's the key: in most programming languages, the appearance of a statement corresponding to val: "1" means that a new string containing "1" is created and the variable (in other languages, remember) is set to refer to that new string. In REBOL, this behavior requires that you explicitly say val: copy "1" So what's happening without the COPY? Everytime that FOO is DOne, the word VAL is set to refer to the STRING! value at FOO/2 (not a copy, but that string itself!). Since APPEND modifies the value of its argument, the second element of FOO is modified by each evaluation of FOO. Remember that REBOL does not distinguish between blocks that contain data and blocks that "contain code" because all REBOL blocks really just contain values! (Some of which do interesting things when the block is DOne or REDUCEd ...) Therefore the content of a REBOL block is capable of being modified during evaluation. The fact that the second element of FOO was *initialized* by a literal in the original source text is no longer relevant.
>> foo: reduce [
to-set-word "val" to-string 3 - 2 to-word "append" to-word "val" to-string #"0" + 1 to-word "val"] == [val: "1" append val "1" val]
>> do foo
== "11"
>> foo
== [val: "11" append val "1" val] Another way to see a similar modifying effect is to consider the use of two blocks, as follows:
>> tweedledee: ["1"]
== ["1"]
>> tweedledum: [val: tweedledee/1 append val "1" val]
== [val: tweedledee/1 append val "1" val]
>> do tweedledum
== "11"
>> tweedledee
== ["11"]
>> tweedledum
== [val: tweedledee/1 append val "1" val] Notice that the value to which VAL is set (in this case, the first and only value in TWEEDLEDEE) is modified by evaluating TWEEDLEDUM, even though it was initialized from a quoted string in the source text. This behavior (modifying the referenced string value) is consistent, regardless of where the string happens to be located or how it was initialized. HTH! -jn- -- ------------------------------------------------------------ Programming languages: compact, powerful, simple ... Pick any two! joel'dot'neely'at'fedex'dot'com

 [4/4] from: greggirwin:starband at: 20-Sep-2001 6:45

Hi Hallvard, << dummy: func [][ return-value: "1" append return-value "1" return-value ]
dummy: func [][ return-value: copy "1" append return-value "1" return-value ] I don't know if this is better than using something like clear "", or make string! 0, to initialize it, but maybe an expert will let us know if they have a better way. --Gregg

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