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

[REBOL] Re: blocks in and out function !

From: joel::neely::fedex::com at: 8-Jan-2002 13:42

Hi, Olivier, Welcome to REBOL! You've encountered the First Koan of REBOL! Olivier Flauzac wrote:
> Hi ! > > I'm try to developpe some rebol code, and I have a little problem : > > When I do the following code in the rebol console, everything is OK > the last append instruction append 4 to the empty block following 1 > ----------------------------------------------- > gr: [] > == [] > >> append gr 1 > == [1] > >> append/only gr [] > == [1 []] > >> append gr 2 > == [1 [] 2] > >> append/only gr [] > == [1 [] 2 []] > >> append select gr 1 4 > == [4] > >> :gr > == [1 [4] 2 []] > ------------------------------------------------- > > now if I write the following functions I obtain a totally different > result : 4 is append to all empty blocks !! > > --------------------------------------------------- > >> addNode: make function! [g n][ > [ append g n > [ append/only g [] > [ ] > >> addLink: make function![g n v][ > [ append select g n v > [ ] > >> gr: [] > == [] > >> addNode gr 1 > == [1 []] > >> addNode gr 2 > == [1 [] 2 []] > >> addLink gr 1 4 > == [4] > >> :gr > == [1 [4] 2 [4]] > ----------------------------------------- > > I solved that problem by replacing the line "append/only g []" by > "append/only g make block! []". With that modification It works ! > > Could anyone give me an explaination ? Why the second code > do not behave like the first one ? >
The short answer is that [] inside a function does not translate into a request for an empty block to be created, but rather *IS* a block which is initialized as empty when the function is defined. Subsequent modifications to the block are retained, because REBOL does not make a distinction between code and data. A longer answer, by way of analogy, considers the following:
>> myword: "?" == "?" >> thing: [myword: []] == [myword: []] >> do thing == [] >> append myword "What?" == ["What?"] >> thing == [myword: ["What?"]]
The second line above sets THING to a "literal" block which contains two values, a SET-WORD! value and a BLOCK! value (initially empty, by the way). The third line evaluates the block referred to by THING. As a result, MYWORD now refers to the second element of THING. The fourth line appends something to the block referred to by MYWORD. Since this *IS* the second element of THING, the fifth line shows that both references to that block (through MYWORD and through the second element of THING) both "see" the change. If you're at all familiar with LISP, I can say simply that REBOL defaults to structure sharing. HTH! -jn-