I have to create a DSL for non-programmers (customers of our company) that needs to provide some higher-level language features (loops, conditional expressions, variables ... - so it's not just a "simple" DSL).
Working with the DSL should be easy; people should be able to experiment with it and learn it by playing around. We want to achieve something similar to Macros in Microsoft Excel - many Excel users can create simple formulas, sums or calculations and have never worked with a "real" (general purpose) programming language.
Obviously not every Excel-user understands the more complicated built-in methods (like When()), but they can use simple methods like SUM() or AVG(). I want to achieve a similar effect with the DSL - uesrs should be able to intuitively work with it and define simple rules or perform simple calculations. At the same time the DSL should offer higher-level features for the more technically inclined - like loops, if-statements, possibly methods or lambdas.
And this leads me to my question(s): What language constructs are intuitive, easy to learn and understand?
In the current, experimental version of the DSL we tried a method-chaining approach, example: list.where(item -> item.value > 5).select(item -> item.name + " " + item.value)
).
Think of where
and select
as foreach
constructs where item
is a variable that represents the current item within the loop.
The reason we tried this approach first is that it would be easy to support code completion - whenever a user enters a period (.
), show a list of possible methods. However I'm not sure this concept meets my criteria of being intuitive and easy to understand and read.
Is it easier / more readable for users if there are no braces? (like in LINQ: from item in list where item.value > 5 select item.name + " " + item.value
). However in this case, there are no "boundaries" - in the prior example the user knows that the statement ends with the last closing brace - in this case, if he types more code after the select
part of the statement, he doesn'- know if it belongs to the statement or not (apart from the fact that the parser wouldn't know either and there had to be some sort of closure).
I hope my question is a bit clearer with these 2 examples - I'm looking for design guidelines, best practices, real-life experiences, probably research material of which language constructs are favorable to others - or some evaluation of pros and cons of certain language constructs.
I am not looking for information on how to create a DSL, on what parser generators I could use etc. and I also can't use an existing general-purpose language (Ruby, Python, ...) instead because of the way the DSL is used. (The DSL, when parsed, works directly with our object model - I won't go into details here since this question is already long enough as it is).
Edit: Perhaps I should point out that by "language constructs" I mean the syntax, the way something is written, not what kind of functionality the language should offer - we already have a list of featuers the DSL has to provide. The question is how these features are best expressed to allow the creation (and maintenance) of simple and complex formulas.
While I don't like to answer my own questions, I want to close this one and leave some links for those looking for similar information. (Reason I accept this one is that, while Ira's answer goes in the right direction, the report is kinda outdated – James' answer is unrelated to my question).
So, on to usability of languages:
The Cognitive Dimensions of Notations are a great framework to evaluate the usability of a notation, or any cognitive artifact for that matter.
The Natural Programming site contains lots of interesting publications, the most useful for me was Usability Issues in the Design of Novice Programming Systems
Finally, the most recently active research field related to my question seems to be End User Development. Searching for publications in that area should result in quite a lot of useful information.
It seems to me that the critical issues for designing a domain are its concepts and the relationships between them. This is covered by domain analysis, which it sounds like you have already done, but a key link anyway:
Guillermo Arango on Domain Analysis
With such analysis, you want to engineerin a domain, including a means of expressing problems and solutions. Wikipedia on Domain Engineering was the obvious first place for this, but I found it very unsatisfying in that it failed to reference Arango's work.
(Arango was my officemate at UCI Irvine back in the 1980s, when domain analysis and engineering was a hot topic).
What you seem to want is human factors in langauge design. Bill Curtis produced a report, while a bit old, might be helpful. He was (still is) a psychologist. I'd look for research papers that referenced his (check out citations under google scholar).
I have read DSLs in Action (http://www.manning.com/ghosh/) and he did a fantastic job of explaining different issues regarding writing DSLs, and used several languages that run on the JVM in his examples.
So, you may want to check that out, and then you can look at his references to get more information where you need it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With