I have quite some background in OOP and switched to functional programming a few years ago, now working a lot with Clojure, where you actually have the "code is data" paradigm. And from my experience, it's way easier to model data with three simple structures; vectors (= arrays), maps and sets. There are other things, too, but most of the time these three types are sufficient. It requires some discipline in the beginning but it can give you a lot of benefits.
Just to reinforce this, the same is essentially true of all the languages I have touched. If the language has associative arrays ( e.g. maps ) all the better. But associativity is not difficult even in assembly language - so long as O(n) lookups are okay. Adding basic better-than-linear searches ( O(log(n)) ) is also not horribly complex - the 'C' library bsearch() is a conceptual template here.
Having large arrays of const data to drive 'C' programs can - emphasis can - lead to much more manageable 'C' code.
You are going to be lectured at length by the (OOP) static types crowd. And they have a point about using explicit types, when it's easy.
That said, I wish the "strong types" crowd would take a look at all of the temporal coupling that their OOP designs are causing, with their update-at-will practices. Now that we have working garbage collector software plus adequate hardware support, why not make use of that?
Some are just lost if autocomplete in the IDE doesn't enter stuff for them, and the more verbosely the IDE spews, the better, cuz it looks like "work".
That may be fixable at compile time, I believe. In the worst case, you could write a patch. (Dijkstra would prefer a half-open indexing scheme anyway.)
And be incompatible with the universe of Lua programs.
The problem was that Lua reified 1-indexing into the language when they optimized to make arrays faster and then created length operators. At that point, 1-indexing got baked into the language.