REBOL3 tracker
  0.9.12 beta
Ticket #0002023 User: anonymous

Project:

Previous Next
rss
TypeWish Statusproblem Date9-Apr-2013 12:35
Versionr3 master CategoryParse Submitted byabolka
PlatformAll Severityminor Prioritynormal

Summary Allow set-word! for the word argument of PARSE's SET and COPY rules
Description (The following discussion will, for brevity, only refer to SET. COPY is to be treated fully analogous to SET.)

Currently, PARSE's SET keyword takes a "word" argument, which must be a word! type:

>> parse [42] [set foo integer!] foo
== 42

Using a set-word! as argument, casues an error:

>> parse [42] [set foo: integer!] foo
** Script error: PARSE - expected a variable, not: foo:

I suggest to allow set-word! types as argument to PARSE's SET as well. The main benefit would be that this usage allows us to indicate to e.g. FUNCT that these variables ought to be "local".

Currently, PARSE variables "leak" through e.g. FUNCT, requiring us to explicitly handle PARSE variables that ought to be local:

f: funct [s /local bar] [parse s [set bar integer!] bar]

Allowing set-word! would allow us to forego this explicit listing:

g: funct [s] [parse s [set baz: integer!] baz]

In this case, FUNCT (using COLLECT-WORDS/set/deep) would be able to detect and properly handle BAZ as local.

The operation of PARSE's SET would not change, and the current behaviour of SET word! would still stay in place. So this is a pure extension of functionality, which should have no effect on backwards compatibility, except for previously erroneous code now becoming meaningful.
Example code

			

Assigned ton/a Fixed inr3 master Last Update7-Mar-2014 20:17


Comments
(0003809)
adrians
9-Apr-2013 18:16

This would be great. Is backwards compatibility the only reason for allowing the current SET word behaviour to remain?
(0003810)
abolka
9-Apr-2013 19:36

No, that's not the only reason. (But backwards compatibility certainly is one reason as well.)

Must fundamentally, there simply is no good reason for removing or changing `SET word` behaviour. `SET word` is independently still very useful: when variable localisation is not necessary and you consider `SET word` more readable, or when you explicitly want to avoid automatic locals handling, and set a "global" variable. Basically, it's the same as with `SET 'name` vs `name:` in the DO dialect. Both are useful.
(0003811)
BrianH
9-Apr-2013 20:38

This wouldn't change the behavior, this would just allow the variable used by the current SET and COPY operations to be a set-word, in addition to its existing support for that variable being a word. There is no existing interpretation for a set-word in that position that would be lost here, so from a semantic standpoint nothing would be lost, and this syntax could be understood by the dialect processor without confusion.

The main downside is that this will make the PARSE dialect harder to understand by developers. Even though there would be no conflict to the dialect processor between set-words used as variables for SET and COPY and set-word operations (position getting, just like in *EACH), it would make the PARSE dialect more confusing to people reading parse rules.

For instance:
>> parse [5] [set x: y: integer!] reduce [x y]
== [5 [5]]

At a glance it is hard to tell that x: is doing one thing and y: is doing something else. So, this would be a tradeoff, making it easier to declare local variables, at the expense of making it harder to debug your code. Maybe this is a tradeoff worth making, and it well may be, since people who use the locals-gathering function builders are more likely to be careful with set-words in their code already.
(0003816)
Ladislav
10-Apr-2013 11:27

Indeed, this seems as a reasonable tradeoff to make.
(0004012)
fork
25-Sep-2013 15:06

Was going to add this ticket, but I see it already exists, and there is no opposition....so...

Can we go ahead and make the change? It looks like as the parser moves along the rule, if it sees a COPY or SET, then it sets the flag PF_COPY or PF_SET as appropriate. (Note: it actually sets *both* in the case of copy, so you need to test the flags in order and assume they're exclusive... eeek, confusing micro-optimization! :-/)

https://github.com/rebol/rebol/blob/bf2ec8dd84abc2af50cc9bda5cc1548f0ce00ce8/src/core/u-parse.c#L707

Note that the specific "expected a variable" error you get when you currently say COPY X: THRU FOO comes from a test to make sure the next element is a WORD!. This would have to be changed to IS_WORD(item) || IS_SET_WORD(item), for starters. But merely enabling that would likely lead to it saving the parse position and ignoring the copy/set flags here:

https://github.com/rebol/rebol/blob/bf2ec8dd84abc2af50cc9bda5cc1548f0ce00ce8/src/core/u-parse.c#L793

So off the cuff I'd guess that if SET-WORD! was passed in the initial test and the flags set, you could check the flags there. If they are set, you could make it do what WORD! does, setting item to the variable indicated by the set-word and falling through instead of doing a CONTINUE:

https://github.com/rebol/rebol/blob/bf2ec8dd84abc2af50cc9bda5cc1548f0ce00ce8/src/core/u-parse.c#L812

Then as it proceeds, when it hits a WORD! it checks to see if the flags are set, and if so it will use that word as the named place to copy or set:

https://github.com/rebol/rebol/blob/bf2ec8dd84abc2af50cc9bda5cc1548f0ce00ce8/src/core/u-parse.c#L988

That copying and setting code is inside of an IF IS_WORD, thus it would not allow SET-WORD! at the moment:

https://github.com/rebol/rebol/blob/bf2ec8dd84abc2af50cc9bda5cc1548f0ce00ce8/src/core/u-parse.c#L864

It may be easiest in the code where the flags are checked and the set-word is recognized to just switch it to be a word, or add IS_SET_WORD to the condition and hammer out the consequences.
(0004033)
fork
3-Oct-2013 20:15

Implementation seems simpler than I thought. Believed to be accomplished with https://github.com/rebol/rebol/pull/165
(0004353)
BrianH
7-Mar-2014 20:17

There is a bug in the current implementation. See #2130 for details.

Date User Field Action Change
7-Mar-2014 20:17 BrianH Comment : 0004353 Added -
7-Mar-2014 20:15 BrianH Status Modified built => problem
17-Feb-2014 22:20 abolka Fixedin Modified => r3 master
17-Feb-2014 22:20 abolka Status Modified reviewed => built
5-Jan-2014 02:31 abolka Description Modified -
5-Jan-2014 02:31 abolka Status Modified submitted => reviewed
3-Oct-2013 20:16 fork Comment : 0004033 Modified -
3-Oct-2013 20:15 fork Comment : 0004033 Added -
25-Sep-2013 15:06 fork Comment : 0004012 Added -
10-Apr-2013 11:27 Ladislav Comment : 0003816 Added -
9-Apr-2013 21:20 BrianH Comment : 0003811 Modified -
9-Apr-2013 20:38 BrianH Comment : 0003811 Added -
9-Apr-2013 19:36 abolka Comment : 0003810 Added -
9-Apr-2013 18:16 adrians Comment : 0003809 Added -
9-Apr-2013 12:35 abolka Ticket Added -