Impurity is a lack of constraints. You can, with impure code, write an interpreter for a language that constrains code to being pure, and implemented correctly, you can then depend on code written in that langauge to be pure.
His point is that there's no lost benefit in calling pure code from impure code - the code is already unconstrained. Calling impure code from pure code, though, means you've lost the purity constraint, which means you've lost the nice emergent properties you get from that constraint.
Even if you write 'pure' code in an impure environment, you can't depend on it being pure, because that constraint isn't actually enforced. No matter how pure I try to keep my Javascript, I can never depend on it being pure - there could be a bug, or someone could add impurity at the bottom of the callstack, breaking referential transparency.
Following your argument to the extreme, Haskell is also an impure language: there could be a bug in the compiler, or someone could introduce impurity in it! Even worse, someone could call unsafePerformIO!
You would argue: but that goes against the Haskell specification, that impurity is not proper Haskell!
And exactly: the "purity" comes from an abstraction, which is a contract between you and some other developers. The fact that JavaScript the language does not enforce such contracts does not mean that you can not get into agreements with other developers. Sure, the JavaScript interpreter won't complain when the contract is broken, in the same way that the CPU is not complaining when Haskell has a bug, in this case, JavaScript is not the one making the purity promise---a developer is.
As such, I believe that in JavaScript, a library author can make claims about the purity of some code. Sure, some adversarial coder could use monkeypatching to break it---and some adversarial coder could also gives you instances of some type class that call unsafePerformIO under the hood. In the end, we are talking about degrees to which some purity can be ensured, and levels at which the contracts are enforced.
I know some Haskell developers would like to think that they are programing in this perfect language and that it is impossible to do functional programming in other languages. But I disagree, and actually, I believe that bringing the design tools of functional programming to mainstream languages is a worthy goal that should not be discouraged.
In theory it would be possible to write a specification for a pure subset of JavaScript. But it's very important to acknowledge that this pure subset doesn't exist, and won't exist unless and until such a specification is written, to the point that it's possible to write an automated tool that can verify whether a given piece of code conforms to this specification. And if such a specification did exist, we would likely call it a "language" in its own right.
Once you write that language and confirm that your library conforms to it you can say your library is pure. Saying your library is pure before you've actually formally checked it is like saying your library doesn't have any bugs in before you've made any attempt to look for them - i.e. almost certainly a false, and so irresponsible to claim that it qualifies as a lie in my book.
I 100% agree that purity is still incredibly useful for reasoning about and maintaining code in any language, but I think you're underselling the benefits of statically verifying that you haven't unintentionally introduced impurity somewhere. Oh, and ideally it'd also allow for some nice optimisations, but I'm not sure to what extent that's being done.
His point is that there's no lost benefit in calling pure code from impure code - the code is already unconstrained. Calling impure code from pure code, though, means you've lost the purity constraint, which means you've lost the nice emergent properties you get from that constraint.
Even if you write 'pure' code in an impure environment, you can't depend on it being pure, because that constraint isn't actually enforced. No matter how pure I try to keep my Javascript, I can never depend on it being pure - there could be a bug, or someone could add impurity at the bottom of the callstack, breaking referential transparency.