Improvement in pure functions specification

Observer via Digitalmars-d digitalmars-d at puremagic.com
Thu Dec 22 10:04:51 PST 2016


On Wednesday, 21 December 2016 at 01:05:50 UTC, Jonathan M Davis 
wrote:
> On Tuesday, December 20, 2016 19:58:38 Andrei Alexandrescu via 
> Digitalmars-d wrote:
>> On 12/20/16 7:40 PM, Timon Gehr wrote:
>> > On 20.12.2016 23:49, Andrei Alexandrescu wrote:
>> >> https://github.com/dlang/dlang.org/pull/1528 -- Andrei
>> >
>> > Good, except:
>> >
>> > "$(P `pure` functions returning `void` will be always called 
>> > even if it is strongly `pure`. The implementation must 
>> > assume the function does something outside the confines of 
>> > the type system and is therefore not allowed to elide the 
>> > call, even if it appears to have no possible effect.)"
>> >
>> > I think this makes no sense. What is the idea behind this 
>> > paragraph?
>>
>> A function that traces execution via a debug statement, for 
>> example. -- Andrei
>
> Well, ultimately, strongly pure functions that return void are 
> either doing something that works around the type system (e.g. 
> using debug statements to do operations which aren't pure), or 
> they arguably shouldn't even compile, because they can't 
> possibly do anything that has any effect on the program beyond 
> eating up CPU time. So, as far as I can tell, we should either 
> make an exception for them (as the PR currently does) or make 
> them illegal.

It seems to me that a pure function could have a variety of
acceptable side effects which don't modify active memory and
that don't work around the type system or necessarily eat
significant CPU time, and that you probably don't want to
have elided.  Here are some examples.

(1) Serve as a convenient breakpoint handle in the debugger, 
perhaps
     as a kind of centralized this_cannot_ever_happen() function.
(2) conditionally_die(conditions);
(3) Sleep for some run-time-computable length of time.
(4) Yield the thread so other threads can take execution priority.
(5) Yield the entire process so other processes can take execution
     priority.
(6) Wait for an external trigger (perhaps a hardware interrupt, 
for
     instance).
(7) Invoke a pass of garbage collection.

Aside from the first, whether or not the pure function actually 
takes
that action might depend on some complex calculation run inside 
the
pure function.

My point here is that when considering what functions do, mutating
memory is only part of the story.  Control of time and other 
resources
can be a critical part of overall program execution, and you 
don't want
the compiler assuming it can ignore such aspects.


More information about the Digitalmars-d mailing list