www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Semantic Scope Operator

reply pragma <pragma_member pathlink.com> writes:
The idea is quite possibly a misnomer, but I wanted to coalesce the flurry of
ideas on the '$', one last time, as a unified proposal for inclusion into D.

It was proposed that '$' be used as a stand in for 'this array' when working
within the slice syntax area.

 array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
 if("foo" ~~ "bar"){
    writefln("first: %s",$.something); // $ would equal _match in DMD 0.147
 }

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array foreach: $ represents the current value of iteration ?/if/else/while/for: $ represents the (non-boolean) result of the 'if' expression switch: $ represents the result of the switch expression (function body): $ is equivalent to _arguments (when applicable) The only thing I can't quite figure out is key/value iteration on foreach. Any takers? - Eric Anderton at yahoo
Feb 16 2006
next sibling parent "Kris" <fu bar.com> writes:
Symmetry and consistency are almost always a good thing, so I really like 
the potential of this proposal.


"pragma" <pragma_member pathlink.com> wrote in message 
news:dt2eo1$vgt$1 digitaldaemon.com...
 The idea is quite possibly a misnomer, but I wanted to coalesce the flurry 
 of
 ideas on the '$', one last time, as a unified proposal for inclusion into 
 D.

 It was proposed that '$' be used as a stand in for 'this array' when 
 working
 within the slice syntax area.

 array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
 if("foo" ~~ "bar"){
    writefln("first: %s",$.something); // $ would equal _match in DMD 
 0.147
 }

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array foreach: $ represents the current value of iteration ?/if/else/while/for: $ represents the (non-boolean) result of the 'if' expression switch: $ represents the result of the switch expression (function body): $ is equivalent to _arguments (when applicable) The only thing I can't quite figure out is key/value iteration on foreach. Any takers? - Eric Anderton at yahoo

Feb 16 2006
prev sibling next sibling parent reply Dave <Dave_member pathlink.com> writes:
In article <dt2eo1$vgt$1 digitaldaemon.com>, pragma says...
The idea is quite possibly a misnomer, but I wanted to coalesce the flurry of
ideas on the '$', one last time, as a unified proposal for inclusion into D.

It was proposed that '$' be used as a stand in for 'this array' when working
within the slice syntax area.

 array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
 if("foo" ~~ "bar"){
    writefln("first: %s",$.something); // $ would equal _match in DMD 0.147
 }

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array foreach: $ represents the current value of iteration ?/if/else/while/for: $ represents the (non-boolean) result of the 'if' expression switch: $ represents the result of the switch expression (function body): $ is equivalent to _arguments (when applicable)

Nice idea - I'm in agreement as long as you "don't pay for what you don't use" efficiency-wise and it doesn't complicate the compiler too much. I think in order to do this, the compiler would have to scan the scope to see whether or not to insert and subsequently update the implicit declarations of '__dollar' or a reference to the temp. holding the result (with MatchExpressions this is easy because it is always at the beginning of the scope).
The only thing I can't quite figure out is key/value iteration on foreach.  Any
takers?

How about: $=value // value because that is consistent with the use above. #=key // '#' (sharp) as in musical key, get it <g> - Dave
- Eric Anderton at yahoo

Feb 16 2006
parent pragma <pragma_member pathlink.com> writes:
In article <dt2jfa$14c3$1 digitaldaemon.com>, Dave says...
In article <dt2eo1$vgt$1 digitaldaemon.com>, pragma says...
The idea is quite possibly a misnomer, but I wanted to coalesce the flurry of
ideas on the '$', one last time, as a unified proposal for inclusion into D.

It was proposed that '$' be used as a stand in for 'this array' when working
within the slice syntax area.

 array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
 if("foo" ~~ "bar"){
    writefln("first: %s",$.something); // $ would equal _match in DMD 0.147
 }

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array foreach: $ represents the current value of iteration ?/if/else/while/for: $ represents the (non-boolean) result of the 'if' expression switch: $ represents the result of the switch expression (function body): $ is equivalent to _arguments (when applicable)

Nice idea - I'm in agreement as long as you "don't pay for what you don't use" efficiency-wise and it doesn't complicate the compiler too much. I think in order to do this, the compiler would have to scan the scope to see whether or not to insert and subsequently update the implicit declarations of '__dollar' or a reference to the temp. holding the result (with MatchExpressions this is easy because it is always at the beginning of the scope).
The only thing I can't quite figure out is key/value iteration on foreach.  Any
takers?

How about: $=value // value because that is consistent with the use above. #=key // '#' (sharp) as in musical key, get it <g>

Heh. Makes 'cents' to me. <g> - Eric Anderton at yahoo
Feb 16 2006
prev sibling next sibling parent reply James Dunne <james.jdunne gmail.com> writes:
pragma wrote:
 The idea is quite possibly a misnomer, but I wanted to coalesce the flurry of
 ideas on the '$', one last time, as a unified proposal for inclusion into D.
 
 It was proposed that '$' be used as a stand in for 'this array' when working
 within the slice syntax area.
 
 
