Re: Delegates: Print 0..9

2016-12-02 Thread Timon Gehr via Digitalmars-d-learn

On 01.12.2016 21:12, Ali Çehreli wrote:



This is a common issue with D and some other languages (as I had learned
during a Dart language presentation, of which Dart does not suffer
from). All those delegates do close on the same loop variable. You need
to produce copies of the variable.


This is a common misconception. It's an implementation bug. The 
variables /are/ distinct. It is actually memory corruption. Evidence:


import std.stdio;

void main(){
int delegate()[] dgs;
foreach(immutable i;0..10){
dgs~=()=>i; // i is immutable
}
foreach(dg;dgs) writeln(dg()); // yet changes
dgs=[];
foreach(i;0..10){
int j=i; // creating a new variable
dgs~=()=>j;
}
foreach(dg;dgs) writeln(dg()); // does not help
}



Re: Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

On Thursday, 1 December 2016 at 20:12:15 UTC, Ali Çehreli wrote:


First, the scary syntax that produces a lambda from an int:
...
Better:
...


All methods.. Thank you!


Re: Delegates: Print 0..9

2016-12-01 Thread Ali Çehreli via Digitalmars-d-learn

On 12/01/2016 11:28 AM, unDEFER wrote:
> Hello!
> Simple using of delegates:
>
> ===
> #!/usr/bin/rdmd
> import std.stdio;
>
> void main()
> {
> void delegate() functions[];
>
> foreach (i; 0..10)
> {
> void print()
> {
> writefln("%s", i);
> }
>
> functions ~= &print;
> }
>
> foreach (i; 0..10)
> {
> functions[i]();
> }
> }
> =
>
> Prints
> $ ./delegates.d
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9
>
> How to print 0..9?

This is a common issue with D and some other languages (as I had learned 
during a Dart language presentation, of which Dart does not suffer 
from). All those delegates do close on the same loop variable. You need 
to produce copies of the variable.


First, the scary syntax that produces a lambda from an int:

import std.stdio;

void main()
{
// Note: dmd's -de command line switch warned me about the use of
// C-style syntax, so I moved the brackets after the type name:
void delegate()[] functions;

foreach (i; 0..10)
{
void print(int j)
{
writefln("%s", j);
}

functions ~= ((a) => (() => print(a)))(i); // <-- SCARY
}

foreach (i; 0..10)
{
functions[i]();
}
}

Better:

// Returns a lambda
auto makePrinter(int j) {
return {  // <-- returns a lambda
writefln("%s", j);
};
}

functions ~= makePrinter(i);

But of course there are better ways of doing things e.g. producing 
numbers. Here is one with D's ranges:


import std.stdio: writeln;
import std.range: iota;
import std.algorithm: each;

void main() {
10.iota.each!writeln;
}

Ali



Re: Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

Yes, I have found:

=
#!/usr/bin/rdmd
import std.stdio;

void main()
{
void delegate() functions[];

foreach (i; 0..10)
{
auto get_print(int i)
{
void print()
{
writefln("%s", i);
}

return &print;
}

functions ~= get_print(i);
}

foreach (i; 0..10)
{
functions[i]();
}
}
=

Thank you!


Delegates: Print 0..9

2016-12-01 Thread unDEFER via Digitalmars-d-learn

Hello!
Simple using of delegates:

===
#!/usr/bin/rdmd
import std.stdio;

void main()
{
void delegate() functions[];

foreach (i; 0..10)
{
void print()
{
writefln("%s", i);
}

functions ~= &print;
}

foreach (i; 0..10)
{
functions[i]();
}
}
=

Prints
$ ./delegates.d
9
9
9
9
9
9
9
9
9
9

How to print 0..9?