[REBOL] Re: Functional programming in REBOL
From: lmecir:mbox:vol:cz at: 8-Aug-2001 22:06
Hi Larry,
> Thanks for your excellent comments. I must confess that I was completely
> unaware of e-func in your higher-order function library, although I had
> looked at some of the other functions. Please accept my apologies.
Nevermind, you don't have to read everything I write :-), for the
interested: something on the subject is in
http://www.sweb.cz/LMecir/contexts.html
> e-func and cfunc were created from very similar goals. I agree with your
> assessment that e-func is more general because it handles refinements and
> delayed evaluation args in the spec block.
To be fair, I would like to say, that I am still convinced, that the
unevaluated/fetched argument passing is something Rebol shouldn't use at
all, because it is breaking the language evaluation order rules, ...
> Two quick comments on e-func, if the line:
>
> :nm-use locals reduce [ ...
>
> was changed to
>
> :use locals copy/deep reduce [ ...
>
> e-func would be self-contained, making it a little more portable.
I considered that, but it would harm E-FUNC in cases like:
f: e-func [copy [any-type!]] [type? get/any 'copy]
> Out of curiosity, I checked the storage requirements for a curry function
> created two ways:
>
> 1) using cfunc: 1268 bytes
> 2) using e-func: 2052 bytes
>
> so e-func is using about 60% more storage. It is also noticeably slower.
> I like the method you used to redefine the locals inside the use block, I
> think that approach is much preferable to renaming the variables in the
body
> block as suggested by Gabriele.
>
> I thought about your comments below and decided to add argument
> type-checking and allow comment strings in the spec block for cfunc
...snip...
> The other restrictions still apply. The spec block for cfunc should not
> contain refinements, get-words, lit-words, or set-words. The approach
which
> I took of reusing the spec block for all the args will not work for
dealing
> with these items, I think your approach is probably the best one.
>
> On the other hand, I had a limited goal in creating cfunc. I just wanted
> something that would handle "ordinary" arguments, so that Scheme code
could
> be entered more or less the same way as it would be in Scheme and produce
> the same results. Scheme does not support user definition of datatypes for
> args, or any of the other REBOL features mentioned above.
>
> So, for my purposes, cfunc is acceptable and the version above allows
> type-checking and doc strings as well. One of the main ideas from Scheme
is
> that most of the higher order functions are really simple, and in Scheme
> they are simple. When we try to implement them to include all of the
nuances
> and features of REBOL functions, they tend to get more complex. In this
> regard, I note that many of your functions also do not support delayed
> evaluation arguments.
I personally do not support the strange argument passing methods too.
> > Larry, your CFUNC doesn't have trouble with "active arguments". Some
> > differences:
> >
> > f1: e-func [x [any-type!]] [type? get/any 'x]
> > f1 () ; == unset!
> >
> > while
> >
> > g1: cfunc [x [any-type!]] [type? get/any 'x]
> > ** Script Error: Expected one of: word! - not: block!
> > ** Where: to-get-word
> > ** Near: to get-word! :value
>
> This is now fixed.
It isn't, see this:
g1 ()
** Script Error: x has no value
** Where: g1
** Near: func [x [any-type!]][type? get/any 'x] :x
> > f3: e-func [do] [type? get/any 'do]
> > f3 "OK" ; == string!
> >
> > while
> >
> > g3: cfunc [do] [type? get/any 'do]
> > g3 "OK" ; == [func [do][type? get/any 'do] :do]
> >
>
> This one bothers me, but I don't see how to fix cfunc. Meanwhile, just
don't
> use DO as a variable name. Are there any other words that create this
> problem?
Yes: 'append, 'reduce, 'func
See this modification:
ga: func [word [any-word!]] [get/any word]
cfunc: function [
{closure creating function}
spec [block!]
body [block!]
] [body2] [
body2: reduce [:do :func spec body]
repeat el spec [if word? :el [append body2 reduce [:ga to lit-word!
el]]]
func spec body2
]
> Thanks again for your comments. And thanks for the effort which you have
put
> into highfun.r, it is a good resource for all of us.
>
> Meanwhile I am looking forward to your solution of the puzzles ;-)
I wanted to let the others to post their solutions. Don't read below the
line, if you want to solve the puzzle on your own:
-------------------------------------------------------
My solution:
pa :pa :pa
should be the CURRY function, while
uncurry :curry
should be the PA function.