array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
if("foo" ~~ "bar"){
   writefln("first: %s",$.something); // $ would equal _match in DMD 0.147
}

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array

Nice.
 foreach: $ represents the current value of iteration

One can have multiple iterator values, which one to default to? i.e. int[] myValues = new int[]; myValues.length = 2; myValues[0] = 5; myValues[1] = 10; foreach (int i, int val; myValues) { writefln($); } This could be possibly solved by making $ an array of somehow boxed values here. Then you could do $[0] to refer to int i and $[1] to refer to int val in the example above. Alas, inout values get tricksy here... [Those tricksy hobbitses!]
 ?/if/else/while/for: $ represents the (non-boolean) result of the 'if'
 expression

D doesn't allow one to use non-boolean expressions in if statements, so what's the purpose here?
 switch: $ represents the result of the switch expression

Yes, I like this. I often fall back to using a temp variable for this.
 (function body): $ is equivalent to _arguments (when applicable)

Possible ambiguity here. I'm not so sure I like this one.
 
 The only thing I can't quite figure out is key/value iteration on foreach.  Any
 takers?
 

Not sure what you mean... AAs? or what I mentioned above?
 - Eric Anderton at yahoo

Why not take this one step further with the ability to alias lvalue/rvalue expressions as identifiers, and allow $ as a legal D identifier? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunne
Feb 16 2006
next sibling parent pragma <pragma_member pathlink.com> writes:
In article <dt2jqt$14p2$1 digitaldaemon.com>, James Dunne says...
pragma wrote:
 ?/if/else/while/for: $ represents the (non-boolean) result of the 'if'
 expression

D doesn't allow one to use non-boolean expressions in if statements, so what's the purpose here?

Eh? Perhaps its not 100% good form, but I do this all the time:
 Foobar foo = new Foobar();
 if(foo){
  writefln("foo is not null!");
 }

In the above case, '$' would be equivalent to 'foo' rather than 'true'. - Eric Anderton at yahoo
Feb 16 2006
prev sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
James Dunne wrote:
 foreach (int i, int val; myValues) {
     writefln($);
 }
 
 This could be possibly solved by making $ an array of somehow boxed 
 values here.  Then you could do $[0] to refer to int i and $[1] to refer 
 to int val in the example above.  Alas, inout values get tricksy here... 
 [Those tricksy hobbitses!]
 

Mayhap an implicitly implanted structure template? # struct $(K, V) { # K key; # V value; # } So then: # foreach (int i, int x; myValues) { # writefln("myValues[%d] == %d"c, $.key, $.value); # } Although now I fail to see the real advantage over just using 'i' and 'x' directly... Except maybe in using mixins and other templates as part of a loop body? -- Chris Nicholson-Sauls
Feb 16 2006
parent pragma <pragma_member pathlink.com> writes:
In article <dt2riq$1bsh$1 digitaldaemon.com>, Chris Sauls says...
James Dunne wrote:
 foreach (int i, int val; myValues) {
     writefln($);
 }
 
 This could be possibly solved by making $ an array of somehow boxed 
 values here.  Then you could do $[0] to refer to int i and $[1] to refer 
 to int val in the example above.  Alas, inout values get tricksy here... 
 [Those tricksy hobbitses!]
 

Mayhap an implicitly implanted structure template? # struct $(K, V) { # K key; # V value; # } So then: # foreach (int i, int x; myValues) { # writefln("myValues[%d] == %d"c, $.key, $.value); # }

That might work. It depends on what Walter's interpretation of things is. I'm just trying to "genericize" the tabled solutions surrounding the "Q&D regex support".
Although now I fail to see the real advantage over just using 'i' and 'x'
directly... 
Except maybe in using mixins and other templates as part of a loop body?

Again, it's all about getting some kind of universal shorthand going.
# foreach (myValues) { // note the subtle change :)
#   writefln("myValues[%d] == %d"c, $.key, $.value);
# }

I suppose that if this falls into the Q&D use-case for the language, than the overhead of *always* using key-value iteration on a single-statement foreach may be acceptable. That would eliminate the need for the compiler to inspect the contents of the loop body in order to diagnose its useage. - Eric Anderton at yahoo
Feb 17 2006
prev sibling parent reply Serg Kovrov <dyh pathlink.com> writes:
Personally, I do not like perl-style 'special variables'. I like 
variables to be explicitly assigned. For clarity sake, and to avoid 
issues with nested statements, etc... But thats just me.

It is perfectly ok for me to use constricts like:

arr[arr.indexof('a') .. arr.length];

There is no need to any special variable.

But it would be a good thing if in statements like ?/if/else/while/for 
will be a way to assign results of expressions to a variable explicitly. 
Since the = operator is forbidden inside expression perhaps some other 
symbol could be used to assign result of expression to a variable:

if (match : "foo" ~~ "bar")
    writefln("first: %s", match);

or even:
if (match1 : "foo" ~~ "bar" || match2 : "some" ~~ "other")
    writefln("the match was: %s", match1.isEmpty ? match2 : match1);

