Andrey Breslav on Designing Kotlin, and Why the Language After It Is Written in English

Open on YouTube ↗
Overview

Andrey Breslav led the design of Kotlin at JetBrains from its first whiteboard sketches in 2010 through its 1.0 release, its adoption as an official Android language, and a team of about a hundred people. In this conversation with the host of The Pragmatic Engineer, Breslav explains how the language was designed, which ideas it deliberately borrowed, what it left out, and what made Java interoperability so hard. The second half turns to CodeSpeak, their new project. It is a programming language based on English that uses LLMs, and Breslav frames it as the same fight against boilerplate that motivated Kotlin, moved up a level of abstraction. Throughout, Breslav holds that humans, not models, will remain responsible for deciding what software should do.

35 min read

An unplanned path to a language job

Breslav describes their early career as unplanned. They studied computer science in St. Petersburg, started teaching programming in schools while still at university, and then joined Borland to work on developer tools in the UML space near the end of that era. Borland went under soon after they joined ("I hope it's not because of me"), and Breslav returned to full-time teaching before starting a PhD on domain-specific languages. They had long been curious about typed languages but had never approached them seriously. The PhD, in their words, was "a mess" and was never defended.

While spending a year as a visiting PhD student in Tartu, Estonia, Breslav was contacted by someone who had run Borland's St. Petersburg office and had since moved to JetBrains. Breslav assumed the conversation would be about MPS, JetBrains' meta-programming system for DSLs. Instead, JetBrains wanted to start a new general-purpose programming language. Breslav's first reaction was that nobody needed a new language.

Why JetBrains thought the JVM needed a new language in 2010

The JetBrains engineers laid out the situation for Breslav. The last major Java release was Java 5, from 2004. Java 6 made no language changes and Java 7 made only minor ones. C# had meanwhile gained lambdas, higher-order functions, properties with getters and setters, and much else. Lambdas for Java had been in development for years and would not ship until 2014.

Alternatives existed on the JVM, and JetBrains knew them well because it built tools for them, usually in the languages themselves. The Scala plugin was written in Scala, and Groovy was used widely inside the company. Their assessment was that Groovy was too dynamic for large-scale mainstream production. Breslav explains the trade-off this way: dynamic languages like Python, Ruby, JavaScript, and Groovy are friendlier at the start because the language gets out of your way. They quote the saying that "nothing limits the imagination of a programmer like a compiler." As projects grow, though, large refactorings and confidence that everything fits together become hard, and teams must lean much more on testing. Static languages offer precise refactoring tools and rule out whole classes of errors. For large projects and big teams, the language clearly had to be static. Groovy also had performance problems from layering a dynamic language on a very static runtime.

Breslav calls Scala "a wonderful static language" with "tons and tons of good ideas," and credits Martin Odersky as a great designer. Scala was used at scale at companies like Twitter and LinkedIn. But Breslav says it relied heavily on implicits, and recalls once spending an hour debugging a single line of Scala to work out what it did. The compiler was slow, stability was a concern, and many features were not accessible to many engineers. Scala was also, at the time, very hard to build precise tools for. Breslav puts it alongside C++ as a language where precise tooling was extremely challenging, and notes that Scala 3 is more tooling-friendly.

JetBrains' pitch had two parts. There was a window of opportunity, and JetBrains was the company that could make a language succeed because it had access to developers, their trust, and the ability to build good tools. Breslav was convinced the idea was "not completely dead in the water," though they had no idea whether it could be pulled off. In that first meeting the engineers were already sketching features on a whiteboard, including the syntax for extensions, borrowed from C#, which is still what Kotlin uses.

Breslav did not commit immediately. They finished in Tartu, spent a month in the St. Petersburg office working with a colleague named Max, and then left for a planned internship of about three and a half months at Microsoft Research in Redmond. That was their first exposure to top-level academia. Afterward, they framed the decision as a choice between an academic career they did not feel built for and "the crazy thing." They chose the crazy thing.

