Recently I had an opportunity to dwell into an interesting UI problem - with the proliferation of Single Page Application (SPA) as a design pattern for UI development, you sometimes end up with many screens that are not significantly different from each other. In this case the screens were web-forms. Most web-forms have a standard bunch of UI components - textbox's, textarea's, radio-button's, combo-box's et al. Instead of building each of these web-form's as a separate UI project the idea was to roll a DSL with 4 requirements -
eval. The hypothesis was since there exist JS parsers which are used in IDE's for checking JS correctness (JS lib that parse JS code) - could they even execute JS without using the built-in
eval. Looked at Acorn, Esprima & Uglify and found they don't provide a 'execute' functionality (and logically so). Also discovered
safe-eval lib's on NPM are mostly useless and the MDN suggestion of using
Function() does not work. The basic problem with
eval itself in JS are plenty including - (a) Prone to injection attacks (b) Debugging is hard (no line number).
UI developers love JSON. So, why not use JSON itself as the DSL. JSON fit the bill perfectly for requirement #1. Now, could I use the logical expression evaluator lib's in the JSON world for #2? I looked at JsonLogic and Json-Rules-Engine. Tho both these are fine projects, what made me anxious was the verbosity and complexity. The logical expressions were not intuitive and required thorough understanding of the intricacies of these lib's. The language got too verbose too quickly - 2 or 3 levels of nesting was going to make the JSON look monstrous.
Thinking about parser-generators, the following thoughts bothered me -
Personally, my most favored languages in current times are Scala and Haskell. My ability to write code is fastest in Scala. And I had heard that ScalaJS packs a punch. I also wanted to add the following non-technical requirements -
My interest on this ScalaJS way got a filip when I found that Scala parser-combinators, which is a standalone lib, is available and works perfectly well for ScalaJS. So here is what I built on a bright Saturday 3 months ago -
RegexParsersdata type of Scala parser-combinator. The statements in the DSL are tokenized into a bunch of neat instances of
case class/object- Scala's wonderful support to build ADT helps in giving structure to the token's
It has some very simple functionality encoded in the DSL. When
textInput3 has value of "kumar" entered, it adds a new TextBox etc
The DSL I built is not complete. I wanted to attempt requirement #3 but could not due to paucity of time. But it should be pretty straightforward to add some new keywords for REST/GQL calls connecting these components, or POSTing their values on form submission. What the project did was open my eyes to the possibilities - both within the Scala ecosystem and how the walls between backend/frontend are being shattered in amazing ways. Finally, it also allowed me to code in Scala after a bit of hiatus :)