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

Fun functions

 [1/7] from: al::bri::xtra::co::nz at: 5-Jan-2001 11:32


Here's a function that automatically handles the problem of words that should be local to a function overwriting global words: Fun: function [ "Automatic local word generation for a function." Spec [block!] Body [block!] ][ Locals ][ Locals: make block! 0 foreach Value Body [ if set-word? :Value [ insert tail Locals to word! :Value ] ] function Spec Locals Body ] It does this by assuming that all set-word!s in a function body block are meant to be local words. So this: f: fun [bla] [t: 1 bla + t] becomes:
>> f: fun [bla] [t: 1 bla + t] >> probe :f
func [bla /local t][t: 1 bla + t]
>> t
** Script Error: t has no value ** Near: t
>> f 5
== 6
>> t
** Script Error: t has no value ** Near: t IF your function needs to change a global word, then just use 'set, like this: fun [] [set 'print none] Permission explicitly granted to Rebol Crew to use this function as they wish.' Happy New Year to all! Andrew Martin Feeling much better... ICQ: 26227169 http://members.nbci.com/AndrewMartin/

 [2/7] from: lmecir:mbox:vol:cz at: 4-Jan-2001 23:57


Hi Andrew, it works, but FUN should probably exclude arguments and refinements ----- Original Message ----- From: Andrew Martin <[Al--Bri--xtra--co--nz]> To: <[rebol-list--rebol--com]> Cc: <[feedback--rebol--com]>

 [3/7] from: al:bri:xtra at: 5-Jan-2001 12:04


I forgot two little points, getting rid of duplicate locals and allowing set-word!s to refer to the argument words. Fun: function [ "Automatic local word generation for a function." [catch] Spec [block!] {Optional help info followed by arg words (and optional type and string).} Body [block!] "The body block of the function." ][ Locals ][ throw-on-error [ Locals: make block! 0 foreach Value Body [ if set-word? :Value [ insert tail Locals to word! :Value ] ] Locals: exclude unique Locals Spec function Spec Locals Body ] ] Func: :Fun Does: fun [ {A shortcut to define a function that has no arguments or locals.} [catch] Body [block!] "The body block of the function." ][ throw-on-error [Fun [] Body] ] I've also included changes for 'func and 'does, in case people feel enthusiastic. :-) Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/

 [4/7] from: al:bri:xtra at: 5-Jan-2001 12:10


Ladislav wrote:
> it works, but FUN should probably exclude arguments and refinements
Whoops! I forgot about assignment to refinements. Might be complicating 'Fun a bit more to do that. I'll have to think about it more later. Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/

 [5/7] from: lmecir:mbox:vol:cz at: 5-Jan-2001 0:32


UNIQUE is not needed, if you use EXCLUDE -Ladislav

 [6/7] from: al:bri:xtra at: 5-Jan-2001 13:18


> UNIQUE is not needed, if you use EXCLUDE
And I fixed up assignments to refinements as well:
>> probe f: fun [bla /ref] [t: 1 xtra: blah: ref: blah + t]
func [bla /ref /local t xtra blah][t: 1 xtra: blah: ref: blah + t] Here's the script: Fun: function [ "Automatic local word generation for a function." [catch] Spec [block!] {Optional help info followed by arg words (and optional type and string).} Body [block!] "The body block of the function." ][ Locals Refinements ][ throw-on-error [ Locals: make block! 0 foreach Value Body [ if all [ set-word? :Value not found? find Spec to refinement! :Value ][ insert tail Locals to word! :Value ] ] Locals: exclude Locals Spec function Spec Locals Body ] ] Func: :Fun Does: fun [ {A shortcut to define a function that has no arguments or locals.} [catch] Body [block!] "The body block of the function." ][ throw-on-error [Fun [] Body] ] Of course, what would be really, really nice would be for Rebol to do this automatically, like set-word!s in object!s. I'll send in a enhancement request to [feedback--rebol--com]. Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/

 [7/7] from: al:bri:xtra at: 5-Jan-2001 16:23


And here's a better version that handles the case if you call Fun with a Specification block all ready containing a /local refinement and local words. Fun: function [ "Automatic local word generation for a function." [catch] Spec [block!] {Optional help info followed by arg words (and optional type and string).} Body [block!] "The body block of the function." ][ Locals LocalRefinement ][ throw-on-error [ Locals: make block! 0 if found? LocalRefinement: find Spec /local [ insert tail Locals next LocalRefinement Spec: copy/part Spec LocalRefinement ] foreach Value Body [ if all [ set-word? :Value not found? find Spec to refinement! :Value ][ insert tail Locals to word! :Value ] ] Locals: exclude Locals Spec function Spec Locals Body ] ] Does: fun [ {A shortcut to define a function that has no arguments or locals.} [catch] Body [block!] "The body block of the function." ][ throw-on-error [Fun [] Body] ] ; Don't do this. Rebol/Core's internet protocols can't handle it. ; Func: :Fun The examples for the above 'problem' are: read http://www.rebol.com Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/