How a language begins: whiteboards, lists of pain, and a bad idea

Asked how a language actually starts, Breslav describes months of talking, mostly with Max, plus several internal presentations at JetBrains. Some of the slides survive, English spelling mistakes included. The advantage of JetBrains, Breslav says, was that many people had strong opinions about the problems programmers face and what they like and dislike in other languages. Breslav was 26, did not know how such things were usually done, and says of their colleagues' trust in them, "I'm not sure it was very rational on their part."

The method was to collect Java's pain points, gather proposed fixes, and argue about which problems actually mattered. For a while these were "pieces of the puzzle" in a table. Later they were fitted together, mostly in Breslav's head, which they admit is "not the best way."

Some early ideas were bad. Breslav wanted full multiple inheritance, which they now call "a dumb idea." The hard part, they explain, is not resolving method conflicts but initializing state through constructors. Someone outside JetBrains explained why it was a bad idea, and Breslav remains grateful.

Starting with an IDE plugin instead of a compiler

Coding started around six months in, perhaps a little earlier, and it began unusually: with an IntelliJ IDEA plugin rather than a compiler. An IDE plugin shares much with a compiler front end, and IntelliJ's parsing infrastructure is, in Breslav's view, better than anything else in the world, because as the core of the IDE it must be extremely fast and robust. Max wrote the scaffolding, Breslav plugged in the parser, and the result was an interactive editor for a language that could not yet compile anything. Breslav says this was a very good way to experiment with syntax. Later, an engineer with deep knowledge of the IntelliJ codebase, which was already more than ten years old, factored the parsing infrastructure out so the Kotlin compiler could run on its own.

Breslav then built a full front end while others worked on the back end. They explain the distinction: the front end reads and parses text, handles types, and works out what the program means. The back end generates executable code. For Kotlin that was initially JVM bytecode, and later there were back ends for native targets such as iOS, JavaScript, and Wasm. Early on nobody was full-time, including Breslav, who was still a part-time PhD student before dropping the PhD to focus entirely on Kotlin. Looking back, they call it the decision of someone "young and stupid," and agree with the host's quip that they did it because they thought it was easy. They say they had "an unreasonable amount of hubris."

From "Jet" to "Project Kotlin"

The internal name was Jet. The codebase was full of names like the Jet parser and Jet highlighter. Then the team found the name was trademarked by a company in Novosibirsk that made a compiler, though not a language. The search for a new name was, in Breslav's words, "one of the worst things." Good names are taken, the untaken ones are often unsearchable, and they point to Go, which people call "Golang" because "go" is too common an English word. Rejected candidates included Robusta, a coffee variety.

Another JVM language of the time was named Ceylon, following the logic that Java is an island of coffee and Ceylon an island of tea. A colleague looked out the window and pointed to Kotlin, a large island in the Gulf of Finland near St. Petersburg. It was searchable, unused, and recognizable. Nobody loved it. "Kot" means something bad in German, and Breslav was told it had a negative connotation in Mandarin. So the language was announced as "Project Kotlin" to leave room for renaming. The first public artifact was a set of Confluence wiki pages describing the language, with no compiler, and the name appeared everywhere in them. To make a future rename possible, Breslav created an empty page called "Kotlin" and linked to it wherever the name appeared, so renaming that one page would update every reference. The rename never happened, and Breslav concludes it "turns out to be not a bad name."

Fighting ceremony: what Kotlin fixed about Java

The central complaint about Java in 2010, Breslav recalls, was verbosity. It was a "ceremony language," with public static void main, getters and setters for every property, constructors, and overloads, all of which amounted to boilerplate. The host notes that this is tedious to type, but Breslav argues typing is not the main problem, since tools can generate and fold boilerplate. The real problem is readability. Code is read far more than it is written, and in boilerplate a small deviation in the middle of otherwise standard code becomes invisible. "You become blind to it," and you can debug for days without seeing it. The goal was to make programs about what they do rather than the ceremony of satisfying the compiler.

