I don't know the ant specifics, but I'd surmise that one starts off thinking of a simple declarative format (we've got some targets, that depend on other targets, which is just a simple tree, and perhaps we can write various analysis tools later). Then of course as time goes on, it gets more general purpose language features (symbol bindings, conditionals, etc), and adopts an ever more procedural feel (especially in the case of a build system, which essentially all about mutating filesystem state). Since these features weren't designed from the start, you end up with rifts, such as between ant "attributes" and "properties", which don't really tax the ant gurus, just the casual users and newcomers.
Seems that it would be easier to write a build system as an embedded DSL in a general purpose language to begin with, and when further analysis tools wanted to be written, make the necessary changes (meanwhile old build scripts run just fine using the old library).
But then again, it's much easier to criticize with hindsight than to design a system that becomes popular.
>But then again, it's much easier to criticize with hindsight than to design a system that becomes popular.
Indeed - ant came about when XML was popular for far more things then it should have been used for, and java wouldn't make a very good declarative build language (which is what ant was targeting).