From a more designwise perspective, I consider [] to be the index
operator of the "data level" while -> is on the "meta level". I.e. if one implements some kind of intelligent mapping class, it's natural to use [] to index the elements in the "mapping" while -> is used to get the extra functionality in the object itself. Dir- and joinnodes follows this design principle.
Unfortunately it's a bit muddled by the fact that [] and -> are equivalent on real mappings. It'd be cleaner if -> was kept undefined so that it could be used for meta functions on mappings. Then we wouldn't have to have a global set_weak_flag function, for instance.
Still, this muddling doesn't make the principle less useful in cases where [] and -> both can do different meaningful things.