What’s a “thunk”?
An archaic old name for an old concept
I remember when everyone started talking about using “thunks” in Redux to execute code without blocking the UI. And I remember getting tripped up on the word “thunk”. What’s a “thunk”? Why are we calling it that?
The term “thunk” goes all the way back to ALGOL 60! It’s a play on “think”, because the ALGOL compiler needed to “think” about what sort of subroutines to generate. ALGOL allows passing expressions as arguments to subroutines, not just constants. One way of allowing this is to substitute the expression for another subroutine that evaluates the expression when the original subroutine call happens. This new subroutine is the “thunk” - the result of the “thinking”.
In redux-thunk, thunks are passed as an argument to dispatch
, which delays their execution until after the React render cycle. This avoids blocking the UI thread when state updates need to happen. If actions need any async logic like making API calls, thunks are the way to handle it.
I think Redux made a mistake using the word “thunk” here, when most programming languages have a concept of an inline function definitions and delayed execution. This sort of behavior is everywhere. In Go’s sort.Slice, you pass a thunk that gets called over and over:
ints := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}
sort.Slice(ints, func(i, j int) bool {
return ints[i] < ints[j]
})
Python uses thunks all over, as “lambdas”:
ints = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
ints.sort(key=lambda x: -x) # sort in reverse
“Lambda” isn’t much better as a term for inline function definition, but at least most programmers are exposed to it. The term “thunk”, though, makes you think that you have to learn some deep new concept.