August 1, 2024 by Olivier Goffart
Embracing DSLs in UI Development: Why Learning Slint Isn’t Harder Than Mastering an API
Many developers hesitate to learn a Domain Specific Language (DSL) for UI development. At Slint, we use a DSL for creating user interfaces. This post explains why adopting our DSL is easier than mastering a GUI toolkit API in your favorite programming language.
Slint is a toolkit for creating user interfaces across a range of targets. Supporting Android, Windows, Mac, Linux, and bare-metal systems, Slint features an easy-to-learn DSL that compiles into native code, optimizing for the target device's capabilities.
What is a Domain Specific Language?
A Domain Specific Language (DSL) is a programming language designed for a specific task. Unlike general-purpose languages, DSLs are specialized to be very good at one thing. Examples of DSLs include SQL for databases and HTML for web pages. When a developer needs to implement a GUI or translate a design into a real application, they must convert a graphical view into the model of the toolkit. This can be done either through calls to the toolkit's API or via a DSL.
To illustrate, let’s compare creating a simple dialog in Slint’s DSL versus using an equivalent Rust GUI API.
Slint DSL:
component SimpleDialog {
property <string> message;
callback close();
VerticalLayout {
Text { text: root.message; horizontal-alignment: center; }
Button { text: "OK"; clicked => { close(); } }
}
}
Imperative code in Rust:
fn create_simple_dialog(message: &str) -> Dialog {
let dialog = Dialog::new();
let content_area = dialog.content_area();
let label = Label::new(message);
label.set_horizontal_alignment(Alignment::Center);
content_area.push(label);
let button = Button::new_with_label("OK");
button.connect_clicked(move |_| {
dialog.close();
});
content_area.push(button);
dialog
}
The Learning Curve: DSL vs. API
Many developers think learning a DSL is hard. But let’s compare it to learning a GUI toolkit API in a general-purpose language. While GUI toolkit APIs use a familiar syntax, you still need to understand the toolkit's concepts, how to set and get properties, react to events, and know the widgets and their properties. In both cases, the new syntax doesn't represent a big part of what needs to be learned. And the DSL's syntax being designed to be easy and specific for the task at hand, the learning curve for a DSL is not really steeper. In fact, it can be easier and more productive.
Advantages of Using a DSL for UI Development
Clean and Concise Code:
DSLs like Slint allow for more readable and maintainable code. The declarative style means you focus on what you want to achieve, not how to do it.
Separation of UI and Logic:
By design, DSLs encourage a clear separation between the UI and the logic. This makes it easier to manage and maintain large codebases. The UI is described in the Slint language, while the application logic is written in a general-purpose language like Rust, C++, TypeScript, or Python.
Better Tooling:
DSLs enable powerful tools that imperative languages cannot match. For instance, with Slint, we provide a live-preview feature and a drag-and-drop property editor, which make UI design faster and easier. This is because a DSL contains the relevant data in a clear structure that tools can directly edit. In contrast, imperative languages mix UI code with other logic, making it hard for tools to isolate and manipulate.
Empowering UI/UX Designers
By using a DSL like Slint, UI/UX designers who are somewhat technical can directly engage with the implementation details of a project. Some are already accustomed to working with complex and interconnected DSLs like HTML and CSS. This hands-on approach enables quicker iterations and better collaboration between designers and developers, leading to more efficient development processes.
A Balanced View on DSLs
While DSLs have many advantages, they also have some disadvantages. One is limited flexibility. DSLs are made for specific tasks, so they might not be as versatile as general-purpose languages. In that case, when developers need to perform tasks outside the domain-specific scope, it requires them to switch back to a general-purpose language. Another issue is tooling dependency and integration with existing systems. But these challenges are often outweighed by the benefits, especially in UI development where clarity, separation of concerns, and powerful tools can make a big difference.
Another concern is the complexity of mixing a DSL with a general-purpose language. However, modern editors have evolved to handle this seamlessly. For example, in VSCode, you can use multiple Language Server Protocol (LSP) extensions to provide auto-completion and other IDE features for both Slint and Rust in the same file.
Conclusion
Domain Specific Languages like Slint offer a great alternative to traditional GUI toolkit APIs. They provide cleaner code, a clear separation of concerns, and better tools. The learning curve is not much different from learning a GUI toolkit API. In fact, using a DSL can make you more efficient and improve your development experience.
Next time you think about learning a DSL, remember: it’s about how effectively you can achieve your goals. In UI development, DSLs like Slint are optimized to help you do just that.
Slint is a Rust-based toolkit for creating reactive and fluent user interfaces across a range of targets, from embedded devices with limited resources to powerful mobile devices and desktop machines. Supporting Android, Windows, Mac, Linux, and bare-metal systems, Slint features an easy-to-learn domain-specific language (DSL) that compiles into native code, optimizing for the target device's capabilities. It facilitates collaboration between designers and developers on shared projects and supports business logic development in Rust, C++, JavaScript, or Python.