Trading off easy heterogenous lists buys you a better type checker, more static knowledge, faster programs and so on. It also has the advantage that mapping data into the system can be done safely. The price is that self-describing data (JSON, Transit, Msgpack, ...) is more unwieldy to work with - but a little combinator library, scrap-your-boilerplate-generics, or a reflective code generator goes a long way to solve that problem:
- OCaml: Yojson.Basic.Util - Haskell: Generics, Rank2 polymorphism - Go: JSON unmarshalling
are all examples of how to handle that problem.