11

I would like to improve my understanding of the word reentrant.

Is this function reentrant?

function* foo() {
  yield 1;
  yield 2;
}

And this one?

function foo() {
  return 1;
}

And this one?

var x = 0;
function foo() {
  return x++;
}

And this one?

function foo() {
  setTimeout(foo, 1000);
}
Ben Aston
  • 53,718
  • 65
  • 205
  • 331

1 Answers1

9

A reentrent function is a function whose execution can be resumed:

In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.

In browser/node JavaScript, all multiprocessing is cooperative (no interrupts or context switches). A regular function always runs to completion in JavaScript. (1)

So in your case - the only reentrent function is the first one since it doesn't run its code to completion and can be resumed at a later point.

  • The second function is just a regular function.
  • The third one uses an outer scope, which is kind of similar because it lets a function hold some state. It's not the same thing though since the function can't be resumed.
  • The fourth one just runs to completion immediately (it schedules another invokation of it - but that's up to the platform and not JavaScript).

Indeed - one can say that generators enable cooperative multitasking in JavaScript with a reentrent syntax. Before generators all code ran to completion.

(1) Or it never halts, but it is never interrupted. Also - in common platforms. There are platforms (like Rhino) that break the rule. They're very rare and don't use the same concurrency execution model as browser/node JS.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 1
    Why 2 is not reentrant? While the javascript execution model doesn't allow it to be called multiple times at once, it is still reentrant. All regular functions are reentrant. – Sulthan Dec 07 '15 at 09:29
  • 1
    Because it cannot be interrupted in the middle of its execution and then safely called again before its previous invocation completes execution - plain and simple. More simply put - it can just not be interrupted in the middle of its execution. This is unlike generators that can declare points of interruption (yields) and be "pumped" to execution completion. – Benjamin Gruenbaum Dec 07 '15 at 09:31
  • 1
    No. Simply no. That goes against the definition. You can call (2) multiple times at once and it will still return consistently the same result. That is what makes it reentrant. The fact that JS doesn't support parallel execution doesn't have anything to do with it. The definition of reentrancy is not different for different languages. – Sulthan Dec 07 '15 at 09:36
  • 1
    JS supports parallel execution (just not threads, well, the platforms JS runs on do). I think the bit you're missing is that reentrency _requires that the function can be interrupted to begin with_. – Benjamin Gruenbaum Dec 07 '15 at 09:38
  • 1
    @freedomn-m actually, called multiple times with the same arguments resulting in the same result is purity. Idempotency means calling it multiple times has the _same effect_ as calling it once. – Benjamin Gruenbaum Dec 07 '15 at 09:39
  • 1
    That was just a simplification of the definition. I still disagree. All pure functions (e.g. (2)) are automatically reentrant. One of the basic condition for reentrancy is that "reentrant code cannot call non-reentrant routines". If you say that (2) is not reentrant, you won't be able to fulfil this condition. – Sulthan Dec 07 '15 at 09:46
  • 3
    @Sulthan If you disagree with this answer, please provide your own and the community can arrive at a consensus. – Ben Aston Dec 07 '15 at 20:09