www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4974] New: Cannot have pure constructor due to impure invariant

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

           Summary: Cannot have pure constructor due to impure invariant
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: jmdavisProg gmx.com



PDT ---
This code

struct S
{
    this(int x) pure
    {
        this.x = x;
    }

    invariant()
    {
        assert(x >= 0);
    }

    int x;
}

void main()
{
}


results in this compilation error

Error: pure function 'this' cannot call impure function '__invariant'
d.d(8): Error: function d.S.__invariant () is not callable using argument types
()
Error: pure function 'this' cannot call impure function '__invariant'


Maybe this will be fixed by the changes that Don has suggested, I don't know.
But with dmd 2.049, it is, as far as I can tell, impossible to have a pure
constructor and an invariant - and the lack of a pure constructor really limits
how much you can make pure. There doesn't appear to be a way to make invariant
pure either.

So, I see three possible solutions

1. Make it possible to mark invariants as pure.
2. Consider invariant pure as long as it doesn't access mutable globals.
3. Have invariant act like it's pure but don't care whether it really is or
(probably better) output a warning if it isn't.



writeln() and have a pure invariant. The invariant would be compiled out in
release builds, so it wouldn't affect release code anyway. And if it means that
writeln() doesn't print as often due to a pure function call being optimized
out, then tough luck. It would just be temporary debugging code anyway. And
since there's a halfway decent chance that pure function calls don't get cached
in debug builds anyway, then you really wouldn't lose anything.


wouldn't require changing the grammar to somehow mark an invariant as pure, but
any of the three would be better than the current situation.

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


bearophile_hugs eml.cc changed:

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



See also bug 3856

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


Don <clugdbug yahoo.com.au> changed:

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



In DMD2.050, 'pure invariant()' compiles, which was your solution 1. Not sure
if that's enough to mark the bug as fixed.

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




PST ---
Well, marking an invariant as pure does seem to actually make it pure which is
a definite improvement, though honestly, I rather like the idea of the compiler
acting like all invariants are pure so that you can have pure functions and
still be able to use stuff like writeln() in your invariant when debugging. As
it is, marking an invariant as pure does seem to make it possible to have pure
functions, but it eliminates your ability to print debug statements in
invariants.

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





 I rather like the idea of the compiler
 acting like all invariants are pure so that you can have pure functions and
 still be able to use stuff like writeln() in your invariant when debugging. As
 it is, marking an invariant as pure does seem to make it possible to have pure
 functions, but it eliminates your ability to print debug statements in
 invariants.
A possible solution using the idea in bug 5125 (syntax is temporary): pure nothrow bool isDebug() { debug return true; return false; } optional_tag(ifDebug(), pure) invariant() { ... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4974





 As
 it is, marking an invariant as pure does seem to make it possible to have pure
 functions, but it eliminates your ability to print debug statements in
 invariants.
I don't think that problem is unique to invariants. It's the same issue as logging in pure functions, and in CTFE functions. You should be able to do printf-style debugging in ANY pure function. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4974






 You should be able to do printf-style debugging in ANY pure function.
Do you mean something like this? pure void foo() { debug { printf("foo"); } } And even giving the compiler an explicit debug{} tag that is tricky. In general writing is a side effect. So if your programs output is the text it produces, its output may change according to how much the compiler optimizes away pure function calls. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4974






 You should be able to do printf-style debugging in ANY pure function.
Another simple solution is to add a special pure printf version, that's just a pure alias of printf: pure void foo() { pureprintf("foo"); } pureprintf() is not meant for normal output, but just for debugging and the like. And the person that uses pureprintf() has to remember that it's not deterministic, its output may appear or not appear. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 09 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4974


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |yebblies gmail.com
         Resolution|                            |FIXED



Now that we have printing from pure functions inside debug conditions, I think
this is all solved.

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