Lambdas were a major part of this. So were type inference and removing semicolons, which other modern languages had already dropped. Breslav gives the example of duplicated types. In Java of that era you wrote something like a list of strings called strings equals a new ArrayList of strings, naming the type twice. For a map from one type to a list of strings, that repetition grows long and hard to read. The diamond operator, which reduced it somewhat, came later.

Null safety: enforced by types, free at runtime

Null safety was not part of the original plan. It came after an internal presentation that Max invited a colleague named Roman to attend. Roman later became Kotlin's project lead, and his feedback was: "if you want to do something really big for enterprise developers, figure out null safety." The team did, and it took years.

Breslav cites Tony Hoare's description of null references as the "billion-dollar mistake" and says that among runtime errors in Java code, null pointer exceptions would be at the top. A type system is supposed to prevent certain errors, such as class cast exceptions or missing methods, unless the programmer explicitly overrides the checks. In Java, however, anything can be null, and when it is, the program throws an exception and dies.

Kotlin's approach was to enforce nullability in the type system while making it free at runtime. A common alternative is an option type, a box that may or may not contain a value. That box has to be allocated and carried around, which can create many objects for the garbage collector, although runtimes have become better at optimizing some of them away. In Kotlin, nullable and non-null references are the same as Java's references at runtime. The work happens at compile time, with some runtime checks at the boundary with Java code, which Breslav says is much cheaper than allocating objects.

Standing on the shoulders of giants

Kotlin's slogan was "pragmatic language for industry," a deliberate contrast with Scala's reputation as academic. Breslav says the team was not doing research and that "if we don't get to invent anything, it's a good thing, not a bad thing." Familiar ideas are easier for people to grasp, and borrowing lets you study how other communities reacted to a design and what it implied in practice. Breslav has a whole talk on this, called "Shoulders of Giants."

Java was the biggest influence, since Kotlin runs on the JVM. After that came Scala, which contributed primary constructors, data classes, val and var, and declaration-site variance for generics. Breslav calls declaration-site variance a great idea of Martin Odersky's and "a huge pity" that Java reversed course on it at the very end of its design process. Kotlin had to handle the mismatch at the Java boundary. Kotlin also simplified some Scala ideas. Scala traits could hold state as well as method bodies, and that raised hard questions about constructor ordering. Kotlin kept method bodies in interfaces but dropped state, a compromise Breslav considers good, especially since Java ended up in the same place, which made integration easier.

From C# came extensions, lessons about compiler implementation, and one parsing trick a colleague on the C# IDE team told Breslav about. Generic calls inside expressions use angle brackets, but to a parser those are just less-than and greater-than signs, and the grammar is mathematically ambiguous. Java works around this by requiring type arguments after a dot, as in Collections.<T>function(), which Breslav calls awkward. Scala uses square brackets for types, which forces arrays to use round brackets, an unfamiliar choice. C# uses an ad hoc disambiguation hack in the parser, and Kotlin does something very similar. The result is familiar syntax that people read without confusion, with an explicit way to disambiguate when needed.

Groovy, which JetBrains used for build scripts, inspired one of Kotlin's more novel features: type-safe builders. These keep almost all of Groovy's syntactic flexibility for constructing objects but are fully typed, so arguments are checked. That goal is why Kotlin has extension function types and trailing lambdas. The less-known language Gosu inspired smart casts.

Smart casts, and what was left out

Breslav calls smart casts "one of the nicest things a compiler can do to a developer." In many languages, after checking that x is a string, you still have to cast x to a string to use it. Kotlin infers the cast. The implementation is complicated because variables can change and a check can go stale, so smart casts apply only to expressions stable enough to trust. The payoff is removing the instanceof-then-cast pattern that fills codebases.

