> generic information manipulation code... requires the capability to generically access/modify/add properties by name/key, ... etc
Java reflection does much of this. Though you can't add properties.
He's against types, and only values them for performance. Yet, the relational algebra that he admires uses types (the definitions of tables - "schema"). Although they're flexible types, in that you can change schema definitions (schema are themselves tables). And you can invent new schema willy nilly (e.g. result of a join). They are types in that each row (or instance) in a table has a value for each column in the table.
The relational algebra is one of the most successful and enduring innovations in computer science - and it also has a solid mathematical basis. It's dynamic types may be a good guide to the value of types other than for performance.
His argument against using classes/objects is that objects (in mainstream PLs) can't be accessed in a dictionary-like fashion.
But switching to dictionaries wholesale for this reason seems to throw out the baby with the bathwater. The loss of abstraction is real, and could be worked around trivially by making every object respond to a dictionary protocol. This would give you the best of both worlds.
The whole point of OO is that you don't want code reaching into the internal member data of the object. The real reason that algorithmic code reuse is so difficult in C++ and Java is that they lack usable first-order function literals.
Not to mention that lack of structural typing and Mixins make it even harder to actually have reuse. Dynamic languages like Python and Ruby solve this beautifully, and so do Go and Scala on the more static type side.
No all those languages suffer (except JS) from the fact they don't give you uniform access. Consider the different forms of access for dict types, array types, object types in said languages.
Being able to deal with data generically in a first class manner is very, very useful. You can only get this in all the languages you've mentioned (including JS) w/ more or less custom code writing.
order.getLineItem(2).getQuantity();
(get-in order [:lineitems 2 :quantity] 1)
The first is simple enough, but it's essentially a DSL. No code that doesn't know about that API can work with those objects. If I want to guard against null objects I have to re-do that sort of work over and over again.
Contrast with the latter, where the get-in function just treats the subject as a nested associative structure. It can handle the null checking, and it doesn't care what my keys look like.
I have to admit, the first line looks like better code in my eyes. The only "advantage" of the second one is that it "handles" null checking. Which really means that I still need to handle what happens when order is null, versus, the non existence of line items, or the non existence of quantity.
The only real advantage I see from the second line version is that I can write that code and run a partially completed program, that for example doesn't have a notion of orders at all -- and the program can still run. But I guess this just boils down to preferences.
When I briefly used Clojure, I was very impressed with clojure.set. (Probably the "relational algebra" Hickey mentioned in the interview, with operators like project, rename, join, etc. Stuff that anyone who knows SQL will be familiar with. A good example of what such abstractness buys you.)