Purely declarative DSL

time to read 2 min | 291 words

Let us assume that we need to build a quote generation program. This mean that we need to generate a quote out of the customer desires and the system requirements.

The customer's desires can be expressed in this UI:


The system requirements are:

  • The Salary module is specification is a machine per every 150 users.
  • The Taxes module requires a machine per 50 users.
  • The Vacations module requires the Scheduling Work module.
  • The Vacations module requires the External Connections module.
  • The Pension Plans module requires the External Connections module.
  • The Pension Plans module must be on the same machine as the Health Insurance module.
  • The Health Insurance module requires the External Connections module.
  • The Recruiting module requires a connection to the internet, and therefore requires a fire wall of the recommended list.
  • The Employee Monitoring module requires the CompMonitor component

The first DSL that I wrote for it looked like this:

if has( "Vacations" ):
	add "Scheduling"
number_of_machines["Salary"] = (user_count % 150) +1
number_of_machines["Taxes"] = (user_count % 50) +1

But this looked like a really bad idea, so I turned to a purely declarative approach, like this one:

specification @vacations:
	requires @scheduling_work
	requires @external_connections
specification @salary:
	users_per_machine 150
specification @taxes:
	users_per_machine 50

specification @pension:
	same_machine_as @health_insurance

The problem with this approach is that I wonder, is this really something that you need a DSL for? You can do the same using XML very easily.

The advantage of a DSL is that we can put logic in it, so we can also do something like:

specification @pension: 
	if user_count < 500:
		same_machine_as @health_insurance
		requires @distributed_messaging_backend
		requires @health_insurance

Which would be much harder to express in XML.

Of course, then we are not in the purely declarative DSL anymore.