This fairly short program gives a reasonable facsimile of a small segment of the painting. It's lacking the rectangular highlights in the petals, and the blue shape on the right is just a dummy, since I did not get around to triangle shapes. It's also missing other elements such as the legs and the streamer on the top right.
Clearly, a lot more has to be added to the language to be able to create the rest of the painting or the others in the series.
But already we have a quite powerful set of primitives. Although each set is only a few lines of code, you can get a variety of results from fairly simple code. This kind of power is something that often does not come up until you put a tool such as this DSL in the hands of an artist and give him or her a chance to play around with the parameters and the code. (Listing 3 and Figure 4 contain more examples of Whimsy.)
Listing 3: Five Whimsy Creations
superEgg .1,.05,4 at .2,.2 green distort 0.01
petals 8 blue
superegg .1,.1,2 at .5,.2 grey distort .02
inner .5 orange distort .02
petals 12 blue size 3
circle at .35,.35 size .05 distort .04 petalblue
petals 8 size 20 petalblue
superegg .1,.05,4 at .2,.45 white distort .1
inner .5 distort .01 yellow
superegg .1,.1,3.0 at .5,.45 brown
superegg .1,.1,2.0 at .5,.45 teal
superegg .1,.1,1.0 at .5,.45 darkblue distort .02
petals 20 .5 yellow size 3
superegg .1,.1,0.5 at .5,.45 darkgreen
petals 50 orange
superegg .1,.1,0.25 at .5,.45 purple
Figure 4: Some examples of the flexibility of the Whimsy primitives.
One rather surprising result was that I was able to duplicate the star-like objects using a tiny distorted circle with eight very long petals. Ideally these would have been created from four intersecting brushstrokes, but the distorted petals works pretty well.
The stars raise a central issue. There are 14 stars in the painting. Clearly it's inefficient to create each one by hand by cutting and pasting the same circle and petal code. You really want a Star function that can manage the position, color, and size parameters. We need some kind of macro or function definition functionality.
Although such functionality would not be particularly hard to add, if we had started out by extending an existing language rather than creating our own unique interpreted language, then we would already have this functionality, as well as looping constructs, expression evaluation, variables, and more.
I could quite easily have implemented the Whimsy programs in C++ as a series of function calls with very similar functionality. The problem is that I would have had to recompile and run the program every time I made a change. Right now, the results of a change are displayed the instant a file is modified, which provides a far more interactive experience, and rapid iterations.
I could have implemented Whimsy as an extension to a powerful scripting language, such as Ruby or Python. This would have allowed me to still have the near-instant feedback; but the downside is the syntax is more restrictive.
By implementing an original language, you can express it in any form you like. If you base it on Python, for example, you have to accept many of the restrictions of Python. Ruby is better, but it still comes with some syntactical constraints. There may also be performance implications of using a language like Ruby.
One reason I like the idea of defining an original DSL is that it can be more easily extended from a text-based editing tool to a graphical-based editing tool. Listings 2 and 3, for example, show that there are a lot of numerical parameters. These are tedious to change by hand, and it's a logical extension to allow some form of direct graphical editing of things like size and position.
You can think of this technique as a graphical interface to the text. GUI tools can be used to edit the relatively high-level DSL code, and still have it human readable (and editable). Used in this way, a DSL can be a useful intermediate step in tool development.
[EDITOR'S NOTE: This article was independently published by Gamasutra's editors, since it was deemed of value to the community. Its publishing has been made possible by Intel, as a platform and vendor-agnostic part of Intel's Visual Computing microsite.]