Follow-up on implied local variables (FUNC-LOCAL)

Carl Sassenrath, CTO
REBOL Technologies
2-Sep-2008 23:52 GMT

Article #0144
Main page || Index || Prior Article [0143] || Next Article [0145] || 24 Comments || Send feedback

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:

  1. 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.
  2. 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.
  3. 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 the forms:

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 types:

>> 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.


Updated 10-Jun-2024 - Edit - Copyright REBOL Technologies -