Similarly for the rest of statements which has own scope. One thing to concern for: is a type of variable needed or it is auto? For example if I want to assign result of match expression (which is a string, i believe) to a class MyString for some reason... Anyway, this needs to be think over tough. No rush please. pragma wrote:
 The idea is quite possibly a misnomer, but I wanted to coalesce the flurry of
 ideas on the '$', one last time, as a unified proposal for inclusion into D.
 
 It was proposed that '$' be used as a stand in for 'this array' when working
 within the slice syntax area.
 
 array[$.indexof('a')..$.length];

This has a certain undeniable appeal, and is quite flexable. Walter has proposed a shorthand syntax for the _match symbol, which is provided behind the scenes as a product of the opMatch operation. Were it expanded in a similar way, then we could see code like this:
 if("foo" ~~ "bar"){
    writefln("first: %s",$.something); // $ would equal _match in DMD 0.147
 }

What I propose is that the '$' operator be taken to its logical conclusion and be used to refer the current scope, so that *all* D constructs can benefit from this concept: []: $ represents the current array foreach: $ represents the current value of iteration ?/if/else/while/for: $ represents the (non-boolean) result of the 'if' expression switch: $ represents the result of the switch expression (function body): $ is equivalent to _arguments (when applicable) The only thing I can't quite figure out is key/value iteration on foreach. Any takers? - Eric Anderton at yahoo

Feb 17 2006
parent reply pragma <pragma_member pathlink.com> writes:
In article <dt4jss$2rcd$1 digitaldaemon.com>, Serg Kovrov says...
Personally, I do not like perl-style 'special variables'. I like 
variables to be explicitly assigned. For clarity sake, and to avoid 
issues with nested statements, etc... But thats just me.

It is perfectly ok for me to use constricts like:

arr[arr.indexof('a') .. arr.length];

There is no need to any special variable.

But it would be a good thing if in statements like ?/if/else/while/for 
will be a way to assign results of expressions to a variable explicitly. 
Since the = operator is forbidden inside expression perhaps some other 
symbol could be used to assign result of expression to a variable:

if (match : "foo" ~~ "bar")
    writefln("first: %s", match);

or even:
if (match1 : "foo" ~~ "bar" || match2 : "some" ~~ "other")
    writefln("the match was: %s", match1.isEmpty ? match2 : match1);


That's an interesting point, its a shame that you can't do this:
if (auto match = ("foo" ~~ "bar")){ /*...*/ }

But via my proposal, you could do this:
if ("foo" ~~ "bar"){ 
   auto match = $;
}

.. which is something that you'd only really want to do if you had nesting that conflicted with the repeated use of '$'.
Similarly for the rest of statements which has own scope.

One thing to concern for: is a type of variable needed or it is auto? 

It would have to be an 'auto' in every case. The coder would have to be aware of the consequences of the statement that $ represents so that they can cast it to whatever type is needed.
For example if I want to assign result of match expression (which is a 
string, i believe) to a class MyString for some reason...

Anyway, this needs to be think over tough. No rush please.

Agreed. So, in review, and much revision, we have this: *Arrays (slice operator)
# char[] myString = "hello world";
# myString[$.indexof('h')..$.length];

*Foreach (allows single argument foreach suitable for regexp)
# foreach("\w*" ~~ "hello world"){
#   writefln("match: #%d is %s",$.key,$.value);
# }

*While
# while(iter.remaining){
#   writefln("%d items left",$);
#   iter.next;
# }

*For
# for(uint i=0; iter.remaining; i++,iter.next){
#   writefln("%d items left",$);
# }

*Branching (if/else)
# Foobar foo;
# if(foo){
#   writefln("foobar is not null: %s",$);
# }
# else{
#   assert($ is null);
# }

*Branching (?: operator)
# Foobar foo = getFoobar() ? $ : new Foobar();

*Switch
# switch(doSomething()){
# case 'y':
# case 'x':
#   writefln("x or y: %s",$);
#   break;
# default:
#   writefln("Unknown case: %s",$);
# }

I'll drop the function body _arguments alias from the proposal, unless anyone can think of a better use for it. - Eric Anderton at yahoo
Feb 17 2006
parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
pragma wrote:

 # foreach("\w*" ~~ "hello world"){
 #   writefln("match: #%d is %s",$.key,$.value);
 # }


This would mean that you had to type $.value.match(0), which is even more verbose than the _match.match(0) $ was intended to help make shorter. My suggestion is that $ by itself refers to the value. If it is necessary to have something to refer to the key, it could be called $key, but maybe the only way to get the key should be to use the full form: foreach(int i, int x; arr)... (and if there was a $key, maybe $value should be an alias to $...)
 *Branching (?: operator)
 
 # Foobar foo = getFoobar() ? $ : new Foobar();


I kind of like this one, but it is not very obvious to whoever reads the code that a new scope has been introduced... One will really have to be aware of the often changing binding of $. I otherwise agree with you on what $ should bind to. /Oskar
Feb 17 2006