I had the motivation for creating a new programming language long before large language models emerged. The fundamental ideas behind the grammar and the design principles actually come from my own work.

I also started by implementing a formal grammar in C++. This was followed by a simple structure for the program code and later an LLVM backend to generate executable code. This allowed me to test the basic feasibility of my ideas: for example, a grammar without reserved keywords, variables for a few simple data types, and output to the console. I did all of this myself.

However, I found the LLVM documentation too difficult to understand. So I bought a book. It helped, but it was based on an older version of LLVM, while I wanted to use the current version. That attempt failed badly. It frustrated me, and I realised that creating a reasonable programming language and a compiler is by far not as easy as some people claim.

I discovered that there are also C bindings for LLVM. These are considered to be more stable and easier to understand. I looked into alternatives and decided to switch to Rust and another library for the formal grammar. At the same time, AI models had become popular among software developers. I didn't want to be left behind, and I wanted to give it a try as well.

I used an AI agent to translate my own C++ code, including the grammar, to Rust and pest. I was impressed by how well it worked.

At this point, I already had a relatively good understanding of how to develop a compiler in general, and I had created my first handwritten hello-world compiler. At the same time, I realised that learning itself was much easier with AI. I had already learned a lot through keyword searches on the internet and from a real book on paper. But AI answers specific questions. That was a giant leap forward.

In other words: I talked to various AI models about my ideas and worked with them to create an architecture document and also a user-facing document. I used several AI models to review each other's results. Of course, I was thinking along the way and orchestrating the process. In doing so, "we all" identified many errors and improved "each other". This allowed me to develop a design that I only rarely had to fundamentally change later.

I then also used AI agents to implement the compiler. That's when I realised how much guidance they need. Of course, they cannot read my mind, and they tend to do exactly what I ask them to do, but with as little effort as possible. This left many unhandled error cases behind. Some of that AI work was quite sloppy. I also realised that the agents sometimes made design decisions without asking me, decisions I certainly would not have made that way.

This resulted in very rapid development with very poor code quality. I then established many rules in my agents.md to guide the AI towards producing high-quality code. Basically, I started the entire implementation again from scratch and focused on an interpreter to start with.

Once again, it was an intense interplay with the AI. Thanks to these rules, the AI would keep stopping whenever it recognized that there were several possible approaches. The decisions were mine.

Therefore, I can say that the design principles and the detailed design decisions are mine. I have spent a great deal of time guiding the AI, asking whether it had tested this or that, why it had implemented something in a particular way, and so on. The same applies to the documentation. Whenever I added a new feature or changed an existing one, I asked the AI to document it.

In the meantime, I am impressed by how well AI can program in Lale, even though it was not directly trained on Lale. Of course, it couldn't have been, because Lale did not exist before. I guess this is also an indication of how easy Lale is to learn, and of what an AI can achieve based on good documentation and good examples.

In a nutshell, I have used AI to learn how to develop a compiler in general, to ask how different programming languages solve the same problem, and of course to implement the code. Sometimes I have adopted an existing solution from a mainstream programming language, while at other times I have introduced my own concepts and solutions.

It was a very iterative process — and far from simply asking an AI, with a few ideas, to write a complete compiler.