I have a strong belief (mostly borne out by my years as Java dev) that the larger the possibility space of a language (and its ecosystem) the more room there is for inappropriate use and unclear code. Add time and an assortment of rolling devs of mixed ability level, and crap mounts faster then a "simpler" language.
Let me be clear: Do I think it is possible to write good, clear, performant code in Java? Of course - Java can be used to write great software. The problem is that in Java there exist an extraordinary set of variations of a sufficient implementation, many of which are package protected abstract static horrors shows. And that will manifest over time if you add different individual developers. Else the project must engage in bureaucracy and control, where you have meetings over style conventions or hardline architects who come to constrain the joy of programming in the devs.
Its much better when the language itself constrains you, then everyone can just move on. I feel Go, though certainly not perfect, meets this niche.
Also - and this is very subjective - I find developers who have similarly low view of software development and high view of simple languages, to be very good team mates. We can laugh at the realities and move on pragmatically.
I see. I tend to agree in principle. I felt this with julia for example and it put me off a bit even though I was very keen on it at first
In the specific case of java however I don't think this applies much; the vast majority of improvements are aimed at under the hood optimisations rather than syntax. And I feel that any changes in syntax have been quite incremental, intuitive, and reasonable.
AND they stay around as preview features forever, so this may inflate the perception of features entering the language, when in fact it's the same one feature being mildly iterated on.
E.g. the main syntactical change in this version seems to be the use of primitives in switch statements, which was already discussed for a while, and is itself a meaningful change brought about by the introduction of switch expressions.
Golang tried to be simple, but reality hit and they started adding features (generics, and now generics on method, iterators, fixed loop variable scoping). Yet when you program in it, you can feel so much resistance because it took a naive approach to simplicity.
Honesty does not just mean reporting facts. It also requires having an understanding of the scope of your knowledge and then endeavouring to communicate that scope effectively.
Like many "cloud native ideas" there is a core 20% to the idea of feature flags that is useful to 80% of teams, and then a remaining 80% of periphery concerns that are relevant to 20% of teams (and I'm erring generously on those figures).
Specifically, the idea of putting toggles on risky functionality is a good idea that is useful broadly. Being able to dynamically toggle feature flags without a restart, or apply some features to some segment of users is unlikely to be useful and entails a lot of complexity and potential footguns.
My approach to feature flags is even simpler than what is suggested here: feature flags are just a section in your config. Done. Even if you are confident that you need more advanced capabilities, you should not "advance" to that level until you have demonstrable proof that your team can manage simple config values for it.
So I love good old fashioned desktop-oriented websites, and the most complex thing I do on my phone is Google Maps... but I also recognize this is not true of the general population.
Almost no one else except the PC gamers I know really like using desktop (or laptop) computers. Most people love being able to sit on the couch and use apps on their phone. Its not like massive portions of the population were loving their desktops until smartphones arrived and they transitioned, no - smartphones are what helped the internet revolution really inseminate into the general population.
One will lose the opportunity to develop domain understanding if they do not get into the weeds of thinking through the problem.
I use Claude plan mode to do relatively small changes and even then I find that if I actually try and think through the problem and solve it myself that I find good metaphors that will aid future work, and I will discover tangential issues which are then important to look at.
I wonder if we need a list of things to tell AI to stay sharp, like this one. Sometimes I tell the model existing design is stupid and then it explains reasoning to me.
Mindset is important. If you care about the craft of programming then you can easily get into a mindset that software must be "perfect", which is almost always impossible to achieve, and so you will become continually dissatisfied. I got into this mindset when I was a junior dev, and it only served to fuel frustration for me and others.
I try to take the mindset of "continuous crap reduction". I let go of the things that are out of my control, and seek to reduce the biggest problems that are in my control. Then I can get a "win" every day, and I don't try and fight the stuff out of my control which is only a little crap. I have to try and be principled without being opinionated.
I think the main difference between me and Claude's work is that it doesn't find a needlessly complex solution offensive, and is happy to contribute that complex solution and to then move on and build further on it. After all, it works.
The problem comes later when the code no longer reveals the domain and the processes of the business, and where changes start affecting other expected business behaviors (at least that is what I think would happen, I find the code too distasteful to let it get that far).
Yes, that's partly a sense of qualified taste I've built through experience, but I think it also comes from trying to actually understand user needs better. E.g. Our finance department says they wants a daily report of invoices, but what do they ACTUALLY NEED? Maybe the problem to solve is to allow more flexibility with billing dates, or increase billing strike attempts, etc. That stuff sometimes doesn't come out until you really ask because of all sorts of organizational and social beliefs, fears, etc. Practicing that and recognizing the signs means you can do that rethinking earlier on in the process, before dev starts.
For me, domain discoveries and elegant solutions arise out of periods of deep befuddlement, and are often a saving grace that can avoid lots of code.
I'm lucky I guess that I've had enough time in this career to experience these moments, and enough experience to know which code I should write and which code really is rote and can be generated (most of the time). Hopefully it keeps the loss of enlightenment to a minimum.
reply