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

[REBOL] Re: bug?

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 > dummy: func [][ > return-value: "1" > append return-value "1" > return-value > ] > >> print dummy > 11 > >> print dummy > 111 > >> print dummy > 1111 > >> print dummy > 11111 > >> print dummy > 111111 > >> > > 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