Thread overview
[Issue 5081] New: Pure functions as initializers for immutable structures
Oct 19, 2010
Tomasz Sowiński
Jul 09, 2011
yebblies
Aug 25, 2011
Walter Bright
October 19, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5081

           Summary: Pure functions as initializers for immutable
                    structures
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: tomeksowi@gmail.com


--- Comment #0 from Tomasz Sowiński <tomeksowi@gmail.com> 2010-10-19 11:49:42 PDT ---
From my post on D newsgroup:

Initializing immutable structures is a source of constant grief. Anything non-trivial requires instancing a mutable structure, initializing it, and then either casting to immutable (it's up to you to ensure no alias leaked) or, not to violate the type system, duplicate the whole.

Yet, if there was a situation where the alias leaking is under control, casting would be safe. Perhaps pure* functions are such a place. They can only touch the immutable world, whether through globals or through their parameters. So if one initializes the returned structure with a reference to the outside world, it will be immutable. And if you stuff the structure with anything mutable, it must have been created within the function's body, so no alias leaks.

I think it is safe to implicitly convert a pure function's return value to immutable.

* here by pure I mean either the old pure** when it still had immutable arguments, or Don's "immutably pure".

Pure functions could be used as follows:

pure T make(Args args) { ... }
unittest {
    T t = make(...); // good
    immutable T t = make(...); // also good
}

Michel Fortin also noticed a nice-to-have: if at the call site you know that all the arguments you're feeding the function with are immutable, then you can automatically cast the result to immutable, even if the function can also accept const arguments.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 31, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5081


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #1 from bearophile_hugs@eml.cc 2010-10-31 16:31:54 PDT ---
See also bug 5147 for a different solution

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



--- Comment #2 from Steven Schveighoffer <schveiguy@yahoo.com> 2011-02-24 12:47:49 PST ---
(In reply to comment #0)

> Michel Fortin also noticed a nice-to-have: if at the call site you know that all the arguments you're feeding the function with are immutable, then you can automatically cast the result to immutable, even if the function can also accept const arguments.

Note actually that as long as you can verify the return value did not come directly from the parameters, it's also possible to implicitly cast to immutable.

For example:

pure T[] mydup(T)(const(T)[] param) {...}

It's provable that the return value did not come from param (without a cast), because you can't implicitly cast param to T[].  So you can cast the result to immutable, even if param began as mutable.

This might be really tricky to implement though, there can be all sorts of weird cases.

But if this could be accomplished, it would completely negate the need for idup.

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


yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
                 CC|                            |yebblies@gmail.com


--- Comment #3 from yebblies <yebblies@gmail.com> 2011-07-09 13:11:16 EST ---
https://github.com/D-Programming-Language/dmd/pull/218

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


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |FIXED


--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> 2011-08-24 19:48:32 PDT ---
https://github.com/D-Programming-Language/dmd/commit/af3efb7e963a65b5abe639df04add44a24d75cfa

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



--- Comment #5 from bearophile_hugs@eml.cc 2011-08-24 20:31:58 PDT ---
This is a new part of the design of D purity, and a significant improvement for D usability.

I think the behaviours shown by this little program are correct, but I think that error message needs to be improved (completed with more details), because in some cases (like foo1) that's an acceptable operation:


string foo1() pure {
    const(char[]) s2 = ['a'];
    return s2;
}
string foo2() pure {
    return ['a'];
}
string foo3(immutable char[] s) pure {
    return s;
}
string foo4(in char[] s1, immutable char[] s2) pure {
    return s2;
}
string foo5(in char[] s) pure {
    return s; // Error: cannot implicitly convert expression (s) of type
const(char[]) to string
}
void main() {
    immutable r1 = foo1();             // OK
    immutable r2 = foo2();             // OK
    immutable r3 = foo3(['a']);        // OK
    immutable r4 = foo4(['a'], ['b']); // OK
    immutable r5 = foo5(['a']);        // Error
}


Good and complete error messages are needed to help the programmer understand her mistake and build a correct model of D semantics in her head.

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



--- Comment #6 from bearophile_hugs@eml.cc 2011-08-24 20:51:28 PDT ---
(In reply to comment #5)

> I think the behaviours shown...

Sorry, that was out of place in this enhancement request. I have opened bug 6553 for it.

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