Pattern matching was designed, drawing on functional languages like Scala and Haskell, but Breslav postponed it on realizing, while writing the parser, that it amounted to "an entire language in size," a parallel universe of syntax. Around the 1.0 review, they concluded that smart casts plus destructuring gave ordinary developers about 80% of the benefit. The remaining value mattered mostly to a vocal group of compiler developers and functional programming enthusiasts. Kotlin's when expression with smart casts covers much of the ground. Breslav says pattern matching might reach the roadmap someday and notes that Java is moving toward it.

The ternary operator is what Breslav calls "the saddest story" in Kotlin's design. Because if is an expression in Kotlin, the ternary seemed redundant, a patch in C-like languages to get a conditional expression. It also used valuable characters, the question mark and colon, which Kotlin wanted for nullable types and type annotations. It turned out people found if expressions verbose and wanted the ternary. Breslav resisted for a while, and by the time they agreed, the operator could not be retrofitted because it clashes with how Kotlin's other operators work. In retrospect they consider the omission a mistake.

Java interoperability: the most expensive feature

The single thing the team spent the most time on, Breslav says, was Java interoperability. Their advice: if someone offers you a job building a system that interoperates transparently with a huge system you don't control, "ask for a lot of money." The requirement went both ways. Kotlin had to use any Java library, and existing Java projects had to be able to convert code to Kotlin piece by piece, often starting with tests, while the surrounding Java code kept calling it transparently.

The first difficulty is that JetBrains does not control the Java compiler, which knows nothing about Kotlin source files. In a mixed project, the Kotlin compiler runs first. It contains a Java front end so it can resolve references into Java sources, and it produces class files. The Java compiler then treats the Kotlin code as binaries, which works because Java supports separate compilation. The IDE needs its own tricks so navigation between Java and Kotlin works. Incremental compilation, already a complex and heuristic-heavy algorithm for Java alone, becomes what Breslav drily calls "fun" when two languages are compiled incrementally together.

Collections illustrate the work of exposing Kotlin features to Java. Java collections are invariant because they are all read-write, so a list of strings cannot be assigned to a list of objects without wildcards. Kotlin wanted read-only collection interfaces that allow this, but such interfaces do not exist at runtime. The compiler has "a layer of trickery" so that Kotlin distinguishes read-only from mutable views of the same Java collection classes, while Java sees ordinary collections. Kotlin also exploits covariance at the boundary. A Kotlin method taking a read-only list of Any is exposed to Java as taking List<? extends Object>, so Java callers can pass a list of strings.

Nullability at the boundary was the biggest problem. Java types carry no nullability information, so the team first treated every Java type as nullable, which is mathematically correct. Internal feedback at JetBrains was "horrible." Code was plagued with null checks everyone knew were unnecessary, and annotations on the Java side were brittle and often missing. The team re-imagined the approach with help from Ross, a type theorist Breslav recalls being at Cornell at the time, who worked out a calculus for types that come from Java. They might be null but should not be treated as nullable. Breslav says that once implemented, "the mathematical beauty is completely gone." What remains is the core idea of splitting a type in two, surrounded by something "messy," "industrial," and "not sound," but it works well. Collections and nullability are handled in a similar way at the boundary.

Six years to 1.0, and a team of fresh graduates

Whenever Breslav was asked when Kotlin would ship, they said "one year from now," which they admit was not a plan. They also believed their first implementation was a throwaway prototype. They think it has since been mostly rewritten, but that took around six years or more. Work started in autumn 2010, and 1.0 shipped in February 2016.

Breslav attributes part of the delay to not knowing how to manage projects, and part to team composition. Having been a teacher, they hired mostly fresh graduates. Some became core contributors who built foundational parts of Kotlin and grew into great engineers, but Breslav thinks they "overdid it" and the balance with experienced engineers was wrong. The team began as four part-time people for about a year, reached around 25 by release, and by the time Breslav left in 2020 was about 100 people, 70 of them engineers.

