On Thu, Apr 19, 2012 at 7:25 AM, Christophe <travert@phare.normalesup.org> wrote:
"Brad Anderson" , dans le message (digitalmars.D.learn:34902), a écrit :
> Perhaps I'm just misunderstanding something about closures but
> the following code seems to behave oddly:
>
>      import std.stdio, std.range, std.algorithm, std.string;
>
>      void main()
>      {
>          auto lst = ["a", "b"];
>          auto rng = range_gen(lst);
>          writeln(rng.take(5));
>      }
>      auto range_gen(string[] lst)
>      {
>          auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0],
> a))();
>          return chain(lst, a); // access violation
>          //return a; // works
>      }

My guess is that chain takes lst by reference, just like the delegates
for map, wo both are working on the same slice instance. The chain first
pops elements from lst, and then calls the mapped sequence. At that
time, lst is empty.

You can just copy lst before you give it to chain (or to map's delegate)
to solve this bug:

auto range_gen(string[] lst)
{
    auto a = sequence!"n+1"().map!(a=>format("%s%d", lst[0], a))();
    string[] lst2 = lst;
    return chain(lst2, a); // access violation
}


Ah, that would make sense.  I'll test and make sure when I get home. Range consumption tricks me more often than I wish.  I'll eventually learn to look out for it more actively.

Regards,
Brad Anderson