Thread overview
[Issue 11046] New: [enh] Pure functions with default and out parameters are allowed
Sep 15, 2013
Maxim Fomin
[Issue 11046] Pure functions with default and out parameters are allowed
Sep 15, 2013
Maxim Fomin
Sep 15, 2013
Maxim Fomin
Sep 15, 2013
Jonathan M Davis
Sep 15, 2013
Jonathan M Davis
Sep 15, 2013
Jonathan M Davis
Sep 16, 2013
Maxim Fomin
Sep 16, 2013
Jonathan M Davis
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046

           Summary: [enh] Pure functions with default and out parameters
                    are allowed
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: maxim@maxim-fomin.ru


--- Comment #0 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-15 13:48:26 PDT ---
extern(C) int printf(const char*, ...);

pure foo(out int arg = x) { }

int x = 1;

void main()
{
   foo();
   printf("%d\n", x); // 0
}

Strictly speaking, spec does not prohibit pure functions from modifying its arguments. On the other hand, there is no much sense in supporting such code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046


Maxim Fomin <maxim@maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[enh] Pure functions with   |Pure functions with default
                   |default and out parameters  |and out parameters are
                   |are allowed                 |allowed


--- Comment #1 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-15 14:01:10 PDT ---
Sorry, it is definitely a bug because global variable is mutable.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046



--- Comment #2 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-15 14:02:19 PDT ---
Another test-case:

int a;

pure foo(ref int a = a) { ++a; }

void main() pure
{
   foo();
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046


Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |jmdavisProg@gmx.com
         Resolution|                            |WONTFIX
            Summary|Pure functions with default |[enh] Pure functions with
                   |and out parameters are      |default and out parameters
                   |allowed                     |are allowed


--- Comment #3 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-09-15 14:04:06 PDT ---
Of course, it makes sense to support such code. In such a case, it's a weakly pure function rather than a strongly pure one. It can then be used by strongly pure functions.

Weakly pure functions are functions which which cannot access global mutable state (e.g. they can't access mutable global variables or have mutable static variables in their bodies). By itself, that is _all_ that pure indicates. It means _nothing_ about altering its arguments or returning the same value every time or anything of the sort.

Strongly pure functions are pure functions whose parameters are all either immutable or implicitly convertible to immutable. In such a case, the compiler can guarantee that the function's arguments aren't mutated, and the compiler can take advantage of that for optimization - e.g. calling foo only once in the expression foo(2) * foo(2). Weakly pure functions cannot be optimized like that, but they can be called from strongly pure functions (since they do not affect anything outside of the strongly pure function and therefore do not affect its guarantees), so they become very useful in writing strongly pure functions.

So, pure in D really is not functional purity. Rather, it provides the building blocks for function purity (and strongly pure functions are then functionally pure).

In fact, the primary benefit of pure is arguably the fact that it guarantees that the function does not access global mutable state rather than anything to do with functional purity or optimizations.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046



--- Comment #4 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-09-15 14:06:27 PDT ---
> Sorry, it is definitely a bug because global variable is mutable.

It mutates global mutable state via one of its arguments. pure functions cannot access global mutable state _directly_, but they can do so if passed a reference or pointer to global data. This is intended behavior and does not present a problem. It's just fine for weakly pure functions and violates nothing for strongly pure functions (because they could never pass a reference or pointer to  a weakly pure function, because they can't access them).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046


safety0ff.bugz@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |safety0ff.bugz@gmail.com


--- Comment #5 from safety0ff.bugz@gmail.com 2013-09-15 14:44:56 PDT ---
I think the problem is this:

import std.stdio;

pure foo1() { bar();}   // Compiles (accepts-invalid)
//pure foo2() { bar(x);} // Equivalent but doesn't compile (correct behaviour)

pure bar(out int arg = x) { }

int x = 1;

void main()
{
        foo1();
        writeln(x); // 0
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046



--- Comment #6 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-09-15 14:55:05 PDT ---
> I think the problem is this:

_That_ is a bug and should be reported as such, but it's different from arguing that pure functions should not be allowed to have out parameters with default arguments, which is what this enhancement request was asking for. It also has nothing to do with out parameters, unlike this enhancement request.

I just reported the issue: Bug# 11048

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046



--- Comment #7 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-15 22:53:56 PDT ---
(In reply to comment #6)
> > I think the problem is this:
> 
> _That_ is a bug and should be reported as such, but it's different from arguing that pure functions should not be allowed to have out parameters with default arguments, which is what this enhancement request was asking for. It also has nothing to do with out parameters, unlike this enhancement request.
> 
> I just reported the issue: Bug# 11048

The issue was _not_ about banning all pure functions with out parameters for which there are default values, but about not taking into account module scope of default argument. This is essentially the same issue (dmd does not check status) you reported but with a better test case.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11046



--- Comment #8 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-09-16 09:33:03 PDT ---
> The issue was _not_ about banning all pure functions with out parameters for which there are default values, but about not taking into account module scope of default argument. This is essentially the same issue (dmd does not check status) you reported but with a better test case.

Well, then you needed to have been clearer in the title and description of the issue. "Pure functions with default and out parameters are allowed!" says nothing about global variables, and while the default argument in the example happens to use a global variable, the text that goes with it talks about modifying the arguments, not about global variables, and the fact that a pure function can modify its arguments is completely acceptable. It's just a weakly pure function rather than a strongly pure one in that case.

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