Good question.
Rebol code is actually best understood as a very stylized data structure. This data structure is "executable." But you need to understand how it works.
For example, from the @WiseGenius suggestion:
make-password: func[Length] [ chars: "QWERTYUIOPASDFGHJKLZXCVBNM1234567890" password: copy "" loop Length [append password (pick chars random Length)] password ]
Take a look at the block containing append password... This block is "displayed" there; what actually looks under the hood:
chars: **pointer to string! 0xSSSSSSS1** password: copy **pointer to string! 0xSSSSSSS2** loop Length **pointer to block! 0xBBBBBBBB** password
All series work this way when they are loaded by the interpreter. Lines, blocks, binaries, paths, parens, etc. Given that it is "turtles all the way down," if you go to this pointer, the 0xBBBBBBBBBB block is internally:
append password **pointer to paren! 0xPPPPPPPP**
One of the results of this is that the series can be referenced (and therefore "portrayed") in several places:
>> inner: [a] >> outer: reduce [inner inner] [[a] [a]] >> append inner 'b >> probe outer [[ab] [ab]]
This can be a source of confusion for beginners, but once you understand the data structure, you begin to know when to use COPY.
So, you have noticed the interesting meaning of this with functions. Consider this program:
foo: func [] [ data: [] append data 'something ] source foo foo foo source foo
This gives an unexpected result:
foo: func [][ data: [] append data 'something ] foo: func [][ data: [something something] append data 'something ]
We call foo couple of times, it seems that the source code of the function changes when we do this. This is, in a sense, self-modifying code.
If this bothers you, there are attack tools in R3-Alpha. You can use PROTECT to protect functional objects from modification and even create your own alternatives to routines, such as FUNC and FUNCTION, that will do this for you. (PFUNC? PFUNCTION?) In version 3 of Rebol you can write:
pfunc: func [spec [block!] body [block!]] [ make function! protect/deep copy/deep reduce [spec body] ] foo: pfunc [] [ data: [] append data 'something ] foo
When you run this, you will get:
*** ERROR ** Script error: protected value or series - cannot modify ** Where: append foo try do either either either -apply- ** Near: append data 'something
So this makes you copy the series. He also points out that FUNC is just a feature! in itself, as well as the FUNCTION function. You can create your own generators.
It can break your brain, and you can scream, saying, "This is not a smart way to write software." Or maybe you say, "My God, he is full of stars." Reactions may vary. But this is quite fundamental to the βtrickβ that controls the system and gives it wild flexibility.
(Note: the Ren-C branch of Rebol3 fundamentally did this so that function bodies and source series in general are blocked by default. If you want a static variable in a function, you can say foo: func [x <static> accum (copy "")] [append accum x | return accum] , and the function will accumulate state in accum for calls.)
I also suggest paying close attention to what actually happens in each run. Before running the foo function, the data does not matter. What happens every time we perform a function, and the evaluator sees SET-WORD! followed by a series value, it assigns a variable.
data: **pointer to block! 0xBBBBBBBB**
After this assignment, you will have two links to the existing block. One of them is its existence in the code structure that was installed during LOAD before the function was run. The second link is the one that was stored in the data variable. It is through this second link that you are modifying this series.
And note that the data will be reassigned each time the function starts. But the same value is reassigned again and again ... this original block pointer! That is why you should COPY if you need a fresh block for each run.
The grappling of basic simplicity in the rules of the appraiser is part of dizzying interest. So simplicity was dressed to make a language (that way, you could twist your own means). For example, there is no "multiple use":
a: b: c: 10
This is just an estimate by pressing a: like SET-WORD! symbol and say "ok, let me bind the variable a in the context of the binding to what creates the next full expression." b: does the same. c: does the same, but gets to the terminal due to the integer value 10 ... and then is also evaluated to 10. Thus, it looks like a multiple assignment.
So just remember that the original instance of the series literal is the one that hangs in the loaded source. If the evaluator ever handles this type of SET-WORD! or SET, it will borrow a pointer to this literal in the source to push the variable. This is a mutable link. You (or the abstractions you are developing) can make it immutable with PROTECT or PROTECT / DEEP, and you can do this without reference using COPY or COPY / DEEP.
Topic Note
Some argue that you should never write copy [] ... because (a) you may get used to forgetting to write COPY, and (b) you make an unused series every time you do it. This "empty series template" gets highlighted, must be checked by the garbage collector, and no one ever touches it.
If you write make block! 10 (or no matter what size you want to distribute over the block), you avoid the problem, save the series and offer a size hint.