2

Is getFeedbackThunk pure?

function setWinTitle(msg) {
    window.document.title = msg;
}

function getFeedbackThunk(msg) {
    return () => setWinTitle(msg);
}

voteButton.onclick = getFeedbackThunk('Thanks for voting!');

It doesn't interact with external state, and the output is always determined by the inputs. What's confusing is that the purpose of the output is to cause an effect, but I think we can say that the function itself is pure.

robC
  • 2,592
  • 1
  • 23
  • 28
  • 4
    Yes, it's pure, because you deferred the effectful computation. It is still not safe though, because nothing keeps you from unleashing the effect and compromising your pure program. You need a type that encloses the impure computation and don't give the means to extract it. For this type to be useful, it also must contain a way to compose impure computations inside itself. You probably already know what I'm talking about: The inevitable monad. In Javascript we don't have a compiler and hence the only thing we can do is using a Monad that handles deferred computations with thunks. –  May 03 '19 at 08:47
  • 1
    @bob "In Javascript we don't have a compiler" Well to be honest we have a JIT compiler. – Seblor May 03 '19 at 08:49
  • 1
    @Seblor to be even more pedantic every language above the machine level has a compiler or it wouldn't run. But in this case I'm pretty sure he means a compiler that enforces a static type system. – Jared Smith May 03 '19 at 12:01
  • @JaredSmith "to be even more pedantic every language above the machine level has a compiler or it wouldn't run." What do you mean by that? Unless you have some very strange definitions of either "compiler" or "has", that's just not true. It is perfectly possible to interpret a language without translating it to machine code (or any other language). JIT-compilers (or even bytecode compilers) are purely an optimization - it's perfectly possible to interpret programming languages with a plain AST-based interpreter. – sepp2k May 03 '19 at 15:33
  • @sepp2k I'm defining compiler as "program that transforms one form of code into another form of code", whether it happens on the fly or ahead of time. Is that an unreasonable definition? – Jared Smith May 03 '19 at 15:39
  • @JaredSmith No, that's a reasonable definition, but using to that definition, the statement "every language above the machine level has a compiler or it wouldn't run" is false. – sepp2k May 03 '19 at 15:46
  • 1
    @JaredSmith What is important at this point is that in JS you can just release the effect by calling the impure expression, because it is just wrapped in a regular thunk: `getFeedbackThunk(msg) ()`. There is no mechanism to stop you. In Haskell this thunk would look like `RealWorld -> ((), RealWorld)`, but since there is no value of type `RealWorld`, you can never call it. Only the runtime system can do this. I don't think it is possible to reproduce this behavior with an interpreter or JIT compiler, it would just be too cumbersome. –  May 03 '19 at 16:31

1 Answers1

0

In this particular example, I would agree with you. But in general (i.e. for the purpose of hinting the code optimization) there is no syntactic guarantee. In C++, there are const methods that enforce purity:

// C++ code
class Feedback {
  string state;

  // here the const guarantees not to change the state
  void getFeedbackThunk(string msg) const {
    ...
  }
};

But AFAIK there is no such const use in JS.

Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • https://stackoverflow.com/questions/45834108/can-i-restrict-a-function-to-be-pure-in-typescript – robC May 03 '19 at 10:29