RFC, ensureHeaped

bearophile bearophileHUGS at lycos.com
Wed Nov 17 05:19:39 PST 2010


Steven Schveighoffer:

>It makes me think that this is going to be extremely confusing for a while, because people are so used to pure being equated with a functional language, so when they see a function is pure but takes mutable data, they will be scratching their heads.<

I agree, it's a (small) problem. Originally 'pure' in D was closer to the correct definition of purity. Then its semantics was changed and it was not replaced by @strongpure/@weakpure annotations, so there is now a bit of semantic mismatch.

------------------------

Rainer Deyke:

> Making functions weakly pure by default means that temporarily adding a
> tiny debug printf to any function will require a shitload of cascading
> 'impure' annotations.  I would consider that completely unacceptable.

To face this problem I have proposed a pureprintf() function (or purewriteln), that's a kind of alias of printf (or writeln), the only differences between pureprintf() and printf() are the name and D seeing the first one as strongly pure.

The pureprintf() is meant only for *unreliable* debug prints, not for the normal program console output.

------------------------

spir:

>Output in general, programmer feedback in particuliar, should simply not be considered effect.

You are very wrong.


> The following is imo purely referentially transparent and effect-free (where effect
> means changing state); it always executes the same way, produces the same result,
> and never influences later processes else as via said result:
> 
> uint square(uint n) {
>     uint sq = n*n;
>     writefln("%s^2 = %s", n, sq);
>     return sq;
> }

If we replace that function signature with this (assuming writefln is considered pure):

pure uint square(uint n) { ...


Then the following code will print one or two times according to how much optimizations the compiler is performing:

void main() {
    uint x = square(10) + square(10);
}

Generally in DMD if you compile with -O you will see only one print. If you replace the signature with this one:

pure double square(double n) { ...

You will see two prints. In general the compiler is able to replace two calls with same arguments to a strongly pure function with a single call. DMD doesn't do it on floating point numbers to respect its not-optimization FP rules, but LDC doesn't respect them if you use the 
-enable-unsafe-fp-math compiler switch, so if you use -enable-unsafe-fp-math you will probably see only one print.

Generally if the compiler sees code like:

uint x = foo(x) + bar(x);

And both foo and bar are strongly pure, the compiler must be free to call them in any order it likes, because they are side-effects-free.

So normal printing functions can't be allowed inside pure functions, because printing is a big side effect (even memory allocation is a side effect, because I may cast the dynamic array pointer to size_t and then use this number. Even exceptions are a side effect, but probably they give less troubles than printing).

I have suggested the pureprintf() that allows the user to remember its printing will be unreable (printing may appear or disappear according to compiler used, optimization levels, day of the week).

Bye,
bearophile


More information about the Digitalmars-d mailing list