First class language support for iterating the storage fields of a struct is so useful and nobody is supporting it in their language.
I have to imagine I’m not the only one in this boat.
State of language support
I feel like I read a draft of ‘enumerable classes’ support for C++1x but I can’t find it now so I’m guessing it was a rare happy dream about C++.
Python can presumably do it with dataclasses as of the latest release, but python approaches this problem from the opposite side – python class instances have never strictly speaking had attributes (
__slots__ was never really embraced).
>>> class C: ... def __init__(self): self.a = self.b = 1 ... def x(): return 'y' ... >>> dir(C()) ['__doc__', '__init__', '__module__', 'a', 'b', 'x'] >>> # which are the attributes?
ObjMap<> I guess, and typescript has a slightly better one?
In rust you can do it but the rust macro syntax is impenetrable and insane.
I guess you can do it with
go:generate but once again, good luck. Last time I looked at this (admittedly 18 months ago) the level of integration between go:generate and the rest of the buildsystem was somewhere between alpha & aspirational. Also it was easier to write a parser for go in python than to make do with whatever go was providing from the native library.
I’m assuming java reflection is rock solid and full-featured at a serious performance penalty. I’ve used scala reflection, which I’m assuming is built on java reflection, under protest and I recall it being a beast.
This is such an easy feature to write. The language knows what shape classes are at compile time. Looping polymorphically over class elements is not a huge ask.
The obvious use case for this is at the serialization boundary.
ORMs are everyone’s least-favorite swiss-army knife attachment but they’re also the only tool that opens their particular can of worms. Enumeration of class properties would make ORMs so much easier to write for library authors, and more importantly easier to use for consumer-developers.
Misc thoughts on future language features
Graydon Hoare also wrote an article about this and is an expert on this topic – read his first and then come back and read mine.
I think we’re at peak JIT. I always feel like I have to be smarter than the JIT to get it to work for me. And it’s completely nontransparent. I still don’t know how to audit deopts in nodejs, and it seems like every time someone releases a tool for this the v8 team deprecates it.
I’m looking forward to compiled languages with typesystems and buildsystems that are more featureful, if not necessarily more sophisticated. There are relatively few shops using ocaml & haskell in production I think? But more people are getting on board for code generation, especially when the code gen is maintained within a 3rd-party library.
Array bounds are important. Type-systems should allow the user to express constraints like shorter-than and same-size. I think this opens up new options for static safety as well as malloc optimization.
Enforcing rules across the whole codebase, i.e. sophisticated call graph linting and ordering constraints. ‘No mallocs below this call’ would be interesting, or ‘lint on amount of IO beneath this call’. ‘Must be within a lock’ can be enforced statically instead of at runtime.
Business logic and the type system will blur together. Serious teams view linting as part of the task of delivering safe code at scale from complex codebases. That’s why as JS took over the web, google wrote closure, facebook wrote flow and msft wrote typescript.
(These JS type layers are great tools and I don’t think it’s a coincidence that they came out of a language that someone designed over a weekend at netscape – this isn’t a dis, it’s just an observation: flowers bloom in crap).
Most companies can’t afford to develop their own static checkers for dynamic languages, so I see the next generation of industry languages providing pluggable typesystems so that big codebases can enforce the rules that matter to their authors & operators.