You might be able to make a pure functions, if you don't consider type errors to be side effects (which I do if they don't require explicit catching, which is unlikely in a dynamic language), but that doesn't make the entirety of the language pure.
How are you going to represent effects? As you pointed out you will need at some point. Untyped monads? A framework like TEA but error resistant?
So, you might be able to do it, but it's going to be a bit awkward at least, which is why I said "almost by necessity".
We’re a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.