www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - foreach UFCS

reply ixid <adamsibson hotmail.com> writes:
What is going on with UFCS and foreach?

foreach(i;0..5).writeln;

This prints five line breaks.

foreach(i;0..5).i.writeln;

This will not compile.

foreach(i;0..5).writeln(i);

This writes out 1 to 4 on separate lines. Is this supposed to 
work? I thought a.b would be rewritten to b(a) with UFCS but 
writeln(foreach(i;0..5)) is nonsensical and does not compile and 
should be the same as foreach(i;0..5).writeln;
Mar 31 2016
next sibling parent Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Thursday, 31 March 2016 at 13:39:25 UTC, ixid wrote:
 What is going on with UFCS and foreach?

 foreach(i;0..5).writeln;

 This prints five line breaks.

 foreach(i;0..5).i.writeln;

 This will not compile.

 foreach(i;0..5).writeln(i);

 This writes out 1 to 4 on separate lines. Is this supposed to 
 work? I thought a.b would be rewritten to b(a) with UFCS but 
 writeln(foreach(i;0..5)) is nonsensical and does not compile 
 and should be the same as foreach(i;0..5).writeln;
The compiler interprets it as a foreach without curly braces. With curlies it would look like: foreach(i; 0..5) { .writeln(); } In this context the dot means the writeln lookup should happen from the module level scope.
Mar 31 2016
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 31 March 2016 at 13:39:25 UTC, ixid wrote:
 What is going on with UFCS and foreach?
There's no such thing as UFCS on foreach. UFCS only works on variables, not a foreach statement.
 foreach(i;0..5).writeln;
You can add a line break and optional braces there to see what it really is: foreach(i;0..5) { .writeln; } It is just an ordinary loop calling writeln 5 times. The leading dot in D means "look up in the global namespace".
 foreach(i;0..5).i.writeln;
foreach(i; 0 .. 5) { .i.writeln; } It is trying to look up a name i in global scope, and calling writeln on it. This is why the .name syntax exists: so you can bypass local variables with the same name when trying to access a global. It would compile if you put an `int i;` at the top of your module... try it!
 foreach(i;0..5).writeln(i);
foreach(i; 0 .. 5) { .writeln(i); // leading . just means call global writeln } What you're seeing is similar to the Java hoax where people say it supports hyperlinking: public static void main() { http://dlang.org/awesome } That compiles, but it isn't a link, it just looks like one at first. It is actually a label, "http:", followed by a comment, "//dlang.org....". Two legal things without whitespace that looks like something else at first glance.
Mar 31 2016
parent ixid <adamsibson hotmail.com> writes:
On Thursday, 31 March 2016 at 13:48:27 UTC, Adam D. Ruppe wrote:
 It is trying to look up a name i in global scope, and calling 
 writeln on it.

 This is why the .name syntax exists: so you can bypass local 
 variables with the same name when trying to access a global.

 It would compile if you put an `int i;` at the top of your 
 module... try it!
Thanks, that makes sense! I had forgotten the global dot syntax. That seems like a somewhat sketchy syntax given how little one would use it, wouldn't something like: writeln(i).global; be much clearer for globals?
Mar 31 2016
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 31 March 2016 at 13:39:25 UTC, ixid wrote:
 What is going on with UFCS and foreach?

 foreach(i;0..5).writeln;
This is not UFCS; it is calling writeln on module scope. See http://dlang.org/spec/module.html#module_scope_operators Your code is semantically identical with foreach (i; 0 .. 5) { .writeln; // module scope operator! } Furthermre because there is no local variable writeln that could be confused with the imported function, the code is identical with foreach (i; 0 .. 5) { writeln; }
 This prints five line breaks.

 foreach(i;0..5).i.writeln;

 This will not compile.
It does not compile because i is not an identifier at module scope. i is a local variable and a hypothetical i at module scope (accessible via .i) is not declared, therefore this is an error.
 foreach(i;0..5).writeln(i);

 This writes out 1 to 4 on separate lines. Is this supposed to 
 work? I thought a.b would be rewritten to b(a) with UFCS but 
 writeln(foreach(i;0..5)) is nonsensical and does not compile 
 and should be the same as foreach(i;0..5).writeln;
It does rewrite. But only if there is an expression beforehand the dot. Here it just isn't. The "foreach (i; 0 .. 5)" is not a complete expression.
Mar 31 2016