Bootstrapping, compatibility, and messages from the future

Some language development practices are ordinary. Kotlin had code reviews early on, often done with Breslav sitting next to the other person because they like talking to people, and a public issue tracker that was hard to manage but valuable as a communication channel. Others are unusual. The Kotlin compiler is written in Kotlin, so building it requires an earlier compiler, and the team had to agree on which version. Sometimes a hack was committed to a branch, used once as the bootstrap compiler for a binary-format or syntax change, and then discarded. Breslav doubts Kotlin's full history could be rebuilt from scratch without a lot of manual intervention.

Backward compatibility shaped the release process and helped delay 1.0. Java was known for stability, and Scala's community had suffered from frequent breakage. Breslav also notes, wryly, that Python survived the break from Python 2 to Python 3. Before 1.0 there were 13 milestone builds, which Breslav calls embarrassing, and for major breaking changes the team provided automated migration tools. They believe this was not standard practice then and are happy to have helped popularize it. The year before 1.0 was spent reviewing the whole design and prohibiting, through compiler errors, any code that might conflict with planned future features. At one point there were design meetings almost every day. Some things were prohibited correctly and some incorrectly, but overall it worked.

For changes nobody anticipated, the compiler has a mechanism called "message from the future." Many languages make newer binaries entirely unreadable to older compilers, which forces whole projects to upgrade when a library adds a single method. Instead, a newer Kotlin compiler can mark only the specific elements an older compiler cannot understand, and the rest of the library stays usable. Kotlin also developed a discipline around experimental features: "experimental" in package names, warnings, and compiler flags required to enable them. Breslav is glad other languages, now including Java, do the same.

Their broader lesson is that a compiler, unlike a SaaS system, leaves behind source code and binaries that pin down its history in the wild. They say that with enough users, "you hit every freaking case." They realized this before 1.0, with only a few thousand users: anything possible, someone will do.

How Android happened

Android was not in the original plan. In 2010 the target was server-side Java developers, the biggest source of IntelliJ revenue through Spring users, plus desktop developers, since JetBrains had "probably the last desktop application written in Java," or at least in Swing. A few years in, a user asked whether Kotlin worked on Android. Breslav assumed it should and told them to try. The report came back that the Android toolchain, not Kotlin's, was crashing with a core dump in a tool written in C.

The cause, Breslav explains, was that the Android team had actually implemented the JVM specification, while the HotSpot VM, which Breslav suspects predates the spec, was lenient about things like disallowed class-file flags. The Kotlin team had only tested on HotSpot. From then on they used the Android toolchain as a validation environment to clean up their bytecode, though it also faithfully enforced some legacy details mainstream Java ignored. Breslav came to see Android as a growing platform with many new applications, where adopting a new language would be easier, and made sure Kotlin worked well there. All of this happened against the background of Oracle's lawsuit against Google over Java after acquiring Sun, which took years to settle.

Breslav gives several reasons Kotlin caught on with Android developers. Android apps run on billions of devices whose virtual machines are not always updated, so Android developers were stuck with old Java even after Java 8 arrived in 2014. Workarounds like Retrolambda helped, but frustration with Java was much higher in the Android community than on the server. Swift on iOS showed a large ecosystem moving from a dated language to a much nicer one. And Google had moved Android developer tooling from Eclipse to the IntelliJ platform after IntelliJ was open-sourced, so Kotlin's plugin worked in Android Studio "reasonably smooth[ly]."

