<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.3" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>A Fistful of Languages</title>
	<link>http://littlelanguages.net/blog</link>
	<description>Bridging the gap between language and problem</description>
	<pubDate>Tue, 27 Nov 2007 19:49:18 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.3</generator>
	<language>en</language>
			<item>
		<title>Example Mini Language: MenuBuilder</title>
		<link>http://littlelanguages.net/blog/2006/09/15/example-mini-language-menubuilder/</link>
		<comments>http://littlelanguages.net/blog/2006/09/15/example-mini-language-menubuilder/#comments</comments>
		<pubDate>Fri, 15 Sep 2006 17:46:26 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
	<category>ruby</category>
	<category>dsl</category>
		<guid isPermaLink="false">http://littlelanguages.net/blog/2006/09/15/example-mini-language-menubuilder/</guid>
		<description><![CDATA[In this entry, we elaborate on the previous entry with some examples, along the way providing a glimpse into the most popular technique for embedding DSLs in Ruby, as well as doing a little bit of code generation.
We will consider a very simple domain, that of building nested menus such as the following:

  [Show [...]]]></description>
			<content:encoded><![CDATA[<p>In this entry, we elaborate on the <a href="http://littlelanguages.net/blog/2006/09/01/the-setting-for-dsl-development/">previous entry</a> with some examples, along the way providing a glimpse into the most popular technique for embedding DSLs in Ruby, as well as doing a little bit of code generation.</p>
<p>We will consider a very simple domain, that of building nested menus such as the following:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a8689ded0">
<div class="synthi_header" style="font-weight:bold;">  <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a8689ded0').style.display='block';document.getElementById('plain_synthi_4827a8689ded0').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
<ul>
<li>
    <a href=&#034;/q&#034;>Questions</a>
  </li>
<li>
    <a href=&#034;/a&#034;>Answers</a>
  </li>
<li class=&#034;active&#034;>
    <a href=&#034;&#034;>Letters</a>
<ul>
<li class=&#034;active&#034;>
        <a href=&#034;/letter/bill&#034;>To Bill</a>
      </li>
<li>
        <a href=&#034;/letter/steve&#034;>To Steve</a>
      </li>
</ul>
</li>
</ul>
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a8689ded0">
<div class="synthi_header" style="font-weight:bold;">  <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a8689ded0').style.display='block';document.getElementById('styled_synthi_4827a8689ded0').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div style="font-family: monospace;">&lt;ul&gt;<br />
&nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &lt;a href=&quot;/q&quot;&gt;Questions&lt;/a&gt;<br />
&nbsp; &lt;/li&gt;<br />
&nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &lt;a href=&quot;/a&quot;&gt;Answers&lt;/a&gt;<br />
&nbsp; &lt;/li&gt;<br />
&nbsp; &lt;li class=&quot;active&quot;&gt;<br />
&nbsp; &nbsp; &lt;a href=&quot;&quot;&gt;Letters&lt;/a&gt;<br />
&nbsp; &nbsp; &lt;ul&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;li class=&quot;active&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;a href=&quot;/letter/bill&quot;&gt;To Bill&lt;/a&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;/li&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;a href=&quot;/letter/steve&quot;&gt;To Steve&lt;/a&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;/li&gt;<br />
&nbsp; &nbsp; &lt;/ul&gt;<br />
&nbsp; &lt;/li&gt;<br />
&lt;/ul&gt;</div>
</div>
<p>It&#8217;s simply a nested list in HTML, where each entry is a link to some other page. Clearly, for such a simple example, a DSL may seem redundant. But it does keep the code quite simple, while hopefully keeping enough interest to be of value.</p>
<p>We will implement 3 different versions of the DSL, corresponding to different approaches to DSL development (as per the previous blog entry):</p>
<ol>
<li>
 <t>Program → Actions</t>: In this case, running the DSL program immediately generates the menu as directly as HTML.
</li>
<li>
 <t>Program → Model → Actions</t>: In this case, running the DSL program generates a data structure (the <i>model</i>) representing the menu.  A separate operation renders the menu as HTML.</li>
<li>
 <t>Program → Model → Artifacts → Actions</t>: Again, running the DSL produces a model of the menu. In this case, a code generation phase takes the model and produces Java code which can be incorporated into a Swing application to use our menu (albeit, without any functionality).</li>
</ol>
<p>First, let&#8217;s see what the old school approach looks like in the case where an intermediate data structure is constructed. </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868a2d04">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868a2d04').style.display='block';document.getElementById('plain_synthi_4827a868a2d04').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
require 'model'
require 'render'

mymenu = Node.new(:root, 'root')
questions = mymenu.add_node(:q, '/q', 'Questions')
answers   = mymenu.add_node(:a, '/a', 'Answers')
letters   = mymenu.add_node(:letter, '', 'Letters')
bill      = letters.add_node(:bill, '/letter/bill', 'To Bill')
steve     = letters.add_node(:stever, '/letter/steve', 'To Steve')

puts ListRenderer.new(mymenu).render
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868a2d04">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868a2d04').style.display='block';document.getElementById('styled_synthi_4827a868a2d04').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> &#8216;model&#8217;<br />
<span style="color:#CC0066; font-weight:bold;">require</span> &#8216;render&#8217;</p>
<p>mymenu = Node.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>:root, &#8216;root&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
questions = mymenu.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>:q, &#8216;/q&#8217;, &#8216;Questions&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
answers&nbsp; &nbsp;= mymenu.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>:a, &#8216;/a&#8217;, &#8216;Answers&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
letters&nbsp; &nbsp;= mymenu.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>:letter, &#8216;&#8217;, &#8216;Letters&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
bill&nbsp; &nbsp; &nbsp; = letters.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>:bill, &#8216;/letter/bill&#8217;, &#8216;To Bill&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
steve&nbsp; &nbsp; &nbsp;= letters.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>:stever, &#8216;/letter/steve&#8217;, &#8216;To Steve&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p><span style="color:#CC0066; font-weight:bold;">puts</span> ListRenderer.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>mymenu<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">render</span></div>
</div>
<p>Firstly, a data structure representing the model is imported, as well as code to render the model into HTML. The menu is created by constructing a root node, to which menu entries and submenus are added by attaching these to the appropriate part of the tree being constructed. Finally, the resulting data structure is passed to an object to render it to HTML.</p>
<p>Incidentally, this code resembles the DOM-style of building XML documents.</p>
<p>The MenuBuilder DSL for the above menu will look like the following.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868a7bf5">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868a7bf5').style.display='block';document.getElementById('plain_synthi_4827a868a7bf5').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
mymenu = menu do
	item :q, '/q', 'Questions'
	item :a, '/a', 'Answers'
	item :letter, '', 'Letters' do
	  item :bill, '/letter/bill', 'To Bill'
	  item :steve, '/letter/steve', 'To Steve'
	end
end

render mymenu
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868a7bf5">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868a7bf5').style.display='block';document.getElementById('styled_synthi_4827a868a7bf5').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;">mymenu = menu <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; item :q, &#8216;/q&#8217;, &#8216;Questions&#8217;<br />
&nbsp; &nbsp; &nbsp; &nbsp; item :a, &#8216;/a&#8217;, &#8216;Answers&#8217; <br />
&nbsp; &nbsp; &nbsp; &nbsp; item :letter, &#8216;&#8217;, &#8216;Letters&#8217; <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;item :bill, &#8216;/letter/bill&#8217;, &#8216;To Bill&#8217; <br />
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;item :steve, &#8216;/letter/steve&#8217;, &#8216;To Steve&#8217; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>render mymenu</div>
</div>
<p>This code introduces two methods <t>menu</t> and <t>render</t> which construct menus and render them as HTML, respectively. The <t>menu</t> method takes a Ruby block which implements the contents of the menu. The method <t>item</t> which is available only within the block passed to the <t>menu</t> method creates the items of the menu. Each item is given a symbolic label, a target url, and a label, and optionally, as a Ruby block, a submenu.</p>
<p>The difference between the old school code and the DSL code is small but  important. The original approach forces the programmer to think in terms of objects and operations upon them which build up a data structure representing the menu. With the DSL, the programmer directly describes the menu. The DSL implementation performs the construction of the underlying data structures. With the DSL, a menu is specified declaratively, rather than constructed imperatively. </p>
<p>In addition, the old school approach also requires a premature commitment to a particular approach, which may need to be changed whenever the requirements change. The DSL program is sufficiently abstract yet contains enough information to specify the menu completely. When the implementation requirements change, the menu code need not (necessarily) change.</p>
<h4>1. Direct implementation: Program → Actions</h4>
<p>The following code implements the DSL so that running the <t>menu</t> method directly produces the HTML code to standard output. The <t>render</t> command is not required in this example.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868ac932">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868ac932').style.display='block';document.getElementById('plain_synthi_4827a868ac932').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class MenuWriter
  def self.menu(&#038;block)
    puts &#034;
<ul>&#034;
    instance_eval &#038;block
    puts &#034;</ul>

&#034;
  end

  def self.item(sym, url='&#8217;, name='&#8217;, &#038;block)
    puts &#034;
<li>&#034;
    puts &#034;<a href=&#034;#{url}&#034;>#{name}</a>&#034;
    if block_given?
      menu &#038;block
    end
    puts &#034;</li>

&#034;
  end
end

def menu(&#038;block)
  MenuWriter.menu &#038;block
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868ac932">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868ac932').style.display='block';document.getElementById('styled_synthi_4827a868ac932').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MenuWriter<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">menu</span><span style="color:#006600; font-weight:bold;">&#40;</span>&amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;&lt;ul&gt;&quot;</span><br />
&nbsp; &nbsp; instance_eval &amp;block<br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;&lt;/ul&gt;&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">item</span><span style="color:#006600; font-weight:bold;">&#40;</span>sym, url='&#8217;, name='&#8217;, &amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;&lt;li&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;&lt;a href=<span style="color:#000099;">\&quot;</span>#{url}<span style="color:#000099;">\&quot;</span>&gt;#{name}&lt;/a&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> block_given?<br />
&nbsp; &nbsp; &nbsp; menu &amp;block<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;&lt;/li&gt;&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">def</span> menu<span style="color:#006600; font-weight:bold;">&#40;</span>&amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; MenuWriter.<span style="color:#9900CC;">menu</span> &amp;block<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>The code is pretty straightforward. It evaluates the DSL in the order that is is presented on the page, wrapping each item with the appropriate HTML tags. </p>
<p>For a simple DSL with a simple application which is not likely to ever be reused, this is not bad approach. </p>
<h4>2. Implementation via Model: Program → Model → Actions</h4>
<p>In this approach we introduce a simple class which acts as the model for menus. It is a simple tree data structure.</p>
<p>The following is the code which represents the nesting menu. This is the implementation of the underlying model:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868b174e">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868b174e').style.display='block';document.getElementById('plain_synthi_4827a868b174e').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class Node
  @active = false
  attr_accessor :url, :label
  attr_reader :name, :children

  # constuctor
  def initialize(name, url='', label='')
    @children = []
    @name     = name.to_sym
    @url      = url
    @label    = label
  end

  # add a new node to the tree, returning new node
  def add_node(name, url, label)
    node = Node.new(name, url, label)
    @children << node
    ## stores node in a field named name, creating accessor method
    instance_eval &#034;
      @#{name} = node
      def #{name}; @#{name}; end&#034;
    return node
  end
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868b174e">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868b174e').style.display='block';document.getElementById('styled_synthi_4827a868b174e').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Node<br />
&nbsp; @active = <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; attr_accessor :url, :label<br />
&nbsp; attr_reader :name, :children</p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># constuctor</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, url='&#8217;, label='&#8217;<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @children = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; @name&nbsp; &nbsp; &nbsp;= name.<span style="color:#9900CC;">to_sym</span><br />
&nbsp; &nbsp; @url&nbsp; &nbsp; &nbsp; = url<br />
&nbsp; &nbsp; @label&nbsp; &nbsp; = label<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># add a new node to the tree, returning new node</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> add_node<span style="color:#006600; font-weight:bold;">&#40;</span>name, url, label<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; node = Node.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, url, label<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @children &lt;&lt; node<br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">## stores node in a field named name, creating accessor method</span><br />
&nbsp; &nbsp; instance_eval <span style="color:#996600;">&quot;<br />
&nbsp; &nbsp; &nbsp; @#{name} = node<br />
&nbsp; &nbsp; &nbsp; def #{name}; @#{name}; end&quot;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> node<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>This is really the code of a more elaborate and more useful class. Notice the use of meta-programming in the <t>add_node</t> method. The call the <t>instance_eval</t> creates a field with the name of the node, and stores the new node in that field. An accessor method for this field is also created.</p>
<p>The following class renders a menu as an HTML unordered list using the <a href="http://builder.rubyforge.org/">XML Builder library</a>. This is achieved by performing a simple traversal of the <t>Node</t> data structure.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868b8c88">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868b8c88').style.display='block';document.getElementById('plain_synthi_4827a868b8c88').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
require 'rubygems'
require_gem 'builder', '~> 2.0'

class ListRenderer

  attr_reader :root, :depth, :buffer, :builder

  # pass in the root node of the menu you're trying to render
  def initialize(root)
    @buffer = ''
    @builder = Builder::XmlMarkup.new(:target => @buffer, :indent=>2)
    @root = root
    @depth = 0
  end

  # output HTML -- skips root!
  def render
    render_children @root
    @builder.target!
  end

  private
  # render a single node, recursively render its children
  def render_node(node)
    attr = {}
    @builder.li(attr) { |xml|
      xml.a(&#034;#{node.label}&#034;, :href=>node.url)
      render_children node
    }
  end

  # render children
  def render_children(node)
    # now descents down the children and do the same
    return if node.children.length == 0
    @builder.ul {
      node.children.each { |child| render_node(child) }
    }
  end
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868b8c88">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868b8c88').style.display='block';document.getElementById('styled_synthi_4827a868b8c88').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> &#8216;rubygems&#8217;<br />
require_gem &#8216;builder&#8217;, &#8216;~&gt; <span style="color:#006666;">2.0</span>&#8216;</p>
<p><span style="color:#9966CC; font-weight:bold;">class</span> ListRenderer</p>
<p>&nbsp; attr_reader :root, :depth, :buffer, :builder</p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># pass in the root node of the menu you&#8217;re trying to render</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>root<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @buffer = &#8216;&#8217;<br />
&nbsp; &nbsp; @builder = Builder::XmlMarkup.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>:target =&gt; @buffer, :indent=&gt;<span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @root = root<br />
&nbsp; &nbsp; @depth = <span style="color:#006666;">0</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># output HTML &#8212; skips root!</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> render<br />
&nbsp; &nbsp; render_children @root<br />
&nbsp; &nbsp; @builder.<span style="color:#9900CC;">target</span>!<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; private<br />
&nbsp; <span style="color:#008000; font-style:italic;"># render a single node, recursively render its children</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> render_node<span style="color:#006600; font-weight:bold;">&#40;</span>node<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; attr = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; @builder.<span style="color:#9900CC;">li</span><span style="color:#006600; font-weight:bold;">&#40;</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |xml|<br />
&nbsp; &nbsp; &nbsp; xml.<span style="color:#9900CC;">a</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{node.label}&quot;</span>, :href=&gt;node.<span style="color:#9900CC;">url</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; render_children node<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># render children</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> render_children<span style="color:#006600; font-weight:bold;">&#40;</span>node<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># now descents down the children and do the same</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">if</span> node.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">length</span> == <span style="color:#006666;">0</span><br />
&nbsp; &nbsp; @builder.<span style="color:#9900CC;">ul</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; node.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |child| render_node<span style="color:#006600; font-weight:bold;">&#40;</span>child<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>Finally, we have the implementation of the DSL constructs, which in this case consists of: a class <t>Creator</t> which holds a reference to the node being created, and itself implements the <t>item</t> operation; the method <t>menu</t> for creating a menu, and the method <t>render</t> for rendering a menu. </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868c01b1">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868c01b1').style.display='block';document.getElementById('plain_synthi_4827a868c01b1').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class Creator
  def initialize(menu)
    @menu = menu
  end

  def item(sym, url='', name='', &#038;block)
    nextnode = @menu.add_node(sym,url,name)
    if block_given?
      foo = Creater.new(nextnode)
      foo.instance_eval(&#038;block)
    end
  end
end

def menu(sym=:root, name='root', &#038;block)
  nm = Node.new(sym, name)
  creator = Creator.new(nm)
  creator.instance_eval &#038;block
  return nm
end

def render(menu)
  puts ListRenderer.new(menu).render
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868c01b1">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868c01b1').style.display='block';document.getElementById('styled_synthi_4827a868c01b1').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Creator <br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>menu<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @menu = menu<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> item<span style="color:#006600; font-weight:bold;">&#40;</span>sym, url='&#8217;, name='&#8217;, &amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; nextnode = @menu.<span style="color:#9900CC;">add_node</span><span style="color:#006600; font-weight:bold;">&#40;</span>sym,url,name<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> block_given?<br />
&nbsp; &nbsp; &nbsp; foo = Creater.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>nextnode<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; foo.<span style="color:#9900CC;">instance_eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>&amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">def</span> menu<span style="color:#006600; font-weight:bold;">&#40;</span>sym=:root, name=&#8217;root&#8217;, &amp;block<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; nm = Node.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>sym, name<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; creator = Creator.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>nm<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; creator.<span style="color:#9900CC;">instance_eval</span> &amp;block<br />
&nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> nm<br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">def</span> render<span style="color:#006600; font-weight:bold;">&#40;</span>menu<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> ListRenderer.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>menu<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">render</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>The main reason this approach is better than the first approach is that it enables more reuse. The model can serve as the basis of this reuse. In the next implementation, we will use the same model to generate Java code which calls to Java&#8217;s Swing library to generate our menu. Neither the DSL implementation, the DSL code, nor the model code needs to change to accommodate this new feature (apart from changing the call to render).</p>
<h4>3. Implementation via Model and Generator: Program → Model → Artifacts → Actions</h4>
<p>In this example, we take the existing DSL and its implementation and generate Java code to build a menu using Java&#8217;s Swing library. The main point to observe is that neither the DSL implementation, nor the model need change; we simply add another class which traverses the model to spit out Java rather than HTML. We have now entered the world of <i>generators</i>, also called <i>code generators</i>, not to be confused with code generation in a compiler back-end compiler.</p>
<p>Before presenting the generator we need to think about what code it will produce. A good approach to doing this is to first write the desired code for a small example, such as for our example menu. One can then apply techniques which we&#8217;ll dub <a href="http://littlelanguages.net/blog/patterns-and-refactoring-for-code-generation/"><i>refactorization for code generation</i></a> to construct the generator.</p>
<p>Here is the Java code we anticipate the generator will output for our example menu: </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868c76e0">
<div class="synthi_header" style="font-weight:bold;"> Java <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868c76e0').style.display='block';document.getElementById('plain_synthi_4827a868c76e0').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
import javax.swing.*;

public class MenuGen {
  public static void addMenu(JFrame frame) {
    JMenuBar menuBar;
    JMenu menu, submenu;
    JMenuItem menuItem;

    menuBar = new JMenuBar();

    menu = new JMenu(&#034;Root&#034;);
    menuBar.add(menu);

    menuItem = new JMenuItem(&#034;Questions&#034;);
    menu.add(menuItem);

    menuItem = new JMenuItem(&#034;Answers&#034;);
    menu.add(menuItem);

    submenu = new JMenu(&#034;Letters&#034;);
    menu.add(submenu);

    menuItem = new JMenuItem(&#034;To Bill&#034;);
    submenu.add(menuItem);

    menuItem = new JMenuItem(&#034;To Steve&#034;);
    submenu.add(menuItem);

    frame.setJMenuBar(theJMenuBar);
  }
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868c76e0">
<div class="synthi_header" style="font-weight:bold;"> Java <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868c76e0').style.display='block';document.getElementById('styled_synthi_4827a868c76e0').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="java" style="font-family: monospace;"><span style="color: #a1a100;">import javax.swing.*;</span></p>
<p><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MenuGen <span style="color: #66cc66;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #993333;">void</span> addMenu<span style="color: #66cc66;">&#40;</span><a href="http://www.google.com/search?q=allinurl%3AJFrame+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JFrame</span></a> frame<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.google.com/search?q=allinurl%3AJMenuBar+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuBar</span></a> menuBar;<br />
&nbsp; &nbsp; <a href="http://www.google.com/search?q=allinurl%3AJMenu+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenu</span></a> menu, submenu;<br />
&nbsp; &nbsp; <a href="http://www.google.com/search?q=allinurl%3AJMenuItem+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuItem</span></a> menuItem;</p>
<p>&nbsp; &nbsp; menuBar = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenuBar+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuBar</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; menu = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenu+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenu</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Root&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; menuBar.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>menu<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; menuItem = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenuItem+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuItem</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Questions&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; menu.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>menuItem<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; menuItem = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenuItem+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuItem</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Answers&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; menu.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>menuItem<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; submenu = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenu+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenu</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Letters&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; menu.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>submenu<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; menuItem = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenuItem+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuItem</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;To Bill&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; submenu.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>menuItem<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; menuItem = <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=allinurl%3AJMenuItem+java.sun.com&amp;bntl=1"><span style="color: #aaaadd; font-weight: bold;">JMenuItem</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;To Steve&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; submenu.<span style="color: #006600;">add</span><span style="color: #66cc66;">&#40;</span>menuItem<span style="color: #66cc66;">&#41;</span>;</p>
<p>&nbsp; &nbsp; frame.<span style="color: #006600;">setJMenuBar</span><span style="color: #66cc66;">&#40;</span>theJMenuBar<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div>
</div>
<p>Code generators are typically written based on a domain model, although the model need not be formally or explicitly developed; it may be purely a mental model. The model is constructed used what&#8217;s called <i>domain analysis</i>. This is a topic for future entries, but the key techniques we wish to point out now is <i>commonality/variability analysis</i>. This analysis helps determine which parts of a model, or, in our case, code, remain constant and which parts vary. Typically, the variation points are features which are represented in DSL programs and the constant parts are present in the framework which underlies the DSL implementation. </p>
<p>The same idea applies to our code generation implementation. We need to work out which parts of the above code are constant and which vary. You could print out the code and use a highlighter to get a rough general idea. We can then attack the code either top-down (from the package/class level inwards) or bottom-up (starting from inside methods, working out to classes), with the aim of writing Ruby code which will generate the Java code.</p>
<p>Starting from the top, we identify a Java package, some import statements, and the start and finish of the method <t>addMenu</t>, the workhorse, as being pretty much fixed. The following Ruby method simply outputs this code as a string, making a call in the middle to a method <t>render</t>, which will generate the code which varies for each menu.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868daf5d">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868daf5d').style.display='block';document.getElementById('plain_synthi_4827a868daf5d').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class JavaMenuGenerator
  def generate_class
    puts %(
    import javax.swing.*;

    public class MenuGen {
      public static void addMenu(JFrame frame) {
        JMenuBar menuBar;
        JMenuItem menuItem;
        menuBar = new JMenuBar();
    )
    # renders the model
    render &#034;menuBar&#034;, @root
    puts %(
        frame.setJMenuBar(theJMenuBar);
      }
    }
    )
  end
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868daf5d">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868daf5d').style.display='block';document.getElementById('styled_synthi_4827a868daf5d').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> JavaMenuGenerator<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> generate_class<br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> %<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; import javax.<span style="color:#9900CC;">swing</span>.<span style="color:#9900CC;">*</span>;</p>
<p>&nbsp; &nbsp; public <span style="color:#9966CC; font-weight:bold;">class</span> MenuGen <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; public static void addMenu<span style="color:#006600; font-weight:bold;">&#40;</span>JFrame frame<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; JMenuBar menuBar;<br />
&nbsp; &nbsp; &nbsp; &nbsp; JMenuItem menuItem;<br />
&nbsp; &nbsp; &nbsp; &nbsp; menuBar = new JMenuBar<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># renders the model</span><br />
&nbsp; &nbsp; render <span style="color:#996600;">&quot;menuBar&quot;</span>, @root<br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> %<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; frame.<span style="color:#9900CC;">setJMenuBar</span><span style="color:#006600; font-weight:bold;">&#40;</span>theJMenuBar<span style="color:#006600; font-weight:bold;">&#41;</span>;&nbsp;&nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>A more serious implementation would endeavor to pretty-print the generated code, which is important for both debugging the generator and using the generated code.<br />
Now it&#8217;s time to start thinking bottom-up. As we already know, there are two basic elements:<br />
<i>menus</i> and <i>items</i>. Let&#8217;s write a method to generate each of these. We also write a generic <t>render</t> method which determines whether a particular node is a menu or an item based on the number of children it has.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868dfd7d">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868dfd7d').style.display='block';document.getElementById('plain_synthi_4827a868dfd7d').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class JavaMenuGenerator
  def menu(parent, label, children)
    target = genvar
    puts &#034;JMenu #{target} = new JMenu(&#034;#{label}&#034;);&#034;
    puts &#034;#{parent}.add(#{target});&#034;
    children.each { |c| render target, c }
  end

  def item(target, label)
    puts %(
      menuItem = new JMenuItem(&#034;#{label}&#034;);
      #{target}.add(menuItem);
    )
  end

  def render(parent, node)
    if node.children.length == 0 then
      item parent, node.label
    else
      menu parent, node.label, node.children
    end
  end
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868dfd7d">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868dfd7d').style.display='block';document.getElementById('styled_synthi_4827a868dfd7d').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> JavaMenuGenerator<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> menu<span style="color:#006600; font-weight:bold;">&#40;</span>parent, label, children<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; target = genvar<br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;JMenu #{target} = new JMenu(<span style="color:#000099;">\&quot;</span>#{label}<span style="color:#000099;">\&quot;</span>);&quot;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{parent}.add(#{target});&quot;</span><br />
&nbsp; &nbsp; children.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |c| render target, c <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> item<span style="color:#006600; font-weight:bold;">&#40;</span>target, label<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> %<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; menuItem = new JMenuItem<span style="color:#006600; font-weight:bold;">&#40;</span>\<span style="color:#996600;">&quot;#{label}<span style="color:#000099;">\&quot;</span>);<br />
&nbsp; &nbsp; &nbsp; #{target}.add(menuItem);<br />
&nbsp; &nbsp; )<br />
&nbsp; end</p>
<p>&nbsp; def render(parent, node)<br />
&nbsp; &nbsp; if node.children.length == 0 then <br />
&nbsp; &nbsp; &nbsp; item parent, node.label<br />
&nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; menu parent, node.label, node.children<br />
&nbsp; &nbsp; end<br />
&nbsp; end<br />
end </span></div>
</div>
<p>The <t>render</t> method also forms a bridge between this code and the constant code, to loosen the coupling between the two parts of the code generator.</p>
<p>Finally, here&#8217;s the remainder of the code which initializes a <t>JavaMenuGenerator</t> object with particular <t>Node</t>:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868e4b9c">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868e4b9c').style.display='block';document.getElementById('plain_synthi_4827a868e4b9c').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
class JavaMenuGenerator
  attr_reader :root

  # pass in the root node of the menu you're trying to render
  def initialize(root)
    @root = root
    @varid = 0
  end

  # generate new variable names
  def genvar
    @varid += 1
    &#034;var#{@varid}&#034;
  end
end
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868e4b9c">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868e4b9c').style.display='block';document.getElementById('styled_synthi_4827a868e4b9c').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> JavaMenuGenerator&nbsp; <br />
&nbsp; attr_reader :root<br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color:#008000; font-style:italic;"># pass in the root node of the menu you&#8217;re trying to render</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>root<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @root = root<br />
&nbsp; &nbsp; @varid = <span style="color:#006666;">0</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#008000; font-style:italic;"># generate new variable names</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> genvar<br />
&nbsp; &nbsp; @varid += <span style="color:#006666;">1</span><br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;var#{@varid}&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
<p>After creating a menu, the following call generates the Java code:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4827a868e99bb">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4827a868e99bb').style.display='block';document.getElementById('plain_synthi_4827a868e99bb').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
JavaMenuGenerator.new(mymenu).generate_class
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4827a868e99bb">
<div class="synthi_header" style="font-weight:bold;"> Ruby <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4827a868e99bb').style.display='block';document.getElementById('styled_synthi_4827a868e99bb').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="ruby" style="font-family: monospace;">JavaMenuGenerator.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>mymenu<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">generate_class</span></div>
</div>
<p>It&#8217;s a simple task for the reader to hide this behind a more DSL-like call.</p>
<p>If you run this code, you&#8217;ll notice that it doesn&#8217;t produce exactly the code that we initially wrote. This is because some simple changes were made along the way to make the code generator easier to write. </p>
<p>Now we have written two generators for the same model. Both generators are not exactly the same, but they have much in common. As pragmatic programmers, we would want to make this code DRY-er to avoid any duplication. The Visitor pattern or some variation on in would certainly come in handy here.</p>
<h4>Final Words (Finally)</h4>
<p>We&#8217;ve covered a lot of ground in this entry, and we&#8217;ve employed one very basic technique for writing DSLs in Ruby. Other techniques are possible, but we&#8217;ll explore these at another time. (Also look at the comment from Justin for a potential pitfall with the approach we&#8217;ve taken.) One lesson to take away is that DSL design and implementation goes well beyond simply writing some methods which have an English like appearance. A lot more code is written to support the DSL. The DSL process works is most effective when you have a clear notion of what your domain model is.</p>
<h4>Credits</h4>
<p>Jeroen Houben of Lost Boys posed this simple challenge and wrote the initial version of the code.</p>
]]></content:encoded>
			<wfw:commentRSS>http://littlelanguages.net/blog/2006/09/15/example-mini-language-menubuilder/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>The Setting for DSL Development</title>
		<link>http://littlelanguages.net/blog/2006/09/01/the-setting-for-dsl-development/</link>
		<comments>http://littlelanguages.net/blog/2006/09/01/the-setting-for-dsl-development/#comments</comments>
		<pubDate>Fri, 01 Sep 2006 16:26:38 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
	<category>dsl</category>
	<category>rant</category>
		<guid isPermaLink="false">http://littlelanguages.net/blog/2006/09/01/the-setting-for-dsl-development/</guid>
		<description><![CDATA[Domain Specific Languages are typically implemented in the following phases, although some phases may be omitted or joined with others:

    Program --> Model --> Artifacts --> Actions

The various components are:

a program written in the concrete syntax of the DSL;
a model which captures the underlying interpretation of the program, possibly as some form [...]]]></description>
			<content:encoded><![CDATA[<p>Domain Specific Languages are typically implemented in the following phases, although some phases may be omitted or joined with others:</p>
<pre>
    Program --> Model --> Artifacts --> Actions
</pre>
<p>The various components are:</p>
<ol>
<li>a <b>program</b> written in the concrete syntax of the DSL;</li>
<li>a <b>model</b> which captures the underlying interpretation of the program, possibly as some form of annotated abstract syntax tree, generally decorated with semantic information gained from analyzing the program;
</li>
<li>a number of <b>artifacts</b> such as classes, libraries, objects, database entries/tables, binaries, programs, configuration files, documentation, web pages, and so forth which are generated based from the model; and</li>
<li>some <b>actions</b> which are the resulting behaviour of the DSL, which could include parsing a particular kind of data stream, playing a sequence of sounds, transforming an XML document, or what have you.</li>
</ol>
<p>The phases proceed as follows:</p>
<h4>Program → Model</h4>
<p>Standard compiler technology (lexing, parsing, semantic analysis) converts a program in an <i>external DSL</i> into its abstract model. <i>Internal (or embedded) DSLs</i> are evaluated and part of their execution involves semantic checks and the construction of the underlying model.</p>
<h4>Model → Artifacts</h4>
<p>Generative programming techniques (meta-programming, templating, &#8220;code generation&#8221;, program transformation) convert the model into executable code, web pages, documentation, etc. More dynamic approaches convert the model into objects, modify the structure of running classes and objects, instantiate components, and so forth.</p>
<p>Czarnecki and Eisenecker&#8217;s book <i>Generative Programming: Methods, Tools and Applications</i> covers these techniques in details, mostly in the context of C++. </p>
<h4>Artifacts → Actions</h4>
<p>The final step is often the simplest, given that all the code/objects have been set up. These artifacts are incorporated into some program or run standalone, all we need do is run the code.</p>
<p>Sometimes this phase may not be as simple as this, because the generated artifacts need to be integrated into existing code. This is often difficult because the generated code may have complex interfaces which are not  apparent from the DSL program. Issues of integration testing arise here, especially when the DSL program is changing.</p>
<h4>Variations</h4>
<p>All of the steps just described are not necessarily employed.  Sometimes different phases are integrated or are totally omitted.</p>
<p>For example, it is often the case that when either XML, JSON or YAML is used, the program and the model coincide. Examples include various XML configuration files (often touted as DSLs), Ant, and so-called <a href="http://citeseer.ist.psu.edu/113798.html">Jargons</a>, which incidentally pre-date XML. Sometimes the model is an elaborated version of the program.</p>
<p>The model is often omitted when the language is simple, or provides a one-off effect. Some of the DSL-like features in Ruby on Rail&#8217;s ActiveRecord are like this. In this case, evalutating the embedded DSL program directly modifies the class structure using reflection and meta-programming.</p>
<p>Often no artifacts are generated, when a language can be interpreted directly into actions. Jargons  adopt this approach explicitly as a part of its methodology by advocating the use of syntax-directed translators which apply to the model.</p>
<h4>Models</h4>
<p>A number of advantages can be argued for explicitly including a model in a DSL implementation, just as different but related advantages to separating the program syntax and the model exist.</p>
<p>The advantage of using a separate language syntax, as opposed to using a representation of the model directly, is that languages can be designed to more concisely reflect domain knowledge, often in a manner which is familiar to domain experts. This means that the domain knowledge embedded in the program is directly accessible to and modifiable by the domain experts.</p>
<p>The advantage of using a model is the domain knowledge encoded in the model can be more readily reused. For example, from a PADS description, not only is a parser generated, but also a statistics collection engine and other tools. Without a model, these tools would need to derive directly from the language, which typically would clutter the language processor&#8217;s implementation. With a separate model, multiple interpreters can traverse it and produce different artifacts without affecting the initial processing phase.</p>
<p>The main advantage of keeping a model separate is that it enables the reuse of domain knowledge. This is important because <i>domain knowledge is an extremely valuable asset.</i></p>
]]></content:encoded>
			<wfw:commentRSS>http://littlelanguages.net/blog/2006/09/01/the-setting-for-dsl-development/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Vacation Time</title>
		<link>http://littlelanguages.net/blog/2006/07/28/vacation-time/</link>
		<comments>http://littlelanguages.net/blog/2006/07/28/vacation-time/#comments</comments>
		<pubDate>Fri, 28 Jul 2006 13:25:17 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
	<category>Uncategorized</category>
		<guid isPermaLink="false">http://littlelanguages.net/blog/2006/07/28/vacation-time/</guid>
		<description><![CDATA[Just as you people out there discovered our littlelanguages blog, it&#8217;s time to go on vacation. We certainly plan to be more active after we get back. But with Tobias finishing his PhD thesis and then vanishing into a well deserved oblivion for a while, and me finishing of all the things that need to [...]]]></description>
			<content:encoded><![CDATA[<p>Just as you people out there discovered our littlelanguages blog, it&#8217;s time to go on vacation. We certainly plan to be more active after we get back. But with Tobias finishing his PhD thesis and then vanishing into a well deserved oblivion for a while, and me finishing of all the things that need to be finished off before I go to Mexico, well, there just hasn&#8217;t been much time.</p>
<p>Please keep commenting. Please keep sending links. Even write a little article if you want. Community support is what will help make this a great little blog.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://littlelanguages.net/blog/2006/07/28/vacation-time/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Research Position in DSLs</title>
		<link>http://littlelanguages.net/blog/2006/06/26/research-position-in-dsls/</link>
		<comments>http://littlelanguages.net/blog/2006/06/26/research-position-in-dsls/#comments</comments>
		<pubDate>Mon, 26 Jun 2006 12:09:31 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
	<category>job</category>
		<guid isPermaLink="false">http://littlelanguages.net/blog/2006/06/26/research-position-in-dsls/</guid>
		<description><![CDATA[Eelco Visser, developer of the Stratego program transformation language, has a research position available for either a post-doc or PhD student. 
The project is called Transformations for Abstractions and the topic it addresses lies at the intersection generative programming, wherein programs are produced via automatic transformation, and domain-specific programming, wherein application specific abstractions concepts and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cs.uu.nl/wiki/Visser">Eelco Visser</a>, developer of the <a href="http://www.stratego-language.org">Stratego</a> program transformation language, has a research position available for either a post-doc or PhD student. </p>
<p>The project is called <a href="http://www.cs.uu.nl/wiki/Visser/TFA"><b>Transformations for Abstractions</b></a> and the topic it addresses lies at the intersection generative programming, wherein programs are produced via automatic transformation, and domain-specific programming, wherein application specific abstractions concepts and notations are directly supported in programming languages. The idea is to incorporate domain-specific notions in general purpose languages, and then compile them away using program transformation techniques, in particular, using the <a href="http://www.stratego-language.org">Stratego/XT</a> toolset.</p>
<p>If was not otherwise employed, I&#8217;d consider applying for the position myself.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://littlelanguages.net/blog/2006/06/26/research-position-in-dsls/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>World.hello();</title>
		<link>http://littlelanguages.net/blog/2006/06/08/worldhello/</link>
		<comments>http://littlelanguages.net/blog/2006/06/08/worldhello/#comments</comments>
		<pubDate>Thu, 08 Jun 2006 13:50:26 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
	<category>dsl</category>
	<category>rant</category>
		<guid isPermaLink="false">http://littlelanguages.net/blog/2006/06/08/worldhello/</guid>
		<description><![CDATA[A Domain Specific Language (DSL), or &#8220;little language&#8221;, is designed to solve a specific sort of task well, in contrast to General Purpose Languages like Java or Python that want to take on the world. DSLs aim to increase programmer productivity by raising the level of abstraction at which programs are written and to even [...]]]></description>
			<content:encoded><![CDATA[<p>A Domain Specific Language (DSL), or &#8220;little language&#8221;, is designed to solve a specific sort of task well, in contrast to General Purpose Languages like Java or Python that want to take on the world. DSLs aim to increase programmer productivity by raising the level of abstraction at which programs are written and to even allow domain experts with little programming training  to write and understand programs. Programs written in a DSL exploit domain notations to directly express domain concepts. The advantage can be as dramatic as a 50 times reduction in the size of the code required. </p>
<p>The advantages of DSLs come not without cost: the development time required to design and build a DSL may be prohibitive. The expertise required to develop DSLs is expensive as the skills required are uncommon, often requiring compiler construction skills hand in hand with comprehensive domain understanding. </p>
<p>Programming languages such as Ruby, Python, Haskell and LISP enable the somewhat easier construction of internal DSLs, those which embed domain constructs within a programming language. These languages often use features such as metaprogramming, macros, templates, type-classes, and so forth to implement the embedded DSL features.</p>
<p>DSLs have been around since the dawn of Unix, which was home to &#8220;little languages&#8221; such as make, pic, lex, yacc, troff etc. Recently, DSLs have broken into the collective consciousness otherwise known as the blogsphere. The interest within the blogsphere of developing internal DSLs in Ruby is particularly vivid (spurred by the popularity of Rails). This is no surprise, as Ruby offers both powerful metaprogramming facilities and palatable syntax, making it suitable for writing DSLs.</p>
<p>Here&#8217;s where the &#8220;Fistful of Languages&#8221; blog comes in. This blog aims to address all aspects of DSL development, focussing particularly on DSLs embedded in Ruby.</p>
<p>Dave &#038; Tobias
</p>
]]></content:encoded>
			<wfw:commentRSS>http://littlelanguages.net/blog/2006/06/08/worldhello/feed/</wfw:commentRSS>
		</item>
	</channel>
</rss>
