Hacker News new | past | comments | ask | show | jobs | submit login

No enforcing! This is useful even when it's, strictly speaking, a lie.

Suppose I want to add some debug tracing into f():

   f.c: 42: f entered
   f:c: 43: returning 2
that's a side effect, right? But now the pure attribute tells a lie. Never mind though; I don't care that some calls to f are "wrongly" optimized away; I want the tracing for the ones that aren't.

In C++ there are similar situations involving temporary objects: there is a freedom to elide temporary objects even if the constructors and destructors have effects.

Even a perfectly pure function can have a side effect, namely this one: triggering a debugger to stop on a breakpoint set in that function!

If a call to f(2) is elided from some code, then that code will no longer hit the breakpoint set on f.

Side effect is all P.O.V. based: to declare something to be effect-free in a conventional digital machine, you have to first categorize certain effects as not counting.




Such attributes would be most useful if the semantics were that any time after a program receives inputs that would cause a "pure" function to be called with certain arguments, a compiler may at its leisure call the function with those arguments as many or as few times as it sees fit.

The notion that "Undefined Behavior" is good for optimization is misguided and dangerous. What is good for optimization is having semantics that are loose enough to give the compiler flexibility in how it processes things, but tight enough to meet application requirements.

Instead of saying that compilers can do anything they want when their assumptions are violated, it would be far more useful to recognize what they are allowed to do on the basis of certain assumptions. For example, given a piece of code:

    long long test1(long long x, int mode)
    {
      while(x)
        x = slow_function_no_side_effects(x);
      return x;
    }

    void long test2(long long x, int mode)
    {
      x = test1(x);
      if (!mode)
        x=0;
      doSomething(x);
    }
It would generally be useful and safe to allow a compiler that determines that no individual action performed by "test1()" could have any side effects may omit the call to "test1()" if its value never ends up being used, without having to prove that the slow function with no side effects will eventually return zero. It is likewise useful and safe to say that if the generated code observes either that the loop exits or that "mode" is zero, it may replace the call "doSomething(x)" with "doSomething(0)". The fact that both optimizations would be safe and useful individually, however, does not imply that it would be safe and useful to allow compilers to change the code for "test2()" so that it calls "doSomething(0)" or otherwise allow code to observe that the value of "x" is zero when mode is non-zero, without regard for whether "test1()" would complete.


> flatfinger

https://news.ycombinator.com/user?id=supercat

?

If you contact the HN gods maybe there is a way to recover access to that account.


Just offer a -Wpure flag for checking if functions are pure. That way production/test releases can check while you can still use it for debugging.

Also, the problem with eliding breakpoints already exists afaik, since the compilers already check for pure functions.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: