www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3995] New: Can't access array/AA from function literal defined inside the array/AA's initializer

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3995

           Summary: Can't access array/AA from function literal defined
                    inside the array/AA's initializer
           Product: D
           Version: 1.050
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: cbkbbejeap mailinator.com
            Blocks: 340



12:38:04 PDT ---
I find this idiom very useful, particularly for handling domain-specific
languages:

------------------------------
auto dgMap = [
    "foo": (int i) {
        return /+..stuff..+/;
    },
    "bar": (int i) {
        return /+..stuff..+/;
    },
    "bat": (int i) {
        return /+..stuff..+/;
    },
];
dgMap["bar"](4);
------------------------------

However, those functions cannot refer to each other or use recursion even
though doing so would be perfectly safe:

------------------------------
auto dgMap = [
    "foo": (int i) {
        if(i < 1)
            return 0;
        else
            // Recursion, would be perfectly safe if allowed.
            // ERROR: undefined identifier dgMap
            return dgMap["foo"](i-1);
    },

    "bar": (int i) {
        // Call different element: would be perfectly safe if allowed.
        // ERROR: undefined identifier dgMap
        return dgMap["foo"](7);;
    }
];
------------------------------

This is a bit of a pain, as it can't be solved without giving up either the
locality of the in-line delegate literals or the type inference of the array/AA
(which is *very* useful in this sort of situation).

I'm not sure if this counts as an enhancement or a declaration-order bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 20 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3995




12:48:27 PDT ---
The above example might have a problem inferring the return type of the
delegate literals (and therefore the type of 'dgMap' itself). But this
alteration doesn't have that problem and still fails to compile with "undefined
identifier dgMap":

---------------------
auto dgMap = [
    "foo": delegate int(int i) {
        if(i < 1)
            return 0;
        else
            return dgMap["foo"](i-1);
    },

    "bar": delegate int(int i) {
        return dgMap["foo"](7);;
    }
];
---------------------

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 20 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3995


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies gmail.com
           Platform|Other                       |All
            Version|1.050                       |D1 & D2
             Blocks|340                         |
         OS/Version|Windows                     |All
           Severity|normal                      |enhancement



This is working as intended.

Variables are not added to the scope until after their initializers are
processed, preventing garbage like this:

int x = x;

And other cases where this would make it possible to refer to uninitialized
variables that, even when they have an initializer.

A trivial workaround is the following:

int delegate(int)[string] dgMap;
auto tmp = [ ... delegate definitions referring to dgMap ... ];
dgMap = tmp;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 01 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3995


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID



I think this is invalid, letting the initializer reference the variable is a
real pain in c++, and was intentionally disallowed in D.

While it can be useful in some cases (when used carefully) I doubt it's worth
adding (for this case or in general), especially when there's such a trivial
workaround.

Nick, please reopen if you disagree.

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