Kotlin's team tried to get Google's attention without success, even after 1.0 in 2016. Growth was organic. Breslav had privately set 100,000 users as the threshold for success, and by 2016 usage was in the tens of thousands and on track. Then Google reached out about announcing official Kotlin support at Google I/O 2017, about three months away. Breslav calls the Google team's effort "heroic" and says they came very close to missing the deadline. JetBrains had to improve Android Studio integration and set up processes. The legal side led to the creation of the Kotlin Foundation and its decision-making protocols. As a guarantee from JetBrains, Google held the Kotlin trademark for a year until the foundation was established and the trademark was transferred to it. Usage probably reached millions that year. Breslav had long believed the easiest way for a language to succeed is to be part of a platform, as C was for Unix, C# for Windows, and JavaScript for the web. Kotlin had no platform, "but yeah, the platform came along somehow."

CodeSpeak: removing boilerplate at the next level

Breslav left Kotlin in 2020 and later left JetBrains. They are working on another language, CodeSpeak, which they present as a continuation of Kotlin's goal of making programs more to the point, now possible at a higher level because of AI. LLMs find obvious the same things humans find obvious, which narrows the gap between what a machine and a human can understand. That, Breslav argues, means "we might not need to write dumb code anymore."

They place this in the history of programming as a rise in abstraction: machine code, assembly, C, managed languages like Java that let teams grow and made it possible to build working software without being an exceptionally skilled programmer, and then languages like Kotlin. When one engineer asks another to write some code, they explain what the program must do rather than spelling out every line. CodeSpeak aims to shrink what a programmer must tell the computer in the same way. From their "current anecdotal experience," Breslav says much code can be shrunk by about 10x, making projects easier to read and navigate and leaving programmers to express only "what only you know about what needs to happen."

Breslav describes CodeSpeak as "a programming language that's based on English." It is not an entirely formal language, but it is meant for engineers and uses LLMs heavily. Their framing is that the ultimate language of today is a normal programming language that uses an LLM as a library. If npm was a huge repository of JavaScript packages, an LLM is "an even better npm" that has seen all the code in the world. The catch is that the only way to query it is natural language, and there is no known way to make that fully formal. So such a language must be at least partly informal. How formal CodeSpeak can become is, in Breslav's words, "still in the air." The goal is not heavy restriction but using the model's power while ruling out stupid mistakes.

Should there be new languages designed for LLMs?

The host asks whether new languages should be designed for LLMs themselves, a question also put to Chris Lattner on the show. Breslav thinks the idea is probably misguided. First, LLMs need large training sets, which a new language lacks. They say today any LLM writes Python better than Rust or even Kotlin, and models that write Java very well still write Kotlin less well because it is younger and less represented, though they believe later models have added more Kotlin to their RL data and are improving. Second, LLMs are trained on human language, their programming knowledge is part of that, and their power comes from exposure to existing code, so Breslav is not sure how promising a new language would be. They mention one interesting research direction: extracting an optimal prompting language from a model's internal representations. It might not be intelligible to humans, and they note experiments showing unintelligible prompts can produce the same results as normal ones while being shorter. Breslav doesn't know if this would help much.

In CodeSpeak's own work, the team takes existing code and searches for the shortest English descriptions that can generate equivalent implementations, meaning ones that behave the same, not identical character by character. The code also evolves through its commit history, so the descriptions must represent changes too, and a small change in code should produce an even smaller change in the spec. Breslav says they are in this sense "discovering" parts of CodeSpeak rather than designing them. In AI work, they add, everything becomes a machine learning problem: "if you don't know how to collect a data set, don't even start."

The backwards workflow of coding agents

Breslav still writes code, sometimes by typing, more often with Cursor's tab completion, which they consider a real step up from traditional IDEs, and often by prompting. They see the current moment as the early days of a new era, noting that only in the past year did it become clear coding agents are good. They use agents daily but see an inherent problem in the model. A developer communicates intent to the agent in human language in a one-on-one chat, the agent produces code, and the code is what gets committed and what teammates see. The chat history is lost. "I'm talking to a machine in a human language, but the way I communicate with my team is the machine language. That's kind of backwards." CodeSpeak aims to lift everything to the human-language level.

