Follow-up on implied local variables (FUNC-LOCAL)
In June I opened a large can of worms by suggesting that R3 provide a
function that allows local variables as the default for "undefined"
variables. The func-local discussion is here.
Many of you posted comments and suggestions regarding this idea.
Thanks. There were a lot, but I read and considered each one carefully.
In general, my reply is that in REBOL it is important to distinguish
between primary feature functions and secondary helper functions.
- A primary function is one that provides the root capability for a
specific feature. The round function is a good example.
- A helper function exists only for ease-of-use. One of the best examples
is the append function which provides a common but minor variation in
the insert function (to insert at the tail of a series.)
Note that the current func, function, has, and does functions fall into the helper category. After all, you can always write:
example: make function! [[specs] [body]]
But, most of us want a shortcut for doing that, and that's why those
other function functions were created.
So, now it's time to look at another helper, one that saves time by
collecting the local variables for us.
I could go into a long detailed explanation about why REBOL
picked explicit declaration of locals (rather than declaration of
non-locals), but that really does not matter because in REBOL you
can easily create whatever kind of function function you need.
I think what's more important is to recognize the most common patterns
we encounter during serious programming sessions and ask the question,
"what can we do to make the process easier?"
Over the last few months, as a test, I've been using the func-local
function while writing the R3 GUI system. I've learned quite a lot from
this exercise. Let me summarize:
- It is a very useful helper! I found that about 80% of my
functions are now defined this way. The reason is that most funcs
(in my programming style) are very short, well isolated functions.
They very rarely, if ever, set global variables.
- It is not free! While you are relieved of the task of keeping
track of locals, you need to remain aware of new restrictions regarding
usage of the set-word form. E.g. you cannot casually set variables that
are outside the function's context, such as inferred object variables,
(including globals, which in R3 are bound to the module's top-level
object) and set-words used in dialects such as parse.
- A shorter name is better. After a couple months, I discovered
that I did not like func-local and really wanted a shorter name.
I considered your suggestions of using refinements, both of
example: func [args /global words] [body]
example: func/local [args] [body]
But, I wasn't really thrilled by those approaches. They really take the
"h" out of helper function idea.
After considering all suggestions, I reduced it down to these choices:
- funct - t for "tight" as suggested by Gregg's comment
- funx - x for "excluded" or "extended"
- lfunc - l for "local"
I like funct the most because it's part of the word function.
I sort of like funx because it's really short, like func.
The word lfunc is also good because it is clear, but in an alphabetic
list of functions, it won't appear near func nor function, similar to
does and has, but I think those are used less often.
Of course, all of these words will appear in the list when the user
>> help fun
(However, I'm not sure how important that is, because I think help
needs improved search features anyway.)
So, what's it going to be? Pick one.