Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Functional programming in REBOL

From: larry:ecotope at: 8-Aug-2001 10:13

Hi Ladislav, 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. 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. 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. The other comment is that, for me personally, the e-func code much easier to read and follow with the internal comments removed. 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. Here is the new version: cfunc: func [spec body /local args][ args: copy [] repeat el spec [if word? :el [append args to-get-word :el]] func spec compose/deep [ do append reduce [func [(spec)][(body)]][(args)] ] ] 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.
> 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.
> f2: e-func [:x] [type? get/any 'x] > f2 // ; == op! > > while > > g2: cfunc [:x] [type? get/any 'x] > g2 // ; == get-word!
See above
> 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? 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 ;-) Cheers -Larry