According to wikipedia, metaprogramming is the “writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime. In some cases, this allows programmers to minimize the number of lines of code to express a solution (hence reducing development time), or it gives programs greater flexibility to efficiently handle new situations without recompilation”.
Thanks to these features of dynamic languages, it is straightforward to create a mini-language modeling a particular business domain. These ad-hoc languages, called Domain-Specific Languages (DSL), make it easy for developers and subject matter experts to share a common way to create and deliver the final application to the end users.
In OEPI, as our prototype is based on Java, we have been leveraging groovy metaprogramming features to develop some nice features allowing our business users to describe formulas and calculations almost in “natural language”:
3.kg + 250.g (3 kilograms + 250 grams)
2.kg + 3.lb (2 kilograms + 3 pounds)
100.MJ + 200.kW*h (100 Mega Joules + 200 kiloWatts * hour)
50.km/h + 20.m/s (50 kilometers per hour + 20 meters per second)
1500.EUR + 1200.USD + 1300.CHF
Therefore, the impacts of some materials, processes, etc. can be expressed in a language easily understood by domain experts. Moreover, all the stuff related to calculations with different units of measurement is automatically handled under the hoods.
For example, carbon dioxide emissions for a given mass of stainless steel (from ELCD database) can be expressed as follows:
CO2 = 3.38.kg * mass / 1.kg
A similar example is the impact of the consumption of a given amount energy in a country. Using the data for Spain (from ELCD database), we get the impact formulated as follows:
CO2 = 0.634.kg * energy / 3.6.MJ
A little more complex example is the impact of the transportation of goods by an articulated lorry (ELCD database):
CO2 = (0.0044.kg * mass * distance) / (1.kg * 100.km)
Thanks to the power of the DSL, business can later set values that are compatible with mass units (kg, g, lb, etc.), energy units (J, kJ, MJ, W*h, kW*h, etc.) or distance units (m, km, ft, yd, mi, etc.) to perform calculations based on these formulas. Therefore, the main advantage of such solutions is that users are writing actual code snippets almost without realizing it.
Thus, we have thoroughly used these capabilities in the prototype:
Letting users create “composed EPIs” (i.e.: Global-Warming Potential):
GWP100 = 1*CO2 + 25*CH4 + 298*N2O + 22800*SF6 + …
Calculating impacts through the supply chain (one of the key points of the project). Assuming that a product has components purchased from suppliers (for example, two containers and an electrical panel), the impact of the components of such product is managed also by a DSL:
components.CO2 = 2 * container_XA300.CO2 + electric_panel_FX2.CO2
This can be read as “the CO2 emissions of the components is 2 times the CO2 emissions of the container plus the CO2 emissions of the electri panel”. Generally speaking, the term “product”.”name_of_epi” can be used by a domain expert to compose different formulas (business rules) when describing and calculating environmental impacts.
Therefore, from my point of view, writing a Domain-Specific Language for calculating environmental impacts has really paid off in OEPI. First of all, it is a more expressive language, quite close to natural language. As a result, the development team has been working closely with domain experts sharing a common understanding, writting together an important part of the business rules.
Summing up, metaprogramming and DSLs not only have been a neat way to tackle some challenges we have been facing in the development of our prototype but they have provided an efficient and expressive solution, allowing us to build a solution closer to our users’ needs and requirements.
José Antonio López Abad, Solution Architect at ERICSSON