Miraikan is one of our favorites, been there like 3-4 times with my son. The current exhibit that turns quantum logic gates into a DJ game is really innovative but they only give you like 5 mins which is barely enough time to figure out WTF is even going on
For all the disparagement of “fact regurgitation” as pedagogical practice, it’s not like there’s some proven better alternative. Higher-order reasoning doesn’t happen without a thorough catalogue of domain knowledge readily accessible in your context window.
Your last statement misses the mark—of course the brain is the root of human intelligence. The error is in assuming that consciousness is the primary learning modality. Or, as you put it, “arguing semantics”.
From my own personal experience, this realization came after finally learning a difficult foreign language after years and years of “wanting” to learn it but making little progress. The shift came when I approached it like learning martial arts rather than mathematics. Nobody would be foolish enough to suggest that you could “think” your way to a black belt, but we mistakenly assume that skills which involve only the organs in our head (eyes, ears, mouth) can be reduced to a thought process.
Your analogy to PHP developers not reading assembly got me thinking.
Early resistance to high-level (i.e. compiled) languages came from assembly programmers who couldn’t imagine that the compiler could generate code that was just as performant as their hand-crafted product. For a while they were right, but improved compiler design and the relentless performance increases in hardware made it so that even an extra 10-20% boost you might get from perfectly hand-crafted assembly was almost never worth the developer time.
There is an obvious parallel here, but it’s not quite the same. The high-level language is effectively a formal spec for the abstract machine which is faithfully translated by the (hopefully bug-free) compiler. Natural language is not a formal spec for anything, and LLM-based agents are not formally verifiable software. So the tradeoffs involved are not only about developer time vs. performance, but also correctness.
For a great many software projects no formal spec exists. The code is the spec, and it gets modified constantly based on user feedback and other requirements that often appear out of nowhere. For many projects, maybe ~80% of the thinking about how the software should work happens after some version of the software exists and is being used to do meaningful work.
Put another way, if you don't know what correct is before you start working then no tradeoff exists.
> Put another way, if you don't know what correct is before you start working then no tradeoff exists.
This goes out the window the first time you get real users, though. Hyrum's Law bites people all the time.
"What sorts of things can you build if you don't have long-term sneaky contracts and dependencies" is a really interesting question and has a HUGE pool of answers that used to be not worth the effort. But it's largely a different pool of software than the ones people get paid for today.
> For many projects, maybe ~80% of the thinking about how the software should work happens after some version of the software exists and is being used to do meaningful work.
Some version of the software exists and now that's your spec. If you don't have a formal copy of that and rigorous testing against that spec, you're gonna get mutations that change unintended things, not just improvements.
Users are generally ok with - or at least understanding of - intentional changes, but now people are talking about no-code-reading workflows, where you just let the agents rewrite stuff on the fly to build new things until all the tests pass again. The in-code tests and the expectations/assumptions about the product that your users have are likely wildly different - they always have been, and there's nothing inherent about LLM-generated code or about code test coverage percentages that change this.
> So the tradeoffs involved are not only about developer time vs. performance, but also correctness.
The "now that producing plausible code is free, verification becomes the bottleneck" people are technically right, of course, but I think they're missing the context that very few projects cared much about correctness to begin with.
The biggest headache I can see right now is just the humans keeping track of all the new code, because it arrives faster than they can digest it.
But I guess "let go of the need to even look at the code" "solves" that problem, for many projects... Strange times!
For example -- someone correct me if I'm wrong -- OpenClaw was itself almost entirely written by AI, and the developer bragged about not reading the code. If anything, in this niche, that actually helped the project's success, rather than harming it.
(In the case of Windows 11 recently.. not so much ;)
> The "now that producing plausible code is free, verification becomes the bottleneck" people are technically right, of course, but I think they're missing the context that very few projects cared much about correctness to begin with.
It's certainly hard to find, in consumer-tech, an example of a product that was displaced in the market by a slower moving competitor due to buggy releases. Infamously, "move fast and break things" has been the rule of the land.
In SaaS and B2B deterministic results becomes much more important. There's still bugs, of course, but showstopper bugs are major business risks. And combinatorial state+logic still makes testing a huge tarpit.
The world didn't spend the last century turning customer service agents and business-process-workers into script-following human-robots for no reason, and big parts of it won't want to reintroduce high levels of randmoness... (That's not even necessarily good for any particular consumer - imagine an insurance company with a "claims agent" that got sweet talked into spending hundreds of millions more on things that were legitimate benefits for their customers, but that management wanted to limit whenever possible on technicalities.)
OK but, I've definitely read the assembly listings my C compiler produced when it wasn't working like I hoped. Even if that's not all that frequent it's something I expect I have to do from time to time and is definitely part of "programming".
It's also important to remember that vibe coders throw away the natural language spec each time they close the context window.
Vibe coding is closer to compiling your code, throwing the source away and asking a friend to give you source that is pretty close to the one you wrote.
Imagine if high level coding worked like: write a first draft, and get assembly. All subsequent high level code is written in a repl and expresses changes to the assembly, or queries the state of the assembly, and is then discarded. only the assembly is checked into version control.
Or the opposite, all applications are just text files with prompts in them and the assembly lives as ravioli in many temp files. It only builds the code that is used. You can extend the prompt while using the application.
People choose to hold non-yield-bearing assets when they believe the returns offered by current investment opportunities are not sufficient to justify the risks.
It is the miracle of modern capital markets that enables almost anyone to quickly and easily invest their savings in productive assets, but of course capital markets aren’t perfect. The availability of “none of the above” options (like gold) that remove savings from the pool of active investment capital is the essential feedback loop that balances risk and return.
I started teaching undergraduate computer science courses a year ago, after ~20 years in various other careers. My campus has relatively low enrollment, but has seen a massive increase in CS majors recently (for reasons I won’t go into) so they are hiring a lot without much instructional support in place. I was basically given zero preparation other than a zip file with the current instructor’s tests and homeworks (which are on paper, btw).
I thought that I would be using LLMs for coding, but it turns out that they have been much more useful as a sounding board for conceptual framing that I’d like to use while teaching. I have strong opinions about good software design, some of them unconventional, and these conversations have been incredibly helpful for turning my vague notions into precise, repeatable explanations for difficult abstractions.
I found Geoffrey Hinton's hypothesis of LLMs interesting in this regard. They have to compress the world knowledge into a few billion parameters, much denser than the human brain, so they have to be very good at analogies, in order to obtain that compression.
I feel this has causality reversed. I'd say they are good at analogies because they have to compress well, which they do by encoding relationships in stupidly high-dimensional space.
Analogies then could sort of fall out naturally out of this. It might really still be just the simple (yet profound) "King - Man + Woman = Queen" style vector math.
Another principle that builds on the other two, and is specifically applicable to Java:
- To the greatest extent possible, base interfaces should define a single abstract method which allows them to be functional and instantiated through lambdas for easy mocking.
- Terminal interfaces (which are intended to be implemented directly by a concrete class) should always provide an abstract decorator implementation that wraps the concrete class for (1) interface isolation that can’t be bypassed by runtime reflection, and (2) decoration as an automatic extension point.
I’m required to teach DSA in Java, so I lay down a couple rules early in the course that prohibit 95% of the nonsense garbage that unconstrained OOP allows. Granted, neither of these rules is original or novel, but they are rarely acknowledged in educational settings:
1. All public methods must implement an interface, no exceptions.
2. The super implementation must be called if overriding a non-abstract method.
The end result of strict adherence to these rules is basically that every feature will look like a GoF design pattern. True creative freedom emerges through constraints, because the only allowable designs are the ones that are proven to be maximally extensible and composable.
but sometimes that is not worth it... IOW, it optimizes only to a couple of variables.
it's important not to lose sight of the ultimate goal: to get the machine to do what we want with the least amount of total human attention throughout the entire lifetime of the software.
it's a typical trap for good/idealist programmers to spend too much time on code that should already have been re-written, or not even written to begin with (because faster iteration can help refining the model/understanding, which in turn may lead to abandoning bad paths whose implementation should never have been refined to a better quality implementation).
i think it's a more important principle to always mark kludges and punts in the code and the design.
IOW sloppiness is allowed, but only when it's explicitly marked formally in code, and when not possible, then informally in comments and docs.
but then this entire discussion highly depends on the problem domain (e.g. on the cost of the various failures, etc).
I don’t completely disagree, just like 90%. Junior developers typically aren’t taught the design patterns in the first place so they dig deeper holes rather than immediately recognizing that they need to refactor, pull out an interface and decorate/delegate/etc.
I’m also going to point out that this is a data structures course that I’m teaching, so extensibility and composability are paramount concerns because the interfaces we implement are at the heart of almost everything else in an application.
I can’t stop thinking about this exact notion. The main reason we don’t always use stuff like TLA+ to spec out our software is because it’s tedious AF for anything smaller than, like, mission-critical enterprise-grade systems and we can generally trust the humans to get the details right eventually through carrot-and-stick incentive systems. LLM agents have none of the attentional and motivational constraints of humans so there’s no reason not to do things the right way.
That last line is exactly what I was thinking. Find an expressive language and then progressively formalize your workflows in DSLs that enforce correctness by design, not through layers and layers of natural language “skills” and deadweight agentic watchdogs.
reply