Bottom values aren't a “concession to practicality”: they're a defect in lazy languages. In ML, when types are viewed as collections of values, the empty type is really empty, sum types are really sums, tuple types are really tensor products and distribute over sums. But, of course, strict languages have dual defects, function spaces aren't as nice unless the language is total (which a general-purpose language can't be), and `let x = e in t` isn't equivalent to the result of substituting `x` with `e` in `t`.
To get both the good parts of strictness and the good parts of laziness, you need call-by-push-value: http://www.cs.bham.ac.uk/~pbl/cbpv.html. But, if that's overkill, it's easier to get the benefits of laziness in a primarily strict language, than the other way around.