Thread overview
[Issue 5641] New: Local instantiation does not save context properly
Feb 22, 2011
Andrej Mitrovic
Nov 08, 2012
Denis Shelomovskij
February 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5641

           Summary: Local instantiation does not save context properly
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrei@metalanguage.com


--- Comment #0 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-02-22 06:10:45 PST ---
The following program compiles but produces an incorrect result. It prints:

[false, false, false, false, true]

although it should print

[true, true, false, false, false]

When fixing this bug, care must be given to avoiding conservative dynamic allocation of the frames in all cases. This would consistently ruin performance of most of std.algorithm. Instead, the compiler should detect only the cases when context must be saved and only act on those cases. Saving should happen inside non-static struct Result, ideally without dynamic allocation (although I'm not sure how that would be done in the general case).

Alternatively, the compiler could reject the example as written and require the user to save the context manually, in a TBD manner. Don, Walter, let's talk about this, it's important.

After fixing, this example should work if the template map2 is removed and std.algorithm.map is used instead.

import std.algorithm, std.array, std.stdio;

template map2(alias fun)
{
    auto map2(R)(R r)
    {
        struct Result
        {
            R _input;

            this(R input)
            {
                _input = input;
            }

            @property bool empty()
            {
                return !_input.length;
            }

            void popFront()
            {
                _input.popFront();
            }

            @property auto ref front()
            {
                return fun(_input.front);
            }
        }

        return Result(r);
    }
}

auto fun(int[] a)
{
    auto y = 42;
    auto m = map2!((x) { return x == y; })(a);
    return m;
}

void main()
{
    auto a = [ 1, 2, 3, 4, 5 ];
    auto m = fun(a);
    writeln(m);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5641



--- Comment #1 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-02-22 06:32:25 PST ---
Correction. The program should print "[false, false, false, false, true]". Alternatively, replacing y = 42 with y = 3 should print the originally claimed output.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5641


wfunction@hotmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wfunction@hotmail.com


--- Comment #2 from wfunction@hotmail.com 2011-02-22 11:46:25 PST ---
Apparently, type-inference also has a problem here:

This code:
    int b = 5;
    writeln(map!((a) { return a + b; })([0, 1, 2, 3]));
outputs:
    [1637916, 1637917, 1637918, 1637919]

if I specify the type of 'a' manually:
    int b = 5;
    writeln(map!((int a) { return a + b; })([0, 1, 2, 3]));
it outputs:
    [0, 1, 2, 3]

Of course, both answers are incorrect, but this might be an indication of another bug; I don't know.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5641


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com


--- Comment #3 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2011-02-22 12:10:35 PST ---
A workaround for those that need this code to work is to use static (it can be used for type inference just like auto):

import std.stdio;
import std.algorithm;
auto fun(int[] a)
{
    static y = 3;
    return map!((x) { return x == y; })(a);
}
void main()
{
    auto a = [ 1, 2, 3, 4, 5 ];
    auto m = fun(a);
    writeln(m);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5641


Denis Shelomovskij <verylonglogin.reg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |verylonglogin.reg@gmail.com
         Resolution|                            |DUPLICATE


--- Comment #4 from Denis Shelomovskij <verylonglogin.reg@gmail.com> 2012-11-08 18:57:40 MSK ---
(In reply to comment #1)
> Correction. The program should print "[false, false, false, false, true]". Alternatively, replacing y = 42 with y = 3 should print the originally claimed output.

The program from description should print only `false`, after replacing `y = 42` with `y = 3` it should print the only `true` in a middle.

And this is essentially same as Issue 7965 which is fixed so I mark this one as a duplicate.

*** This issue has been marked as a duplicate of issue 7965 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------