Breslav thinks many teams have not realized how hard it is to review all this generated code. When people suggest simply not reviewing it, Breslav replies that you can do that "for a couple of days and then it just collapses." Testing will become a major theme. Depending on the domain, good tests may reduce the need to review code, and CodeSpeak is investing heavily in automated testing that checks the right things and covers all the code. The open problem is presenting generated tests to users in a way that actually lets them confirm the right thing was built, since some tests are long and tedious to read.

In the near term, Breslav expects "obvious" improvements to agent scaffolding. Agents are only beginning to use language servers and the other tooling that has long existed for code. IDE-integrated agents, such as Cursor or JetBrains' Junie, can use indexed code navigation, while a terminal agent like Claude Code might fall back on grep, succeeding just as often but taking longer and burning more tokens. Breslav expects these capabilities to reach most agents this year.

Humans stay in charge, so engineering stays

For the longer term, Breslav says the one thing they know is that models will get much smarter and humans will not: people will be "as smart or as dumb as they are today." What we do will therefore be constrained by human limits, which is why CodeSpeak is a tool for humans rather than for models. To those who say sufficiently smart models will review and test their own code, Breslav asks who then makes the decisions. If humans have no say, that is the technological singularity, and "nobody should build any projects for that future. In that future, we're gone." Their working assumption is that the singularity does not happen and humans remain in charge.

If humans are in charge, their job is to communicate intent, and serious software is always complex. Breslav distinguishes accidental complexity, which comes from how systems are implemented and may shrink, from essential complexity, the inherent intricacy of how we want systems to behave. Managing essential complexity requires an engineering mindset, whatever it ends up being called. Breslav expects teams of engineers to keep building systems, possibly smaller teams delivering far more, and says CodeSpeak is built for that work.

Developer tools in the "wild west"

On the state of tooling, Breslav repeats that this will be the year developer tools become available to agents. They also see value in dedicated environments over terminals. Terminal tools, especially Claude Code, are "a complete breakthrough" in what a terminal can do, but specialized environments can offer a better experience, and Breslav expects more IDE integration and new environments built for agents from the ground up. With more emphasis on review, they expect new review tools that improve on current practice. They do not expect testing breakthroughs this year "because it's hard. I'm doing it right now," though some advances may arrive. The broader lesson of recent years, in Breslav's view, is that obviously needed features, like connecting agents to developer tools, take a long time not because anyone is lazy but because you must build the basics before the advanced things.

Advice for anxious engineers and new graduates

The host describes engineers shaken by how quickly coding agents improved over the winter break. Breslav says advice is hard to give, but offers a few thoughts. Much of the hype reaches management and leads to suboptimal decisions that will be reversed. Not hiring junior developers, for instance, is "dumb" and won't last, though it is hard to say how long it will go on. It is worth investing time in learning AI tools. Breslav acknowledges widespread skepticism but says using these tools well is a real skill. It is not yet formalizable, and some people get much better results than others without being able to explain why, but it can be learned. They caution against believing everything claimed on Twitter. And engineers will still build complex systems in the future.

For new graduates, Breslav suggests following their inclinations. If you can be highly productive at producing robust, evolvable code, get good at that. If you like harder problems, go into "the most hardcore things you can." That expertise will be rare and marketable, and even if the specific area disappears, you will have become much smarter by learning it. Young people have a lot of mental capacity for going deep, and drilling down on many things builds expertise across wide fields.

In a closing rapid-fire round, Breslav names AirPods, which fit under their ear muffs, and the ear muffs themselves as favorite tools, and recommends Zen and the Art of Motorcycle Maintenance, both for its thinking about technology and real systems and as a good novel. The host's closing reflection returns to Breslav's point about agents: developers express their intent in English, commit only code, and lose the intent. Whether or not CodeSpeak is the answer, the host concludes, something is missing, a layer that preserves intent, and someone will have to figure out how to keep it.