Type | Wish | Status | reviewed | Date | 20-Feb-2014 05:42 |
---|---|---|---|---|---|
Version | r3 master | Category | Datatype | Submitted by | fork |
Platform | All | Severity | major | Priority | normal |
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 to | n/a | Fixed in | - | Last Update | 20-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 | - |