It works and is IMO quite okay because NA is not the same as NaN (not a number). NA _does_ actually stand for a number, it's just that we don't know it.
Which is an interesting detail in R that should be mentioned anyway, the difference between NA and NaN. Anyone used to languages which just NaN may confuse NA for that non-value.
Except - 1^NaN also is 1... now that IMO is wrong. But you can try the same in your browser's JS console and you will get 1 as a result too, so R is not the only one.
There are several NA values in R - NA_integer_, NA_real_, NA_complex_ and NA_character_, and the results will be different if you use some of them. NA_character_ and NA_complex_ will produce errors (different ones).
Interesting. I must admit I've never used substitute.
I tried dims but: Error in dims(iris) : could not find function "dims"
I do find the occasional oddity. I've noticed more very useful messages/warnings (particularly in common tidyverse functions) recently, so I think they help.
To be fair, these quirks are generally very uncommon in day to day use.