In the journey to build a good useful language, we decided to enforce consistency wherever we can.
That’s one of the three rules we have in the team.
- Fix the broken window
- Zero support scalation policy
To achieve this, one of the fundamental steps was to get rid of the hardcoded operators. Before this, functions such as
filter were reserved words of language. That made the language very little extensible and made the fixes were scarce, because we had to deliver the whole product to fix an error.
At the same time, we had to maintain consistency with DataWeave 1.0, because we couldn’t afford to let users learn the new version from scratch.
That’s why we introduced the infix functions. These are normal functions, which can be used between arguments instead of being a prefix.
map is now a function.
How do we create infix functions?
It is really easy indeed, it is just a function.
That script returns a value
When we wanted to make
map become a function, we found that it was overloaded for Ranges and Arrays. In that moment we decided to implement function overloading in the language.
1 [ "Hello world!", 3 ]
We knew that precedence was a complicated thing in DataWeave 1.0, people spent their time fixing their scripts using dozens of parenthesis. We decided to solve it by unifying precedence in a simple way.
All that is on the left side of an Infix operator is the first argument, and the first expression on the right side is the second.
But wait, what is the dollar sign?
It is an argument of an automatic function injection. I explain it in detail here
We are still missing a mechanism to replace core functions like
Previously, we had no way to iterate over arrays or objects. The language itself did not provide any mechanism to do that. We decided to implement tail call functions to solve that problem.
Briefly, it allows us to create streamable recursive functions, and that’s really important due the async nature of DataWeave.
We use tail recursion to create lazy generators, a good example could be a sequence generator.
Going back to the
map function, in DataWeave 1.0 it was a Scala binding. It was a hardcoded operator in the language. Right now we can implement the
map function directly in DataWeave, without external bindings. It looks like this