I really disagree strongly with the take on bash. The best solution is not to add tooling on top of bash or memorize its idiosyncrasies. It is to not use bash. That is the only way to escape its pitfalls.
Actually what language does crash when a function returns false? I mean some throw exceptions but isn't "false" a valid thing to return?
I find the same thing with makefiles - people don't understand what they're doing and expect them to work in a certain way because they haven't ever thought about build systems very deeply. Recursive assignment in Make catches almost everyone out e.g.
FLAGS=-b
COMPILE=compile $(FLAGS)
$(info compile command=$(COMPILE))
FLAGS=-a
myfile:
echo $(COMPILE) $? -o $@
outputs:
t43562@rhodes:~ make -f t.mk
compile command=compile -b
echo compile -a -o myfile
compile -a -o myfile
Despite this, making all assignments immediate to match other programming languages would take a VERY useful tool away. The more you understand these tools the more you know where to bother using them and how much effort to put into it.