For my 2 cents,

The more D allows 'pure' functions to diverge from functional purity the less relevant the flag is for compiler optimisations.

I think purity should be defined by what the compiler is allowed to do to a function. The results of all pure functions should be cacheable. If the compiler can prove that the arguments to a pure function are constant then the function can be run at compile time to get the result.

A more advanced compiler should be able to do a lot of optimisation based on the fact that a function is marked pure. A compiler can often prove arguments are constant when a human can't show the same easily. Other optimisation parses often expose constants that may be arguments to pure functions.

For example, a foreach loop over a small array could be unwound to remove the overhead of branching. The iterator then becomes a constant in each segment of the former loop. If the iterator is the argument to a pure function, the entire function call could be eliminated and replaced with the result.

By the same reasoning cacheability is important. A pure function might be called within a loop with a parameter that is not altered during the loop. If the compiler knows the function is pure, it can perform the calculation before the loop and simply reuse the cached result for each iteration.

New and malloc are not really pure. They return a different result each call, and the state of the PC is changed. However, if the programmer knows his function behaves in a pure way, it would be nice if a programmer could tell the compiler to go ahead and optimise away the function call anyway. Some kind of “trusted pure” tag would be required I guess.

A 'trusted pure' function would be free to allocate memory as it wishes, providing it is freed (or left for collection), and the pointer does not escape the function. From the point of view of the calling software the function is functionally pure.

My point is that if we are going to allow relaxed purity in D, then the definition should be angled towards a performance advantage. Naturally there are quite a number of other advantages of creating pure functions besides performance. If we define what compiler is allowed to do to a pure function we make reasoning about pure functions simple. It even opens the idea of 'trusted pure' functions that compiler can't prove are pure, because they may do something like call a C routine. From a compilers point of view they could be considered pure because the programmer says the compiler is free to eliminate the function call if it knows the result.


On 15/05/2014 8:42 AM, Brian Schott via Digitalmars-d wrote:
What is the plan for the "pure"-ity of memory management?

Right now the "new" operator is considered to be pure even though it is
not, but related functinos like malloc, GC.addRange, GC.removeRange, and
others are not.

This prevents large portions of std.allocator from being pure. This then
prevents any containers library built on std.allocator from being pure,
which does the same for any funcions and data structures written using
those containers.

If malloc can never be considered pure, even when hidden behind an
allocator, why can it be considered pure when hidden behind the GC?


Reply via email to