Tools play an important role in our work and we often use Rascal, but certainly not always. We explain our nuanced relationship with Rascal.

“To a person with a hammer, every problem looks like a nail”. In other words, some people have a one-size-fits-all tool to solve everything. You might think that we’re guilty of this at Swat.engineering because we use Rascal a lot. So, are we myopic software engineers obsessed with a single language and its tools? Not at all. Here is our nuanced story.
Why are we so excited about Rascal?
Let’s start with a disclaimer. I’m one of the original designers of the Rascal meta-programming language. In 2009, I started this journey with Jurgen Vinju and Tijs van der Storm, and I’ve been a core contributor ever since. We founded Swat.engineering in 2016, and it has been profitable since day one. Our goal is to help commercial partners gain control over their software, often with the help of Rascal. Our CEO, Davy Landman, joined the team of core contributors when he was still a researcher at CWI, and now, he and all our employees contribute to Rascal in one way or another. This is the topic of Swat.engineering & Rascal’s Evolution (to be published).
With this disclaimer out of the way, here are some reasons why we’re excited about Rascal from a commercial and technical perspective.
Commercial
Rascal has been designed for software analysis and transformation. Many problems regarding digital transformation, migration, software rejuvenation, and domain knowledge management fit this bill. Rascal is open-source software licensed under BSD2. This means that our customers are never locked in by proprietary tooling.
Rascal is also used at universities and research centers. This creates a pool of Rascal experts and potential employees.
Extensions and improvements we contribute primarily remain open source. This also has a maintenance advantage for our clients. The only closed source we produce is customer-specific applications and VS Code extensions. It goes without saying that all other artefacts we produce for a customer, including requirements and design, remain confidential as well.
Thanks to Rascal’s high-level facilities, we can produce better products for our customers in a shorter time span. Of course, the mileage varies per project.
Technical
Rascal is a one-stop shop for meta-programming. It is a statically typed language with the main (immutable) data types boolean, integer, real, list, set, map, tuple, relation, list relation, datetime, and source location. The latter are URI-based descriptions of a region in a text file and can be used for precise error messages and defining relations between source code fragments, such as use-def relations.
Rascal’s concepts include grammar definition and parsing, tree traversal, pattern matching, string templating, and (de)serialization for data structures. This means that activities, including syntax definition, parsing, type checking, code analysis, code generation, code transformation, data analysis, and visualization, can be carried out in a single conceptual and technical framework. No more error-prone plumbing of only partially compatible tools.
Rascal supports analyzing a range of languages, including Java, Python, Lua, ADA, and C++. The list is growing. Rascal plugins exist for VS Code and Eclipse. They enable the comfortable development of Rascal programs. Rascal also supports the Language Server Protocol (LSP), which enables coupling with many other language tools.
When do we use Rascal?
We use Rascal in a range of scenarios with great effect. However, we have no problems recognizing when a different tool would be better suited.
A legacy system always starts as a black box, and it’s our job to open it and make the box transparent again. During the dark initial phase, we apply requirements engineering (see Keeping Track of Requirements with Lightweight Tools) to gain a global understanding of the whereabouts of the legacy system. What is it supposed to do? Who are the stakeholders? What do they expect from a rejuvenated version of the system?
We also write one-off Rascal queries to gain insight into the internal workings of the system. What is the component structure? How are they linked together? What external components are involved? What is dead code? We also use one-off Rascal queries to explore dangerous or undesired situations in the system.
Based on these insights, we make a roadmap for rejuvenation, see From Requirements to RoadMap (to be published)).
Once some clarity has been obtained, reconstructive steps can be undertaken. Guided by dedicated Rascal-based analyses, parts of the system can be restructured (manually or automatically). Parts involving an editor or IDE can be rewritten in Rascal to benefit from a wealth of functionality provided, for instance, by VS Code and its Rascal integration.
For legacy binary data that need version control, Rascal can be used to introduce textual DSLs to represent the data. As DSLs are better suited for version control.
If the legacy system implements its own domain-specific languages, many more applications of Rascal are in scope. In this case, there is a supposedly large base of DSL code that has to be vetted and possibly migrated. Possible applications are:
- Write checks in Rascal to look for code smells in the legacy DSL code. These are areas for semi-automatic improvement.
- Identify local extensions of the legacy DSL that improve its usability (complete redesigning of a legacy DSL is usually not feasible for either budgetary or technical reasons). These extensions have to be designed, implemented, and tested, and the old DSL code base has to be (semi-)automatically converted to use the new features.
- Where relevant, reimplement the DSL tools, including compiler and typechecker, in Rascal.
- Implement new IDE tools for the legacy DSL. There are no more grateful clients than former Notepad users who have migrated to a shiny VS Code-based IDE for their old DSL.
Most of the things we mention here about legacy systems apply to new (green field) systems as well. But the truth is that nearly every green field system has to be aware of and deal with its legacy surroundings.
Other languages and tools we use
Here are just some of the many languages and tools we use in various situations:
- C/C++/Java: as targets for code generation when improving legacy systems written in these languages, and for building new components.
- JavaScript and TypeScript for implementing UI components and VS Code extensions.
- Spreadsheets: not only for the usual administrative and commercial tasks, but even for requirements engineering.
- R and Python for incidental statistical analysis or charting.
- gRPC/Protocol Buffers when we have to achieve high performance and cross-platform RPC in the communication between components.
- Version control tools for customer DSLs.
- A rather standard Continuous Integration (CI) pipeline.
Key takeaway
“Focus on the nail, not on the hammer, but use the hammer when you can.” In other words, Rascal has many applications, but it cannot cure all ills.
Get in touch
We’re happy to discuss potential applications of our expertise and tools to solve your IT challenges.