Hi Ladislav,
you wrote
>I recall:
>
>>> block1: [do func[f [any-function!]] [print "OK"] func [x] [print "OK"]]
>== [do func [f [any-function!]] [print "OK"] func [x] [print "OK"]]
>>> do block1
>OK
>
>Why isn't this answer good enough for you?
>
you refer to the difference between block1 and block2. Once you have
appended :f to block2, how REBOL displays the two blocks appears identical:
>>> block1: [do func[f [any-function!]] [print "OK"] func [x] [print "OK"]]
>== [do func [f [any-function!]] [print "OK"] func [x] [print "OK"]]
>>> append block2 :f
>== [do func [f [any-function!]] [print "OK"] func [x][print "OK"]]
Looking alike in REBOL's console does not mean that they are the same
thing. What's misleading here is that REBOL displays a function expression
that has been evaluated as the expresssion that was evaluated. The display
notation does not indicate whether the function definition expression was
already evaluated or not.
So, when you are looking at block1, func [x] [print "OK"] is a a function
definition that has not been evaluated yet. When you are looking at block2,
func [x] [print "OK"] is a function definition that was evaluated when f
was assigned as a refernce to the function func [x] [print "OK"].
You can see the difference when you look at what REBOL reports as the type
of the last element of block1 and block2, after :f has been appended to
block2:
>> type? last block1
== block!
>> type? last block2
== function!
Block1 contains the instructions to create a function and therefore last
block1 returns the block [print "OK"], so type is block!, whereas last
block2 returns the function that was already created, and therefore the
type evaluates to function!.
In summary, here is another way to use append :f so as to construct a
block2 block that is identical to block1:
>> f: [func [x][print "OK"]] ; prevent evaluation of func, by embedding in
block
== [func [x] [print "OK"]]
>> block2: [do func [f [any-function!]] [print "OK"]]
== [do func [f [any-function!]] [print "OK"]]
>> insert tail block2 :f
== []
>> do block2
OK
See, because I prevetend the evaluation of the func [x] [print "OK"] at the
time it f was assigned as its reference, by embedding it in a block
(yesterday I accomplished the same thing by embedding it in a function),
what is being appended to block2 has not been evaluated yet. It is the
instruction to create a function and not a function that has already been
created.
When REBOL looks for an argument for [f [any-function!]] [print "OK"] it
will find the word func, instead of finding a function. I.e. it will find
the instruction to create a function, and not a function that has already
been created, when it was assigned to f.
In its attempt to retrieve an argument for the first function in block2, it
will evaluate what it finds. Here, it will evaluate func, create a function
and return the function it just created as the argument, instead of
evaluating the body of an already created function, as it did in the
example you provided.
Hope this helps,
Elan