www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5641] New: Local instantiation does not save context properly

reply d-bugmail puremagic.com writes:
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



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: -------
Feb 22 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5641




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: -------
Feb 22 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5641


wfunction hotmail.com changed:

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



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: -------
Feb 22 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Feb 22 2011
prev sibling parent d-bugmail puremagic.com writes:
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



18:57:40 MSK ---

 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: -------
Nov 08 2012