True. You have to learn to treat programs written in dynamic languages as living, mutable, interactive things instead of designs set in stone. However, when a simple syntax derails your reading, it is a thing of concern.
Then again, you could make similar shenanigans in Common Lisp with `symbol-macrolet', but it's obscure feature that pretty much by definition will be used only by people who know when to use it :).
> However, when a simple syntax derails your reading, it is a thing of concern.
Definitely agreed! It's rare that I've come across a set of code that is _so_ over-abstracted or dynamic that reading the code doesn't usually shed light on the issue I'm after, and usually it's a "dense" language (Scala, Lisps, etc.) that manages to achieve that.
Last time I was really, seriously confused about the code was when going through a Scala codebase written by a person deep in love with traits. My problem was less of the syntax or "denseness" and more of nonlocality - every conceptually "whole" algorithm was split into 10 or 20 files and 2 class hierarchies, each having their own hierarchy of traits.
It made some sense in the end, but it took me a lot of time to figure that one out - not because it was complicated, but didn't fit in my head. That the original author was uncooperative and didn't want to explain things too much didn't help either.