Hi guys,

Pretty hot thread, eh? It's way beyond me, but perhaps this could be of some
use?

composite: func [
    {takes two single-argument functions and returns a function that
    successively applies these to a single argument}
    function-a [any-function!] function-b [any-function!]
][
    func [x] compose [do (:function-a) do (:function-b) x]
]

>> double: func [x][x * 2]
>> add5: func [x][x + 5]
>> a: composite :add5 :double
>> source a
a: func [x][do func [x][x + 5] do func [x][x * 2] x]
>> a 10
== 25

This way you can embed the function values directly in your composite
function without having to worry about the bindings of words.

What's kind of interesting here is that although it looks like the two
functions are being reconstructed every time 'a is applied, actually we have
function! values embedded directly into the code.

>> length? second :a
== 5
>> type? second second :a
== function!
>> print mold second second :a
func [x][x + 5]

So it also works with native! and action! values:

>> a: composite :abs :double
>> a -20
== 40
>> source a
a: func [x][do action do func [x][x * 2] x]

To the best of my understanding, I'd have to say that Elan has the basic
issues nailed down. To put it as simply as I can, Ladislav's original
function,

samef: func [f [any-function!]] [func [x] [f x]]

just returns a function with the enigmatic word 'f in its code:

>> a: samef :double
>> source a
a: func [x][f x]

because 'f isn't dereferenced when the function that is returned is
constructed. And as Gabriele points out, the value of 'f in this case is
defined by the local context of 'samef, which can change every time it is
applied. There has been much documentation on this list about how words local
to a function behave when dereferenced outside of their function. I believe
that the conclusion is that their behavior should be considered neither a
feature, nor a bug, but simply as undefined. The fact that "unauthorized"
dereferencing of words seems to do something useful at times is definitely a
trap, though, and there should be much more warning about this in the
documentation.

See you,
Eric

Reply via email to