Thread overview
[Issue 2832] New: pure function too pure
Apr 11, 2009
d-bugmail
Jul 03, 2009
Don
Oct 13, 2009
Max Samukha
Oct 13, 2009
Don
Oct 13, 2009
Max Samukha
Dec 12, 2009
Walter Bright
Aug 16, 2010
David Simcha
Sep 22, 2010
Tomash Brechko
Sep 22, 2010
Tomash Brechko
Nov 16, 2010
Jesse Phillips
April 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2832

           Summary: pure function too pure
           Product: D
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: andrei@metalanguage.com


pure int fun(int d, int divisor)
{
    if (d < 0)
        d -= divisor - 1;
    return d / divisor;
}

This doesn't compile because d is assumed to be constant. It doesn't have to because it's a private copy of the function. Beware when fixing this - any indirectly-referenced data is not part of function's private state.


-- 

July 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2832


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au




--- Comment #1 from Don <clugdbug@yahoo.com.au>  2009-07-03 02:17:24 PDT ---
Comment: Allowing this would mean that nested pure functions would no longer be able to use the parameters from the enclosing function.

pure int fun(int d, int divisor)
{
   int gun() pure { return d+1; } // would be illegal, since 'fun' could modify
d.
    return gun() + d / divisor;
}

Which in turn would mean that nested pure functions would become quite useless. So there's a price to pay.

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


Max Samukha <samukha@voliacable.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha@voliacable.com


--- Comment #2 from Max Samukha <samukha@voliacable.com> 2009-10-13 03:46:47 PDT ---
Instead of introducing another inconsistency into the language for the not-so-common case, you could take the opposite route:

pure int fun(int d, int divisor)
{
   immutable c = d;
   int gun() pure { return c + 1; }

   return gun() + d / divisor;
}

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



--- Comment #3 from Don <clugdbug@yahoo.com.au> 2009-10-13 06:06:14 PDT ---
(In reply to comment #2)
> Instead of introducing another inconsistency into the language for the not-so-common case, you could take the opposite route:
> 
> pure int fun(int d, int divisor)
> {
>    immutable c = d;
>    int gun() pure { return c + 1; }
> 
>    return gun() + d / divisor;
> }

I think the existing behaviour -- that you cannot change any of the parameters
in a pure function -- is simple and intuitive: pure functions can only modify
variables which they created themselves. A rule that pure nested functions can
use indirectly-referenced data, but cannot use parameters which are passed by
value, just seems complicated.
Especially, in the case where a parameter contains a reference to other data,
it seems folly to be allowed to change part of the parameter, but not all of
it.

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



--- Comment #4 from Max Samukha <samukha@voliacable.com> 2009-10-13 08:44:23 PDT ---
> I think the existing behaviour -- that you cannot change any of the parameters in a pure function -- is simple and intuitive: pure functions can only modify variables which they created themselves.

But the passed-by-value parts of the arguments are copied and consequently can be qualified as "variables which they created themselves".

> A rule that pure nested functions can
> use indirectly-referenced data, but cannot use parameters which are passed by
> value, just seems complicated.

I don't think it is too complicated. It can be trivially done like this:

pure int foo(in int d, ...)
{
 // now we should be able to use d in pure nested functions because it is
 // guaranteed to not change during the function call.
}

> Especially, in the case where a parameter contains a reference to other data, it seems folly to be allowed to change part of the parameter, but not all of it.

I am not sure. For example, it seems to be fairly intuitive to be able to rebind a string parameter, though changing the referenced part of it is not allowed. I would agree if D's function parameters behaved like aliases to the arguments, but they are more like the function's local variables, which arguments are assigned to.

Now that I am trying to purify some functions (most of which have no nested
functions) I need to add the useless temporaries to make them compile :(

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 12, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2832


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com
           Severity|normal                      |enhancement


--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> 2009-12-11 23:30:21 PST ---
This would reintroduce "tail-const" for the parameters, something that we tried hard to make work and failed. I'd rather just leave the parameters const. If you have to make a mutable copy, as in:

  pure int fun(int d, int divisor)
  { auto x = d;
    if (x < 0)
        x -= divisor - 1;
    return x / divisor;
  }

that isn't much of a burden, and the compiler will optimize the extra copy away anyway.

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


David Simcha <dsimcha@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dsimcha@yahoo.com


--- Comment #6 from David Simcha <dsimcha@yahoo.com> 2010-08-15 21:24:26 PDT ---
*** Issue 4630 has been marked as a duplicate of this issue. ***

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


Tomash Brechko <tomash.brechko@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |tomash.brechko@gmail.com


--- Comment #7 from Tomash Brechko <tomash.brechko@gmail.com> 2010-09-22 07:39:43 PDT ---
Note that (with dmd 2.049)

pure int f(int i)
{
  return ++i;
}

doesn't compile, yet

pure auto f(int i)
{
  return ++i;
}

does work (int return type is replaced with auto).

Also http://www.digitalmars.com/d/2.0/function.html section "Pure Functions" gives an example of assignment to parameter,

  i = y;    // ok, reading immutable global state

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



--- Comment #8 from Tomash Brechko <tomash.brechko@gmail.com> 2010-09-22 08:05:37 PDT ---
Created separate issue http://d.puremagic.com/issues/show_bug.cgi?id=4915 for "int -> auto", as auto return type escapes pure completely.

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


Jesse Phillips <Jesse.K.Phillips+D@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |Jesse.K.Phillips+D@gmail.co
                   |                            |m
         Resolution|                            |FIXED


--- Comment #9 from Jesse Phillips <Jesse.K.Phillips+D@gmail.com> 2010-11-16 13:19:39 PST ---
In the recent update of relaxed purity, this code now compiles. However I believe this is a weakly pure function as a strongly pure function requires its parameters to be immutable.

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