a visual dsl toolkit in lua: past, present and future
DESCRIPTION
Lua, besides its other virtues, is quite easy to learn. Nevertheless, Lua is a programming language, and in order to learn it one must invest a considerable effort to learn to write programs. It is often the case that, on one hand, there is a need to configure lots and lots of business logic intricate and ever-changing rules, but, on the other hand, the person who has the most expertise on the particular business logic area – domain expert – not have any clue on how to write code effectively (or even at all). All kinds of clumsy UIs, spaghetti code, wasted dedicated scripter's hours and other unpleasantries stem from that problem. Our flagship product – Business logic editor toolkit – attempts to alleviate that somewhat by providing a programmer with a set of tools to easily build a business-logic configuration UI, suitable for a non-programmer domain expert, and an easy, platform-agnostic way to seamlessly tie business-logic configuration from that UI to an existing (or newly written) codebase, effectively creating a visual domain-specific programming language. Our toolkit is written in Lua (and some JavaScript), and it is a seventh generation implementation of the concept behind it. In this talk I'll talk a little about the past generations, describe the mechanics behind the current implementation in some detail, and I'll share our thoughts on how the next generation should look like – a new approach on the internal DSL design in Lua. And a promise: no marketing speak in the talk, and as much technical details as I'd dare (and time will permit)!TRANSCRIPT
A visual DSL toolkit in LuaPast, present and future
Alexander Gladysh <[email protected]>
Lua Workshop 2013Toulouse
1 / 44
Outline
Introduction
The Problem
Classic third-party alternatives
Past generations
The present generation
The future
Questions?
2 / 44
Alexander Gladysh
I CTO, co-founder at LogicEditorI In löve with Lua since 2005
3 / 44
LogicEditor
I Use Lua to develop:I Visual DSL toolkit (subject of this talk)I Big-data analyticsI Intensive-load web-servicesI In-browser and mobile games
I 600+ KLOC of private Lua codebaseI Some contributions to open-source Lua projects
4 / 44
The Problem
I Business-logic is highly volatile.I Programmers are not domain area specialists.I Specialist ⇔ Manager ⇔ Programmer loop is slow.I Specialist ⇔ Programmer loop is expensive.I Let specialists do the business-logic!
5 / 44
6 / 44
Non-programmers aren’t programmers
It is not enough to be able to compose an algorithm and evenimplement it with some simple programming language.For commercial programming you’ll also need, at least:
I Technical backgroundI Debugging skillsI Team coding skills
7 / 44
Solution
I A tool that prevents technical mistakesI While limiting creativity as little as possibleI And is within grasp of a non-programmer.
8 / 44
Ad-hoc implementations
I One-shot, very limited flexibilityI Full of crutchesI Hard to maintain
9 / 44
Classic third-party alternatives
10 / 44
MIT Scratch
11 / 44
Descent Freespace Editor Events
12 / 44
Lego NXT-G
13 / 44
Apple Automator
14 / 44
What is in common?
I A visual domain-specific language,I that allows user to describeI the control-flow.
15 / 44
A retrospective of ideas
Screenshots shown here are from editors done by me and/or mycolleagues for different companies we worked for, over time.Only an idea was re-used and improved between generations.
16 / 44
Video-adventure game editor
(No screenshots available)
I Legacy, circa 2002—2004I Graph of in-game dialog remarks and answer choicesI Allowing to tie-in video-loop to remarkI No Lua.
17 / 44
Adventure game dialog editor, I, II
I Graph of in-game dialog remarks and answer choicesI With ability to add custom Lua code logic (in II)I Generated data (in Lua) for a state machine (also in Lua)
18 / 44
Browser MMO quest editor, I, II
19 / 44
Browser MMO magic system editor
20 / 44
Analysis
I Some non-programmers prefer visual control-flow editors.I Some — textual representation.I (Programmers hate to use both kinds.)I All editors were very useful, some — invaluable.I But, in retrospective, some should have been replaced by
dedicated coders.I None of the past-generation editors were flexible enough to be
used outside its immediate domain (but this never was anofficial goal for them).
21 / 44
The Visual Business Logic Editor Toolkit
22 / 44
Design goals
I Easy to create new editors.I Easy to support existing editors.I Easy to integrate with "any" other project on "any"
technology.I Easy enough to learn and use by end-users.
23 / 44
Editor use-cases
For example:
I A dialog editor for a game scenario writer.I A magic system editor for a game-designer.I A mission logic editor for a game level-designer.I A DB query editor for a data analyst (Hadoop, anyone?).I An advertising campaign targeting editor for a marketer.I ...and so on.
24 / 44
Technology
I The data is a tree corresponding to the control flow (or toanything tree-like, actually).
I The output is structured text (code or data).I Editor code, UI and backend, is generated by Lua code in the
Toolkit, from the data "schema".I Editor UI is in JavaScript / HTML, backend is in Lua.
25 / 44
The Data Schema
I Embedded Lua DSL (see my talk on Lua WS’11).http://bit.ly/lua-dsl-talk
I Describes how to:I check data validity,I generate default data,I render data to editor UI,I change data in editor UI,I render the conforming data to the output code (or data).
I Two layers: human-friendly and machine-friendly
26 / 44
Schema Example, I
See also: http://bit.ly/le7-schema
lang:root "lua.print-string"
lang:value "lua.string.value" {data_type = "string";default = "Hallo, world!";render:js [[String Value]] { [[${1}]] };render:lua { [[${1}]] };
}
27 / 44
Schema Example, II
lang:func "lua.print-string" {"lua.string.value";render:js [[Print string]] {
[[Print: ${1}]];};render:lua {
[[print(${1})]];};
}
28 / 44
Default Data
{id = "lua.print-string";{
id = "lua.string.value";"Hallo, world!";
}}
Renders to Lua as:
print("Hallo, world!")
29 / 44
UI for default data (simplified)
<div id="lua.print-string">Print: <span id="lua.string.value">Hallo, world!</span>
</div>
NB: That <span> turns to edit-box on click.
30 / 44
Extending string type
lang:type "lua.string" {init = "lua.string.value";render:js [[String]] { menu = [[S]]; [[${1}]] };render:lua { [[${1}]] };
}
lang:func "lua.string.reverse" {type = "lua.string";render:js [[Reverse string]] { [[Reverse: ${1}]] };render:lua { [[(${1}):reverse()]] };
}
31 / 44
Print with multiple arguments
lang:list "lua.print"{
"lua.string";render:js [[Print]] {
empty = [[Print newline]];before = [[Print values: <ul><li>]];glue = [[</li><li>]];after = [[</li></ul>]];
};render:lua {
before = [[print(]];glue = [[,]];after = [[)]];
};}
32 / 44
Main primitives
I lang:constI lang:valueI lang:enumI lang:funcI lang:listI lang:type
33 / 44
Machine-friendly schema
I node:literalI node:variantI node:recordI node:valueI node:list
34 / 44
Data-upgrade routines
I A set of hooks for data tree traversal.I Transformations between two given data versions.I In terms of node schema.I Semi-automatic, template code is generated.
35 / 44
What else?
I Scopes in the schema.I External and internal data-sources.
36 / 44
Several points of improvement
Current generation does its job well, but we see several ways onhow to make it betterSeveral points to improve
I Better, modern HTML (at the cost of support of IE6).I Lua in browser for a server-less integration option.I Even more flexible and expressive Schema DSL.
NB: We’ll probably go for a control-flow diagram UI first, nottext-based one (current text-based is cool enough).
37 / 44
Problems with the current DSL
I One language for three separate concepts:I data tree structure,I editor UI,I final output.
I Data tree structure gets a bit synthetic and convoluted attimes.
I Should be easier to add alternative editor UIs.
38 / 44
Solution
I Three separate sets of languages:I data tree format,I render to output (per output format),I render to editor (per editor kind).
I CSS-like rules instead of pre-defined set of node types
39 / 44
Early examples
http://bit.ly/le8-proto
data:root "script"data:type "script" ("*", "action")data:type "action" "print-var" "var-name"
to:text "script" :T [[local _VARS = {}${indent(concat(children))}]]to:text "print-var" "var-name"
:T [[print(_VARS[${quote:lua(node)}])]]
to:ui "print-var" "var-name":T [[Print: ${child(1)})]]
40 / 44
An alternative approach to the Embedded DSLs in Lua
foo:bar "baz" { "quo" }
local proxy = fooproxy = proxy["bar"]proxy = proxy(foo, "baz")proxy = proxy({ "quo" })
41 / 44
The FSM
foo:bar "baz" { "quo" }
If proxy is as a FSM, indexes and calls — state transitions.
INIT | index "bar" -> foo.barfoo.bar | call -> foo.bar.name
foo.bar.name | call -> foo.bar.name.paramFINAL <- foo.bar.name.param
Early working prototype: http://bit.ly/le-dsl-fsm.
42 / 44
Easier to code complex DSL constructs
play:scene [[SCENE II]].location [[Another room in the castle.]]:enter "HAMLET":remark "HAMLET" [[Safely stowed.]]:remark { "ROSENCRANTZ", "GILDERSTERN" }
.cue [[within]] [[Hamlet! Lord Hamlet!]]:remark "HAMLET" [[What noise? who calls on Hamlet?O, here they come.]]
43 / 44