Hi Ladislav, 

we are making progress. That's good and encouraging.

you wrote:
>But think for the second time:
>
>1. Is the samef expected to return a function? Hint: Yes

Absolutely!
>
>2. Does it really return a function? Hint: No

What?????? Of course it returns a function. Oh, my. What do you think it
returns? The function it returns is:

func [x] [ f x ]

So, when you say

a: samef :id

the word 'a now references the function func [x] [ f x ]:

Look at this REBOL code, directly copied from the REBOL console:

>> samef: func [f [any-function!]] [ func [x] [f x] ]
>> id: func [x] [x]
>> a: samef :id
>> source a
a: func [x][f x]
>>

'source fyi is a REBOL word that displays the source of a word. Here you
can clearly see that samef did return a function. Otherwise source a would
not return the function: func [x] [f x]

Another way of demonstrating that samef does indeed return a function is
using mold:

>> samef: func [f [any-function!]] [ func [x] [f x] ]
>> id: func [x] [x]
>> mold samef :id
== "func [x][f x]"

Or, if your not interested in the details of the function's implementation,
but just want to verify that - whatever it is that samef returns, it is a
function and nothing else, use type? for all I care:

>> type? samef :id
== function

Note that here type evaluates samef's return value and not samef itself. To
evaluate samef itself, you would have to use colon:

>> type? :samef
== function!

Run a little counter test. id which we implemented above is a function but
does not return a function:

>> type? :id
== function!
>> type? id 1
== integer!

When you use the word 'a we defined above, a is dereferenced. REBOL looks
up a's value. That value - as demonstrated above - is

func [x] [ f x ]

Because the value is a function, REBOL now evaluates that function, which
still is 
func [x] [ f x ]. 
1. It first notices that the function requires an argument. So, it goes
looking for an argument. It locates an argument (hopefully) and binds the
argument's value to 'x. 
2. Now REBOL starts evaluating the body of the function. The body is [ f x
]. In this body the word 'x has already been bound to the argument 'a was
passed. 

3. REBOL now has to determine the value of 'f. It looks up the value of 'f
where it was defined.  That's in samef's context. So REBOL replaces the
word 'f by the value it locates in samef's context. If that value is a
function, REBOL will now evaluate that function. 

4. Which function is it? It is the function which is bound in samef's
context to 'f as its value. f is bound in samef's argument block.

5. How did the value get there? Because samef was called with some function
as an argument. 

6. When was samef called with that function as an argument? Whenever samef
was last called with some function as an argument. 

7. Was that when 'a was defined using samef? In our example yes. But that
is not necessarily the case. If you had defined 

b: samef :inc

after we defined a, then 'f in samef's context would be referencing the
value of inc, and no longer referencing the value of id.

8. If 'a was evaluated after b had been defined in step 7, then when REBOL
dereferences the word f as part of evaluating 'a, it will look up the value
referenced by 'f in samef's context and discover the value of inc.
Therefore a will evaluate inc's function and as a result return the value
calculate by 'inc.

8. There is only one 'f in samef's context and that 'f will always at most
be associated with a single value. (Before samef is evaluated for the first
time, the value is undefined, it is probably none.) 

In summary, the function returned by samef (yes, it does return a function)
is a function that dynamically binds f to its value at the time 'a is
evaluated. It binds to the value which is associated with 'f in samef's
argument block at the time of 'a being evaluated. And - very important -
each time you use 'a, steps 1 through 8 are repeated. That means that if at
any time between the first evaluation and a second evaluation of 'a, 'samef
is used to assign a different function to some other word, f will no longer
evaluate to the previous value, if a different argument was used as samef's
argument when the new function was constructed.

>
>After answering the above questions, my point is as follows:
>
>the above definition doesn't work in Rebol, because it doesn't even return a
>function.

Wrong, I hope you can follow my detailed explanation above. 

>
> "not a feature, a bug"
>

Quite on the contrary.

Hope this helps.

Elan

>-Ladislav
>
>
>
>

Reply via email to