When we as software developers instruct computers to do something, we use a programming language like Rust, TypeScript or CSS. Theoretically, the precision of formal languages allows us to predict exactly what behavior we'll get. But this comes at the expense of needing to explicitly specify every detail we want.
On the other hand, if we are instructing a fellow human being, we usually leave out many details because they will be obvious or implied based on our shared context. And if our collaborator comes back with something different than what we had in mind, we may clarify any detail. That's a fundamental and fantastic property of conversation!
SpecLang is an attempt at lifting the developer experience to a higher level of abstraction, closer to how we conceptually think about our programs: where programming is much more similar to how you'd instruct a human being. You are still the one deciding what your app should do and how it should do it, but SpecLang---powered by a large language model---turns those instructions into executable code. Ultimately, this allows you to create as easily as you can think.
In SpecLang, your specification, or "the spec", is the main source of truth for your program, and this is what you will be maintaining. It's a structured Markdown-like document of what you want of your program, penned out in only the necessary level of detail. The executable code that SpecLang creates for you is secondary, and you will rarely have to inspect it yourself. The level of detail may vary throughout the spec, from offhand remarks that translate into a dozen boilerplate lines of code, to mapping out the exact steps of a handshake protocol. Here is an excerpt of a spec for a client webpage that polls a server for progress on a task:
- Continuously poll the server on progress on the route `/progress?taskId=$id`. - The server responds with a JSON object with the following fields: - progress: number - output: string - errors: string - However, if the object is empty, then $progress = 0 and $output and $errors are empty strings. - Display the progress as a blue progress bar. - If $errors is not empty, then - Display $errors in a big red box labelled "Task errors:". - Display $output in a big gray box labelled "Task output:". - When the progress reaches 100%, redirect to the url `/success?taskId=$id`.
Notice how this is detailed and structured, laying out all the main pieces of the behaviour in much the same way we naturally think about them---while most technical details about how exactly to carry this out is glossed over.
We believe that using natural language for programming is a paradigm of the future: it not only has the opportunity to massively increase expressivity and let the developer stay on an intuitive level of abstraction for longer, but may also increase accessibility (e.g. voice input, non-english), and mobility (e.g. code on your phone). The main scepticism is that we may lose precision or predictability, and ultimately control of the software.
SpecLang is an end-to-end tool chain that looks to unlock the benefits, without sacrificing precision and control. It does that in the following ways:
Iterative feedback loop, that allows you to start simple and then refine your spec in response to the running app (“create by reacting”). You iteratively map out what you want in arbitrary detail, and can stop as soon as what you see is what you want.
Bi-directional ideation, where in addition to your spec giving instructions to the model, the model also gives you ideas by “yes anding” your intent, and providing feedback on where to increase precision. This simultaneously empowers the creative process while freeing you from detailing out common sense requirements.
Intent-based expression, that allows you to focus on your app's behavior, and let the AI/tools handle plumbing like setup, recompiling and installing dependencies. That way, you get a robust/real-word app, while being able to focus on your spec, not framework and setup complexity.
The vision of SpecLang is to support any type of application at any scale, but to quickly build a comprehensive end-to-end experience, we will first focus on a particular domain: Mobile apps using React native.
This domain allows a live-preview development experience, where your spec is recompiled as soon as you hit Save, and you then immediately see and can test your changes.
In the screenshot below we see how the developer has a spec and the preview side-by-side.
SpecLang gets you going from zero in no time: from a one-liner on the command-line, SpecLang generates an initial spec for you and compiles that to a working program. This gives you a suggestion for how you can structure your spec, and it gives you something to immediately consider and iterate on: this "creation by reacting" allows you to fully leverage the AI's ability to guess your intent without having to spec it out in all details, since you only need to detail out the parts that need to change.
A process watches for spec changes in the background, ready to initiate the necessary recompiles. SpecLang intelligently identifies which part of your program needs to be recompiled based on your change, keeping the recompilation latency low.
In the example below, we are initializing a simple HackerNews client project:
SpecLang then initializes a fully working project and expands your one-liner into a simple spec:
# SpecNews A HackerNews client that shows a list of trending posts. ## Screens ### Home Page Displays a list of trending posts from HackerNews. - **Behavior:** Fetches and updates the posts from the HackerNews API. - **Layout:** Contains a `Header` and a `PostList`. ## Components ### Header Displays the app title and a refresh button. - **Behavior:** On tap, triggers the `PostList` to refresh the posts. - **Styling:** Fixed at the top, with a large font size and a background color. ### PostList Displays a list of posts in a scrollable format. - **Behavior:** - Renders a list of `PostItem` components. - Supports pull-to-refresh and infinite scrolling. - **Styling:** Occupies the remaining space below the `Header`. ### PostItem Displays an individual post with its title, score, and author. - **Behavior:** On tap, opens the post URL in a web browser. - **Styling:** - Displays the title in a bold font and the score and author in a smaller font. - Has some padding and a separator line.
Compiling and previewing this spec gives the preview we saw before.
The app and spec is probably not exactly what we had in mind, based on just a single one-liner! But it's a great start, and we can now go ahead and iterate on the spec to get to what we want. In the example below, we've detailed some styling on the post items, stipulating that the author and score be right-aligned:
There are many directions for the entire toolchain experience of SpecLang that we would like to explore, e.g.:
- Surfacing to the developer when the model takes non-trivial or stylistic decisions and provide a way to "pull back" those changes into the spec.
- Enable a higher-level editing of the spec, e.g. by planning out a new feature via some interaction between the developer and the model, which then results in a change to the spec.
- Use DALL-E to generate image assets, and conversely, use input diagrams and sketches as input for high-level editing and styling.
More fundamentally, SpecLang represents an entirely new paradigm for programming. As such, we're excited to start exploring with the community what development feels like in this paradigm, e.g.:
- What are useful tools around "debugging a spec"? Is it enabling jumping seamlessly between the spec and the compiled code, or is it via conversations with the model, exploring its understanding of our intent?
- How should complex specs be structured to be extensible, readable, and maintainable? We have more than 60 years of experience with this for classical programming languages, and the community will need to come up with similar best-practices for specs.
- We're currently focusing on mobile apps which is a front-end heavy domain. What will be a good analogy of the live preview for enabling a tight development loop, when developing, for example, a string manipulation library?