REBOL3 tracker
  0.9.12 beta
Ticket #0002108 User: anonymous

Project:



rss
TypeWish Statusreviewed Date20-Feb-2014 05:42
Versionr3 master CategoryDatatype Submitted byfork
PlatformAll Severitymajor Prioritynormal

Summary Change special /LOCAL handling to use LOCAL: instead
Description Right now "local variables" are produced through a sort of trick of a refinement that no one is supposed to use, whose arguments are therefore in local scope. Despite that, it really is just a refinement:

>> x: func [/local z] [if local [print z]]
>> x/local "silly..."
silly...

To prevent this from being used intentionally or accidentally to cause problems, there are currently 3 instances in core of ASSERT/TYPE [local none!]. But as new ideas like RETURN have come into play as RETURN: instead of /RETURN, the benefits of going "out of band" to a set-word instead of a refinement plays more to the strength of dialecting.

Also, the "function specification dialect" is one of the first dialects that a Rebol user encounters. So it's important that it be designed well and orthogonally, especially to demonstrate good practices when people make their own. Using different Rebol word types to avoid these kinds of collisions is a good example.

So the proposal is simply to add LOCAL: handling into FUNCTION! to do as a refinement named /LOCAL would do. Except it would not define the word LOCAL, nor allow you to pass in locals with a refinement called /LOCAL.

Any code that wasn't updated to use the new convention would continue to function just as before, but /LOCAL would just be an ordinary refinement name. The most noticeable effect would be that any /LOCAL refinements would show up in HELP.
Example code
;-- Current behavior

>> z: 10

>> x: func [/local z] [
    if all [
        value? local
        local
    ] [
        print z
    ]
    z: 20
]

>> x/local "silly..."
silly...

>> x

>> print z
10


;-- Desired behavior

>> z: 10

>> x: func [local: z] [
    if all [
        value? local
        local
    ] [
        print z
    ]
    z: 20
]

>> x/local "silly..."
** Script error: x has no refinement called local

>> x

>> print z
10

Assigned ton/a Fixed in- Last Update20-Feb-2014 20:38


Comments
(0004250)
BrianH
20-Feb-2014 19:05

We'd have to decide how local variables would be stored in the function. Perhaps after all of the function arguments, in the stack frame? And we'd have to figure out a way to indicate that these not-really-arguments can't be provided as arguments.

From a spec usability standpoint we might consider having the spec parser consider the first set-word encountered to be the end of the argument list. All data after that would be parsed by the rules for each particular set-word, not by the argument parser. That would allow for richer dialects in the set-word options. I don't know, this merits some discussion.

One theoretical advantage to this kind of thing is that we would be able to specify local words and argument words differently. This might not seem like as much of an advantage in interpreted Rebol, but it could be really useful in compiled Red, where declaring data types and such of local words might not necessarily need to follow the same rules as declaring argument typespecs.

Another theoretical advantage would be that since the local words don't have to be provided as arguments, they wouldn't necessarily have to stay the same. This means optimizers could change the number of local words without affecting the WORDS-OF or TYPES-OF results. It's harder to get this same advantage with /local because those words are arguments.

Date User Field Action Change
20-Feb-2014 20:38 Ladislav Severity Modified minor => major
20-Feb-2014 19:06 BrianH Category Modified Unspecified => Datatype
20-Feb-2014 19:06 BrianH Status Modified submitted => reviewed
20-Feb-2014 19:05 BrianH Comment : 0004250 Added -
20-Feb-2014 05:53 fork Code Modified -
20-Feb-2014 05:52 fork Description Modified -
20-Feb-2014 05:52 fork Code Modified -
20-Feb-2014 05:42 fork Ticket Added -