tag:blogger.com,1999:blog-67398926438409434272024-03-29T00:30:03.524-03:00Uqbar ProjectAnonymoushttp://www.blogger.com/profile/02417806265487074597noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-6739892643840943427.post-87472012389411698242017-08-31T23:56:00.000-03:002017-08-31T23:56:58.171-03:00¿Programar sin saber el problema que quiero resolver?<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Muchas veces, en las clases de programación, nos encuentro a los profes haciendo mucho énfasis en que los alumnos "entiendan el problema" antes de comenzar a programar. Al escribir esto, imagino que muchos, posiblemente la mayoría, de mis lectores habrán pensado: "¡Obvio!". </span></span><br />
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Sin embargo, yo miro mi trabajo profesional y la verdad es que no funciona tan así, y no creo que eso sea porque lo hacemos mal. Muy por el contrario, muchas veces eso pasa <i>justamente </i>porque estamos trabajando bien, no es un error metodológico, es un <i>feature</i> de nuestra metodología de desarrollo.</span></span><br />
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;"><br /></span></span>
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">¿Cómo es eso? Bueno, para empezar busquemos un poco de equilibrio en nuestra afirmación. Por supuesto que uno tiene que tener <i>una idea</i> de lo que quiere hacer, y por supuesto que como profes frecuentemente nos encontramos en situaciones en las que le queremos pedir al estudiante que c fa tome un tiempo para entender antes de lanzarse a escribir código. Sí, pero... ¡hasta ahí!</span></span><br />
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;"><br /></span></span>
<span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Y aunque tal vez parece <i>demodé</i> discutir esto a 16 años de la publicación del manifiesto ágil, yo creo que seguimos teniendo una</span><span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;"> contradicción grande frente a nosotros. </span></span><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Imagino que si yo digo que eso es pensar en </span><i style="font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">cascada</i><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">, a muchos les parecerá anacrónico, nadie piensa ya en desarrollar software en cascada. Los más jóvenes ni saben de lo que estoy hablando. Pero al mismo tiempo, imagino que a muchos (¡todavía!) les da urticaria si escuchan a alguien decir que programa sin entender bien el problema que quiere resolver o que se mandó a codear sin tener un diseño en mente... es que en algunas prácticas, en algunos discursos, en muchos vicios todavía persiste la idea de tener "</span><b style="font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">el análisis primero</b><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">".</span><br />
<span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;"><br /></span>
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">En un desarrollo profesional, no suele pasar que viene alguien con un enunciado inmutable de lo que hay que hacer, como pasa en un parcial. Al contrario, nuestro <i>product owner</i> va puliendo el concepto del producto a medida que avanza el proyecto: se construye una etapa, se enfrenta a los usuarios con estas ideas, se mide el uso, y se toman decisiones que pueden cambiar lo que se hizo antes. A menudo pasa que los programadores negociamos con el product owner, por ejemplo proponiendo alternativas que son más fáciles de desarrollar. </span></span><br />
<span style="font-family: Roboto Slab, Times New Roman, serif;"><span style="background-color: #fafafa; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Y si bien muy posiblemente es quien conoce el dominio, los potenciales usuarios y sus problemas quien guía la definición de qué es lo que queremos del producto, nunca lo hace de manera unidireccional, viendo al resto del equipo de desarrollo como una caja negra que convierte sus especificaciones en software funcionando. En cambio, la definición final del rumbo surge de un proceso interactivo, multidisciplinar, en la que intervienen personas con diferentes visiones y conocimientos: </span></span><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">dominio del problema, </span><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">tecnología (que no es sólo programación), </span><i style="font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">user experience, </i><span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">etc.</span><br />
<span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;"><br /></span>
<span style="background-color: #fafafa; font-family: "Roboto Slab", "Times New Roman", serif; font-size: 14px; font-variant-ligatures: none; white-space: pre-wrap;">Sí, lo sé. Nada nuevo bajo el sol. ¿O sí? ¿Será que ya esos conceptos cascadosos ya están olvidados? ¿O nos sigue pasando que debajo de los nombres nuevos seguimos pensando el desarrollo de software como una cadena de montaje?</span><br />
<br />Anonymoushttp://www.blogger.com/profile/07208836305757129696noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-78676038841539687952015-07-18T01:04:00.001-03:002015-07-18T01:05:53.468-03:00Wisit15 - Proponé tu charla<div class="row" style="box-sizing: border-box; margin-left: -15px; margin-right: -15px;">
<div class="col-md-6" style="box-sizing: border-box; float: left; min-height: 1px; padding-left: 15px; padding-right: 15px; position: relative; width: 480px;">
<ul class="tracks" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Open Sans Condensed', sans-serif; font-size: 14px; line-height: 20px; margin-bottom: 10px; margin-top: 0px;"></ul>
<h2>
<span style="color: blue;">Wisit15 - 19 de septiembre - Universidad de Quilmes</span></h2>
<div>
<span style="color: blue;">Se reciben propuestas de charlas y trabajos para presentar en el Workshop</span></div>
<ul class="tracks" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Open Sans Condensed', sans-serif; font-size: 14px; line-height: 20px; margin-bottom: 10px; margin-top: 0px;"><h3 style="box-sizing: border-box; color: #5c90bf; font-size: 2em; font-weight: 500; line-height: 1.1; margin-bottom: 0.2em; margin-top: 0.6em; text-transform: uppercase;">
<li style="box-sizing: border-box;">TRACK INVESTIGACIÓN</li>
</h3>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
Trabajos científicos que tengan como objetivo mejorar la forma en que desarrollamos software o formamos nuevos profesionales, favoreciendo la interacción entre el ámbito académico y el industrial.</div>
<div class="center" style="box-sizing: content-box; margin-left: auto; margin-right: auto; text-align: center;">
<a class="boton" href="http://wisit15.uqbar.org/propone/research.html" style="background: rgb(92, 144, 191); border-radius: 0.75em; box-shadow: rgba(0, 0, 0, 0.34902) 0.125em 0.2165em 0px 0px; box-sizing: border-box; color: white; font-size: 1.4em; margin: 0.5em auto; padding: 0px 1em; text-decoration: none; text-transform: uppercase;">MÁS INFO</a></div>
</ul>
</div>
<div class="col-md-6" style="background-color: white; box-sizing: border-box; color: #333333; float: left; font-family: 'Open Sans Condensed', sans-serif; font-size: 14px; line-height: 20px; min-height: 1px; padding-left: 15px; padding-right: 15px; position: relative; width: 480px;">
<ul class="tracks" style="box-sizing: border-box; margin-bottom: 10px; margin-top: 0px;"><h3 style="box-sizing: border-box; color: #5c90bf; font-size: 2em; font-weight: 500; line-height: 1.1; margin-bottom: 0.2em; margin-top: 0.6em; text-transform: uppercase;">
<li style="box-sizing: border-box;">TRACK EXPERIENCIAS</li>
</h3>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
Exposiciones sobre experiencias concretas en la aplicación de tecnologías y metodologías innovadoras en el ámbito industrial y docente.</div>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
Enviá tu propuesta a <a href="mailto:info@uqbar.org" style="background: transparent; box-sizing: border-box; color: #428bca; text-decoration: none;">info@uqbar.org</a></div>
</ul>
</div>
</div>
<div class="row" style="background-color: white; box-sizing: border-box; color: #333333; font-family: 'Open Sans Condensed', sans-serif; font-size: 14px; line-height: 20px; margin-left: -15px; margin-right: -15px;">
<div class="col-md-6" style="box-sizing: border-box; float: left; min-height: 1px; padding-left: 15px; padding-right: 15px; position: relative; width: 480px;">
<ul class="tracks" style="box-sizing: border-box; margin-bottom: 10px; margin-top: 0px;"><h3 style="box-sizing: border-box; color: #5c90bf; font-size: 2em; font-weight: 500; line-height: 1.1; margin-bottom: 0.2em; margin-top: 0.6em; text-transform: uppercase;">
<li style="box-sizing: border-box;">HANDS ON</li>
</h3>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
¿Estás utilizando en una tecnología innovadora? ¿Te animás enseñarnos a dar los primeros pasos en un par de horas?</div>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
Enviá tu propuesta a <a href="mailto:info@uqbar.org" style="background: transparent; box-sizing: border-box; color: #428bca; text-decoration: none;">info@uqbar.org</a></div>
</ul>
</div>
<div class="col-md-6" style="box-sizing: border-box; float: left; min-height: 1px; padding-left: 15px; padding-right: 15px; position: relative; width: 480px;">
<ul class="tracks" style="box-sizing: border-box; margin-bottom: 10px; margin-top: 0px;"><h3 style="box-sizing: border-box; color: #5c90bf; font-size: 2em; font-weight: 500; line-height: 1.1; margin-bottom: 0.2em; margin-top: 0.6em; text-transform: uppercase;">
<li style="box-sizing: border-box;">MOSTRÁ TU PROYECTO</li>
</h3>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
¿Estás trabajando en un proyecto novedoso? ¡Vení y contanos tus ideas!</div>
<div style="box-sizing: border-box; color: #5b5b5f; font-size: 1.3em; margin-bottom: 10px;">
No se requiere inscripción previa, acercate con tu propuesta el día de la conferencia. En caso de dudas mandá tu consulta a <a href="mailto:info@uqbar.org" style="background: transparent; box-sizing: border-box; color: #428bca; text-decoration: none;">info@uqbar.org</a></div>
</ul>
</div>
</div>
Lucas Spigariolhttp://www.blogger.com/profile/15615574267218290352noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-71391888791964047682015-06-06T00:43:00.000-03:002015-06-06T12:11:11.185-03:00Tutorial: Language Development with XText: A Logo example - Part III: The InterpreterIn the <b>first post</b> of this tutorial series we have introduced a little bit xtext and discussed in general the different approach for implementing the <b>runtime</b> part of your language.<br />
<br />
In this post we will show an example Interpreter for the Logo language, for which we have already seen its set of instructions and its xtext grammar in the <b>second post</b>.<br />
<br />
So now we will see the interpreter's code.<br />
<br />
But before that<br />
<br />
<h2>
Overview of the Logo Semantic Model</h2>
<div>
Lets analyse a little bit what's a logo program once it has been parsed and validated and then the semantic model instances are created.</div>
<div>
For that it's useful to understand the classes XText generated.<br />
<br />
Here's a full class diagram of the semantic model.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikzrh_V0idX7a2kUz1Qk0LyR05ddzFJXsYukFRMoBLL9OSJiRXAS7i57CatlFhtYx7zIyhvJvPAZepIxhnNtKI4uyKR9jZpGVBQQKj1MhaS-qZodJJUBG30j7vpbGv38hJ6S6kQze3COE/s1600/tortuga-sem-model.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikzrh_V0idX7a2kUz1Qk0LyR05ddzFJXsYukFRMoBLL9OSJiRXAS7i57CatlFhtYx7zIyhvJvPAZepIxhnNtKI4uyKR9jZpGVBQQKj1MhaS-qZodJJUBG30j7vpbGv38hJ6S6kQze3COE/s640/tortuga-sem-model.png" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
The root element is the TortugaProgram (the first grammar rule).</div>
<div>
A program has a list of SENTENCES (grr.. to comply with the syntax we defined rules that are uppercased and now they just don't follow the standard java class names).</div>
<div>
<br /></div>
<div>
Then there are a couple of different SENTENCES like REPEAT, IF, MAKE, etc.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<h2>
The Interpreter</h2>
</div>
<h3>
What's an interpreter ?</h3>
<div>
In its simplest way, an interpreter for an XText language is just a class that, given an input file:</div>
<div>
<ol>
<li>Calls XText so that it parses the file (validating and linking) and returns back an instance of the root model (TortugaProgram in our case)</li>
<li>Then does something with those objects</li>
</ol>
<div>
It could be a simple class with a Main. </div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">class</span> MyInterpreter {</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">static</span> <span style="color: #931a68;">void</span> main(String[] args) {</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="color: #931a68;">val</span><span style="color: black;"> fileName = </span>args.<span style="color: #bb4300;">get</span>(<span style="color: #909090;">0</span>)</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> uri = URI.createURI(fileName)</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> injector = <span style="color: #931a68;">new</span> MyDslStandaloneSetup().<span style="text-decoration: underline;">createInjectorAndDoEMFRegistration</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> resourceSet = injector.getInstance(XtextResourceSet)</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> resource = resourceSet.createResource(uri)</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>resource.load(#{})</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> model = resource.contents.get(<span style="color: #909090;">0</span>) <span style="color: #931a68;">as</span> MyModel</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">new</span> MyInterpreter().interpret(model)</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span></div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">void</span> interpret(MyModel model) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #4e9072;">// DO SOMETHING HERE ...</span></div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
</div>
<div>
<span style="font-family: Monaco; font-size: 14px;">}</span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Then you could package it along with all its dependencies (that would need a new blog post) and then anyone could use it like:</div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">java -cp .... classpath_here... org.uqbar.tutorial.xtext.MyInterpreter myFile.tortu</span></div>
<div>
<br /></div>
<div>
You could also provide a script to hide away the java command</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">./logo myFile.tortu</span></div>
<div>
<br /></div>
<div>
<h3>
Integrating it into Eclipse</h3>
</div>
<div>
Instead of creating a Main class for headless execution, as the interpreter is just java code, you could integrate it with the Eclipse IDE, so that one can use the text editor for writing code in your language and then just "run" it from the IDE itself.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
This can be done by extending an specific eclipse extension point for launch shortcuts (in case you want to show it as part of the "Run" menu), providing a class, icon, and a filter so that it will only apply for your language file extension.</div>
<div>
<br /></div>
<div>
Here is a sample xml from our plugin.xml</div>
<div>
<br /></div>
<div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><extension</div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;">point=</span>"org.eclipse.debug.ui.launchShortcuts"<span style="color: #011993;">></span></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><shortcut</div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;">class=</span>"org.uqbar.paco.dsl.ui.TortugaDSLExecutableExtensionFactory:org.uqbar.paco.dsl.tortuga.ui.launch.LaunchTortugaShortcut"</div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;">icon=</span>"icons/tortuga.png"</div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;">id=</span>"org.uqbar.paco.dsl.tortuga.ui.launchTortuga"</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">label=</span><span style="color: #008f00;">"Tortuga"</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">modes=</span><span style="color: #008f00;">"run"</span><span style="color: #011993;">></span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
</div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><contextualLaunch></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><enablement></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><with<span style="color: black;"> </span>variable=<span style="color: #008f00;">"selection"</span>></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;"><count</span> <span style="color: #011993;">value=</span><span style="color: #008f00;">"1"</span><span style="color: #011993;">/></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;"><iterate</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">ifEmpty=</span><span style="color: #008f00;">"false"</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">operator=</span><span style="color: #008f00;">"and"</span><span style="color: #011993;">></span></div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;"><adapt</span><span style="color: black;"> </span><span style="color: #011993;">type=</span>"org.eclipse.core.resources.IFile"<span style="color: #011993;">/></span></div>
<div style="color: #008f00; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><span style="color: #011993;"><test</span><span style="color: black;"> </span><span style="color: #011993;">property=</span>"org.eclipse.debug.ui.matchesPattern"</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">value=</span><span style="color: #008f00;">"*.tortu"</span><span style="color: #011993;">/></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;"></iterate></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;"></with></span></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span></enablement></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span><contextLabel</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">mode=</span><span style="color: #008f00;">"run"</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #011993;">label=</span><span style="color: #008f00;">"Run Tortuga"</span><span style="color: #011993;">/></span></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span></contextualLaunch></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span></shortcut></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black;"> </span></extension></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">And then the Launch class has code similar to the main we have seen, but delegates the actual interpreting logic to an interpreter class.</span></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">class</span> LaunchTortugaShortcut <span style="color: #931a68;">implements</span> ILaunchShortcut {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #777777;">@Inject</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">private</span> IResourceForEditorInputFactory <span style="color: #0132ba;">resourceFactory</span>;</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">override</span> launch(ISelection selection, String mode) { }</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">override</span> launch(IEditorPart editor, String mode) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">val</span> input = editor.editorInput</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">if</span> (editor <span style="color: #931a68;">instanceof</span> XtextEditor && input <span style="color: #931a68;">instanceof</span> FileEditorInput) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #931a68;">val</span> resource = <span style="color: #0132ba;">resourceFactory</span>.createResource(input)</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> resource.load(newHashMap())</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #931a68;">val</span> program = resource.contents.<span style="color: #bb4300;">head</span> <span style="color: #931a68;">as</span> TortugaProgram</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #931a68;">new</span> TortugaInterpreter(canvas).exec(program)</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> getCanvas() {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>TortugaView.getInstance.canvas</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="color: #011993; font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
</div>
<div>
<br /></div>
<div>
It basically gets the current editor's file and then calls Xtext to load it, which will do all the parsing and validation.</div>
<div>
With the model parsed into a TortugaProgram, it creates a new TortugaInterpreter and executes the program.</div>
<div>
In our case the interpreter receives a Canvas in which Tortue will paint.</div>
<div>
<br /></div>
<div>
That's all for the skeleton of our interpreter.</div>
<div>
<br /></div>
<h3>
The interpreter itself</h3>
<div>
Now we need to implement the execution (the runtime semantic) for each of the classes of our semantic model.</div>
<div>
<br /></div>
<div>
Let's start from top to down</div>
<div>
<br /></div>
<h4>
Interpreter class and evaluating the root model</h4>
<div>
Interpreting a Logo program would be basically to execute each of its sentences.</div>
<div>
So here's a sample implementation:</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">class</span> TortugaInterpreter {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>TortueCanvas <span style="color: #0132ba;">canvas</span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">new</span>(TortueCanvas canvas) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #931a68;">this</span>.<span style="color: #0132ba;">canvas</span> = canvas;</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> <span style="color: black;">exec(TortugaProgram p) {</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #0132ba;">canvas</span>.newCommand</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> p.sentences.<span style="color: #bb4300;">forEach</span>[s | s.<span style="color: #bb4300;">exec</span> ; <span style="color: #0132ba;">canvas</span>.repaint ]</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #4e9072;">// ******************************</span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>// ** EXECs: here one multi method per SENTENCE CLASS</div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>// ******************************</div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def dispatch</span> exec(...) { ... }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def dispatch</span> exec(...) { ... }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def dispatch</span> exec(...) { ... }</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
</div>
<div>
}</div>
<div>
<br /></div>
<div>
What we see here is that evaluating a TortugaProgram is to:</div>
<div>
<ul>
<li>reset the canvas</li>
<li>evaluate each of the "sentences"</li>
</ul>
<div>
We can see that we are using multiple dispatch methods.</div>
</div>
<div>
This is a pretty cool feature of xtend that is really useful for language interpreters along with extension methods.</div>
<div>
Since we cannot touch the semantic model classes because they are generated, we will use extension methods, to add behaviour to them, and use it as if they were methods on those classes.</div>
<div>
<br /></div>
<div>
The multi methods provides a way to implement polymorphic extension methods.</div>
<div>
In our case all of our EObject (superclass of all the semantic model classes) understand the "exec" message, but each particular class has its own implementation.</div>
<div>
<br /></div>
<div>
Lets start with some easy sentences implementation</div>
<div>
<br /></div>
<h4>
Interpreting Movements (RIGHT, LEFT, FORWARD, etc)</h4>
<div>
So now we just need to implement the "exec()" method for this classes.</div>
<div>
Here it is:</div>
<div>
<br /></div>
<div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
// moves</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(LEFT l) { <span style="color: #0132ba;">canvas</span>.left(l.amount.<span style="color: #bb4300;">evaluate</span>) }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(RIGHT r) { <span style="color: #0132ba;">canvas</span>.right(r.amount.<span style="color: #bb4300;">evaluate</span>) }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(FORWARD f) { </div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #0132ba;"> canvas</span>.forward(f.amount.<span style="color: #bb4300;">evaluate</span>.intValue) </div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(SET_X s) { </div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #0132ba;"> canvas</span>.setX(s.amount.<span style="color: #bb4300;">evaluate</span>.intValue) </div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(SET_Y s) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #0132ba;">canvas</span>.setY(s.amount.<span style="color: #bb4300;">evaluate</span>.intValue) </div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<span style="font-family: Times; font-size: small;">Basically we don't need to do much, since the canvas (</span>instance of TortueCanvas) already has methods for this functionalities.<br />
<br />
So on each type of movement we call a different method.<br />
The interesting part is that <b>we need to evaluate the "amount"</b> field of the movement.<br />
Because it could be a number, but it also could be a variable reference.<br />
So basically <b>we need to pass that object also through the interpreter.</b><br />
<b><br /></b>
<b>This is a pretty common pattern</b>. Probably all attributes of all the semantic class will need to eventually get evaluated by the interpreter.<br />
So it's kind of a recursive pattern.<br />
<br />
Evaluate() here is also an extension methods, with multiple dispatch.<br />
Because different classes behave differently for evaluating them.<br />
<br />
We will get back to evaluate() later.<br />
<br />
<h4>
If and Repeat statements</h4>
<div>
The if statement needs to evaluate its condition, and in case it is true, then execute all of its sentences.</div>
<div>
This is exactly that behaviour in xtend code:</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(^IF bif) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">if</span> (bif.condition.<span style="color: #bb4300;">evalBool</span>) </div>
<div style="font-family: Monaco; font-size: 14px;">
bif.commands.<span style="color: #bb4300;">forEach</span>[c| c.<span style="color: #bb4300;">exec</span> ]</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
</div>
<br />
Again we are adding a "evalBool" method to the boolean condition.<br />
<br />
Notice what's funny here is that this means that the Logo IF statement is implemented using Java/Xtend if statement. Which is obvious, but well, just something to be aware of.<br />
As our interpreter is written in Java/Xtend then your language runtime can rely on already implemented functionality from the JVM, for example garbage collection, and also the stack execution model !<br />
You don't need to write that up from scratch or implement.<br />
At least for a language that shares the same execution model as JVM.<br />
<br />
Here is the repeat implementation:<br />
<br />
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(REPEAT r) { </div>
<div style="font-family: Monaco; font-size: 14px;">
(<span style="color: #909090;">1</span>..(r.times.<span style="color: #bb4300;">evaluate</span>.intValue)).<span style="color: #bb4300;">forEach</span>[</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>r.commands.<span style="color: #bb4300;">forEach</span>[c| c.<span style="color: #bb4300;">exec</span>]</div>
<div style="font-family: Monaco; font-size: 14px;">
]</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
}</div>
</div>
<div>
<br /></div>
<div>
It uses xtend literals to create a range from 1 to "N" where N is the "times" property of the REPEAT object. Again that could be a value or a variable. So it needs to get evaluated.</div>
<div>
Then for each of that it will execute all the sentences within the REPEAT.</div>
<div>
As with the if, here we are basing the solution of the REPEAT on the "forEach" methods of xtend Iterables. </div>
<div>
<br /></div>
<h4>
Boolean operations</h4>
<div>
Evaluating boolean operations is really straight forward since we use xtend operators.</div>
<div>
Again we always need to first evaluate both operands and then natively compare them</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">boolean</span> evalBool(EQUALS e) { </div>
<div style="font-family: Monaco; font-size: 14px;">
e.op1.<span style="color: #bb4300;">evaluate</span> == e.op2.<span style="color: #bb4300;">evaluate</span> </div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">boolean</span> evalBool(GREATER_THAN e) { </div>
<div style="font-family: Monaco; font-size: 14px;">
e.op1.<span style="color: #bb4300;">evaluate</span> > e.op2.<span style="color: #bb4300;">evaluate</span></div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">boolean</span> evalBool(LESSER_THAN e) { </div>
<div style="font-family: Monaco; font-size: 14px;">
e.op1.<span style="color: #bb4300;">evaluate</span> < e.op2.<span style="color: #bb4300;">evaluate</span> </div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<h4>
Procedures</h4>
</div>
<div>
Now this is basically the most interesting part of the language.</div>
<div>
We have seen that a Procedure is a piece of behaviour that can be called to reuse code (and of course to "reify this concept").</div>
<div>
So a procedure can actually call another procedure, and so on.</div>
<div>
Procedures receive parameters (PARAM). And within them you could have local variables (MAKE).</div>
<div>
<br /></div>
<div>
Like in any other language, each procedure defines a "scope" which contains all the references that is available within it. That means the "state" of the execution at that point.</div>
<div>
So, when a procedure A, calls a procedure B, the code within B won't be able to modify or access the context of A. If A needs to send some data to B, then it must do it through parameters.</div>
<div>
<br /></div>
<div>
So, while executing A the available state is the <b>current context that contains all A local variables plus its parameters.</b>.</div>
<div>
Then when A calls B, the current context will be B's, and A will be hold back in background.</div>
<div>
So when B finishes, the current context is now A again as it was.</div>
<div>
<br /></div>
<div>
This should be really familiar to you. It's the <b>stack model.</b></div>
<div>
<b><br /></b></div>
<div>
So for our procedures, we need to implement that !</div>
<div>
<br /></div>
<div>
First thing is really easy: what happens when we evaluate a procedure definition, the TO class ?</div>
<div>
<br /></div>
<div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span><span style="color: black;"> </span><span style="color: #931a68;">dispatch</span><span style="color: black;"> </span><span style="color: #931a68;">void</span><span style="color: black;"> exec(TO t) { </span>/* does nothing. It's just a declaration */<span style="color: black;"> }</span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><br /></span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Nothing, of course.</span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Because this is just the declaration. It's not executing it.</span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">But then when we find a procedure call we need to implement the fun part:</span></div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(PROCEDURE_CALL call) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #0132ba;">stack</span>.push(call.<span style="color: #bb4300;">createContext</span>())</div>
<div style="font-family: Monaco; font-size: 14px;">
call.to.commands.<span style="color: #bb4300;">forEach</span>[c | c.<span style="color: #bb4300;">exec</span>]</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #0132ba;">stack</span>.pop </div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">The code should be self-explained.</span></div>
Executing a procedure is basically executing each of its commands (or statements).<br />
But before that we need to push the new context into the stack.<br />
And after that popping it so we will use the previous context.<br />
<br />
So our interpreter has a stack attribute besides the canvas<br />
<br />
<span style="color: #931a68; font-family: Monaco; font-size: 14px;">var</span><span style="font-family: Monaco; font-size: 14px;"> </span><span style="color: #0132ba; font-family: Monaco; font-size: 14px;">stack</span><span style="font-family: Monaco; font-size: 14px;"> = </span><span style="color: #931a68; font-family: Monaco; font-size: 14px;">new</span><span style="font-family: Monaco; font-size: 14px;"> Stack<Map<PARAM, Double>></span><br />
<span style="font-family: Monaco; font-size: 14px;"><br /></span>
Notice that the stack is a map of PARAM and a Double.<br />
This means that each stack element (context) has the declaration of the parameters, plus their actual values.<br />
The part that changes is the value, the double.<br />
<br />
So now we can see how the createContext() works:<br />
<br />
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> Map<PARAM,Double> createContext(PROCEDURE_CALL call) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">val</span> map = newHashMap</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #4e9072;">// <span style="text-decoration: underline;">param</span> - value</span></div>
<div style="font-family: Monaco; font-size: 14px;">
call.params.<span style="color: #bb4300;">forEach</span>[p, i|</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>map.put(call.to.parameters.get(i), p.<span style="color: #bb4300;">evaluate</span>) </div>
<div style="font-family: Monaco; font-size: 14px;">
]</div>
<div style="font-family: Monaco; font-size: 14px;">
map</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<br />
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<span style="font-family: inherit;">To enter a procedure we create the context by creating a new Map evaluating the list of arguments from the call, to get their effective value, and then putting those values in the map (context) using the parameter at the same position from the Procedure declaration.</span></div>
<div style="min-height: 19px;">
<span style="font-family: inherit;"><br /></span></div>
<div style="min-height: 19px;">
This is just one type of argument passing implementation.</div>
<div style="min-height: 19px;">
It's based on the order of the parameters as many languages like Java, C#, C, etc.</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
Lets take this example, if you have this procedure</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<span style="font-family: Courier New, Courier, monospace;">TO drawACircle :radius :center </span></div>
<div style="min-height: 19px;">
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div style="min-height: 19px;">
<span style="font-family: Courier New, Courier, monospace;">END TO</span></div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
Then when you call it you don't need to specify which parameter is the radius and which one is the center, because it uses the arg position as convention to match them</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<span style="font-family: Courier New, Courier, monospace;">drawACircle 10 (4,4)</span></div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
That is a LOGO language decision.</div>
<div style="min-height: 19px;">
Your language could have a completely different mechanism.</div>
<div style="min-height: 19px;">
For example named parameters.</div>
<div style="min-height: 19px;">
In that case the "createContext" method implementation should be different and implement that mapping based on the names.</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
Now back to our example, the counter part of creating the context, is to "access" it.</div>
<div style="min-height: 19px;">
If it holds the parameters, then it means that when you evaluate a reference to a parameter then it will go to the stack to fetch the current value.</div>
<div style="min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(PARAM p) { <span style="color: #0132ba;">stack</span>.peek.get(p) }</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
And there is the complete set of evaluate() multi methods:</div>
<div style="min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(VALUE v) { v.^val }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(VARIABLE_REF r) { r.toVar.<span style="color: #bb4300;">evaluate</span> }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(MAKE m) { m.value.<span style="color: #bb4300;">evaluate</span> }</div>
<div style="min-height: 19px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(PARAM p) { <span style="color: #0132ba;">stack</span>.peek.get(p) }</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
The first one is really easy, it is the case where you declared a double literal number.</div>
<div style="min-height: 19px;">
A variable ref means to evaluate the referenciable.</div>
<div style="min-height: 19px;">
As a referenciable could be a MAKE or a PARAM, then the other methods will be executed.</div>
<div style="min-height: 19px;">
A MAKE evaluates the right side of the declaration, which will be a VALUE.</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<br /></div>
<h4>
Variables (non param references state)</h4>
<div>
So we have seen that the parameters state are managed through a context which is in a stack.</div>
<div>
So this is completely "out" of the semantic model objects. This means that the state is tracked by the interpreter and not the objects themselves.</div>
<div>
<br /></div>
<div>
This is one way to implement state changes, without touching the semantic model objects. Without mutating them.</div>
<div>
<br /></div>
<div>
We could have implemented variables also like that.</div>
<div>
When we exec a variable declaration (MAKE) then it would have added a new key-value to the current context.</div>
<div>
Then when you change that variable (for example with a SUM operation), this would have updated the variable, which would have meant to change the value in the context (the map).</div>
<div>
<br /></div>
<div>
But we didn't implemented that way.</div>
<div>
Just to show that there's another way. A way where you hold the state in the semantic model itself.</div>
<div>
You "change" it.</div>
<div>
For example</div>
<div>
<br /></div>
<div>
<span style="color: #931a68; font-family: Monaco; font-size: 14px;">MAKE</span><span style="font-family: Courier New, Courier, monospace;"> a = 10</span></div>
<div>
<br /></div>
<div>
will create an instance of the class MAKE, with a "value" referencing the "10" object (instance of VALUE).</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
After that if you have this</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
<span style="color: #931a68; font-family: Monaco; font-size: 14px;">SUM </span><span style="font-family: Courier New, Courier, monospace;">a = a + 3</span></div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
Then we will change the "Make->10" object in order to start pointing to a new VALUE object that we must create with the value "13".</div>
<div style="min-height: 19px;">
So we will modify the semantic model object directly.</div>
<div style="min-height: 19px;">
<br /></div>
<div style="min-height: 19px;">
Here is the interpreter logic for this:</div>
<div style="min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(SUM s) <span class="Apple-tab-span" style="white-space: pre;"> </span> { s.<span style="color: #bb4300;">updateVar</span>[a,b| a + b] }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(DIVIDE s) { s.<span style="color: #bb4300;">updateVar</span>[a,b| a / b] }</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(MULTIPLY s) { s.<span style="color: #bb4300;">updateVar</span>[a,b| a * b] }</div>
<div style="min-height: 19px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> <span style="color: #931a68;">void</span> exec(SUBTRACT s) { s.<span style="color: #bb4300;">updateVar</span>[a,b| a - b] }</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<br />
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span style="font-family: Times; font-size: small;">Again it relies on the native java operations. But the interesting part is the updateVar.</span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> updateVar(OPERATION s, (Double,Double)=>Double function) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">val</span> newValue = function.apply(s.valOne.<span style="color: #bb4300;">evaluate</span>, s.valTwo.<span style="color: #bb4300;">evaluate</span>).<span style="color: #bb4300;">asValue</span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
s.targetVariable.value = newValue</div>
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
First it evaluates the closure (+, /, *, etc).<br />
Then it simply changes the targetVariable's "value" to point to the new value.<br />
<br />
The next interesting part here is the "asValue" method, because the function returns a double object, but we cannot set a double to "targetVariable.value".<br />
Which is the MAKE.value property, of type <span style="font-family: Monaco; font-size: 14px;">EXPRESSION.</span><br />
<span style="font-family: Monaco; font-size: 14px;"><br /></span>
So we need to create a new EXPRESSION object with the double number.<br />
<br />
This is interesting because up until now we never created new instances of our semantic model.<br />
All of the instances were created by Xtext itself based on the input file, while parsing it.<br />
<br />
So if you need to create new objects you need to use a Factory class that is also automatically generated by XText.<br />
<br />
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> asValue(Double i) {</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">val</span> v = TortugaDSLFactory.<span style="color: #0326cc;">eINSTANCE</span>.createVALUE</div>
<div style="font-family: Monaco; font-size: 14px;">
v.^val = i</div>
<div style="font-family: Monaco; font-size: 14px;">
v</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
}</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">We are here creating a new VALUE instance, which is a subclass of EXPRESSION, for simple values.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">And that's it. We have created new "synthetic" objects. (because they don't have a corresponding element in the source code)</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">So accessing a variable value is just returning its property:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">def</span> <span style="color: #931a68;">dispatch</span> Double evaluate(VALUE v) { v.^val }</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Because that value will be changing through the execution of the program.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">We don't need to get the value from the stack or any other place outside of the object itself.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<h2>
To Sum-Up</h2>
</div>
<div>
So that's basically all. At least the important part of the interpreter.</div>
<div>
There are some evaluation methods that we have ignored because they are basically the same mechanic.</div>
<div>
<br /></div>
<div>
To sum up we have seen here:</div>
<div>
<ul>
<li>That an xtext interpreter is <b>just Java or xtend program</b> that implements the runtime behaviour of your language (the runtime semantic)</li>
<li>That <b>if you do it in XTend you're be a lot happier</b> than doing it in Java, since there are a couple of Xtend features that were actually designed to be useful for this case: extension methods, and multiple dispatch. To add behaviour to the semantic model classes, and to still have polymorphism without touching the generated classes</li>
<li><b>The general mechanic of evaluating objects</b> in an interpreter: which usually requires to recursively evaluate other objects of the graph, like attributes.</li>
<li>That <b>for some evaluations you just rely on java/xtend functionality</b> like math operations, if, or loops.</li>
<li><b>For more complex languages you need to implement the "state management"</b> like we did for procedures call.</li>
<li>We saw <b>two different approach for state management</b>: one that takes the state away of the semantic model (using a stack), and another that directly changes the semantic model objects</li>
</ul>
<div>
<br /></div>
</div>
<div>
<h2>
To generate code or to interpret</h2>
</div>
<div>
So to get back to our first posts. What would be better for your language: to generate code or to implement an interpreter ?</div>
<div>
<br /></div>
<div>
Of course there's not a single answer for this.</div>
<div>
It depends.</div>
<div>
By generating code you avoid implementing things like state management, and execution model.</div>
<div>
Which could be complex for ready for production interpreted languages.</div>
<div>
<br /></div>
<div>
Although if your language has an execution model which is quite different from Java, then generating the code could also get difficult.</div>
<div>
Generating code also introduces a new step in the execution, and indirection, which could make it difficult to map back runtime errors to the original code in your language.</div>
<div>
While interpreted languages could be easier for this.</div>
<div>
<br /></div>
<div>
Still interpreters could also get complex and messy for complex languages.</div>
<div>
<br /></div>
<div>
The overall sensation is that implementing an interpreted feels like coding any other java/xtend program. It's just that you are writing a language execution model :P</div>
<div>
But it's code, so you can use OOP technics like patterns, delegation, inheritance, etc.</div>
<div>
<br /></div>
<div>
While this is more complex or impossible for code generation. At least if you are using the "templates" approach.</div>
<div>
<br /></div>
<div>
So, it's completely up to you.</div>
<div>
I think that it is a really good practice to try all 3 solutions to get the feeling of them.</div>
<div>
While doing that you'll be learning by experience which is a lot better than just reading this blog post :)</div>
<div>
So I hope you'll go ahead and start your own mini-language !</div>
<div>
<br /></div>
<div>
Have fun !</div>
<div>
<br /></div>
<div>
<h2>
Tortuga Language Source code</h2>
</div>
<div>
You can find the source code of the language in github</div>
<div>
<br /></div>
<div>
<a href="https://github.com/uqbar-project/xtext-tortuga-lang">https://github.com/uqbar-project/xtext-tortuga-lang</a></div>
Anonymoushttp://www.blogger.com/profile/06414934144608751982noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-80705778727345528512015-06-05T18:09:00.000-03:002015-06-05T18:09:39.221-03:00Tutorial: Language Development with XText: A Logo example - Part I: Introduction to XText<h2>
Brief description of XText</h2>
<br />
<a href="http://www.eclipse.org/Xtext/" target="_blank">XText</a> is a Language Workbench. Meaning an environment for developing languages.<br />
<br />
It targets from small Domain-Specific Languages (also known as DSL), to also complex General-Purpose Languages).<br />
<br />
What's is good about it (well it has many good points) is that it gives you a pretty good base for quickly starting up a languages, by providing you advanced features only based on a declarative description of your language.<br />
<br />
To give you an idea:<br />
<br />
<ul>
<li>you don't need to write a Lexer</li>
<li>you don't need to write a Parser</li>
<li>you don't need to write a code editor from scratch</li>
<li>and so on..</li>
</ul>
<div>
It has pretty good defaults for almost all aspects of a language (like scoping and references).</div>
<div>
<br /></div>
<div>
So if if you already know XText at least at a basic level you know what I mean.</div>
<div>
If you don't then I encourage you to read the following links:</div>
<div>
<br /></div>
<div>
<ul>
<li>Main doc site: <a href="http://www.eclipse.org/Xtext/documentation/">http://www.eclipse.org/Xtext/documentation/</a></li>
<li>5 min tutorial: <a href="http://www.eclipse.org/Xtext/documentation/101_five_minutes.html">http://www.eclipse.org/Xtext/documentation/101_five_minutes.html</a></li>
<li>15 min tutorial: <a href="http://www.eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html">http://www.eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html</a></li>
</ul>
<div>
<br /></div>
</div>
<div>
If you happen to know Spanish then <a href="https://sites.google.com/site/programacionhm/conceptos/dsls/domainspecificlanguage/dsl---xtext" target="_blank">this link</a> can be useful </div>
<div>
<br /></div>
<br />
<h2>
Intro to XText</h2>
<h3>
The grammar</h3>
<div>
The starting-point for an xtext language is a file called "the grammar".</div>
<div>
It's kind of a BNF (Backus-Naur Form) declaration of the language, if you know what BNF is.</div>
<div>
If you don't then don't worry (although I would highly recommend reading Naur papers about software development and the industry ;))</div>
<div>
<br /></div>
<div>
An xtext grammar is a file that is itself written in an specific format.</div>
<div>
The goal of this grammar is to define two aspects of your language altogether:</div>
<div>
<br /></div>
<div>
<ul>
<li><b>The Syntactical Form:</b> allowed symbols of your language, and their order, spaces, keywords, etc.</li>
<li><b>The Semantical Model: </b>meaning the core "concepts" of your language and how they are composed. This will be represented as Class-based O.O. design. But you don't need to write those classes.</li>
</ul>
<div>
Let's put an example.</div>
<div>
If you want to write a language for specifying products and their prices. The the syntax part could be defining keywords like: 'prod' , '$', etc.</div>
<div>
But your concepts are: "a Product", "a Price", and the idea that "a Product has a current price".</div>
<div>
<br /></div>
<div>
Here is a sample grammar for the Hello example:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402156369545/conceptos/dsls/domainspecificlanguage/dsl---xtext/xtext-saludos-gramatica.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402156369545/conceptos/dsls/domainspecificlanguage/dsl---xtext/xtext-saludos-gramatica.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div style="font-family: Helvetica; font-size: 12px;">
<span style="font-family: Times; font-size: small;">This tell us that a file for this language will contain a "<b>Model</b>"</span></div>
<div style="font-family: Helvetica; font-size: 12px;">
<span style="font-family: Times; font-size: small;">The model has a list of "<b>Greeting</b>"</span></div>
<div style="font-family: Helvetica; font-size: 12px;">
<span style="font-family: Times; font-size: small;">A <b>Greeting </b>has a <b>name</b> whose format is an "ID".</span></div>
<div style="font-family: Helvetica; font-size: 12px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
In classes it will look like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402156622087/conceptos/dsls/domainspecificlanguage/dsl---xtext/saludos-modelo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402156622087/conceptos/dsls/domainspecificlanguage/dsl---xtext/saludos-modelo.png" /></a></div>
<br />
<br /></div>
<div>
And indeed, XText generates this classes automatically for you. Actually interfaces.</div>
<div>
Of course based on the grammar file.</div>
<div>
<br /></div>
<div>
Besides that you probably noticed that <b>Greeting</b> has some Strings there.</div>
<div>
That's part of the <b>syntax</b>.</div>
<div>
<br /></div>
<div>
You read that <b>Rule </b>(Model and Greeting there are called "Rules") as follows in terms of syntax:</div>
<div>
<br /></div>
<div>
"A greeting is defined by the keyword 'Hello' then an ID you must provide and the a semi-colon".</div>
<div>
<br /></div>
<div>
This are valid examples of the DSL:</div>
<div>
<br /></div>
<div>
<ul>
<li>Hello World !</li>
<li>Hello Uqbar !</li>
<li>Hello Project!</li>
</ul>
<div>
<br /></div>
</div>
<h3>
The Runtime Part</h3>
<div>
Just by defining the grammar XText will generate for you:</div>
<div>
<ul>
<li>The classes for your semantic model</li>
<li>The parser, lexer and linker that will read a file and create instances of your semantic model</li>
<li>A rich text editor with autocomplete, reference browsing and searches, syntax colouring</li>
<li>An outline view</li>
<li>And many extension points</li>
</ul>
<div>
Now what is up to you is what you want to do once the file is parsed into the semantic model.</div>
</div>
<div>
I mean, what is supposed <b>to do !</b></div>
<div>
<b><br /></b></div>
<div>
<b>XText</b> will parse the text into instances of your semantic model and then you choose what to do with it.</div>
<div>
Here's a sample diagram (sorry it's in spanish)</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402157014999/conceptos/dsls/domainspecificlanguage/dsl---xtext/xtext-generainstanciasmodelo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402157014999/conceptos/dsls/domainspecificlanguage/dsl---xtext/xtext-generainstanciasmodelo.png" /></a></div>
<div>
<br /></div>
<div>
<b><br /></b></div>
<div>
For our example a file with greetings should write them to console ? should send an SMS ?</div>
<div>
should publish them to Facebook ?</div>
<div>
What ever.</div>
<div>
<br /></div>
<div>
That's what we call <b>the runtime part</b> of your language</div>
<div>
<br /></div>
<div>
And there's a whole new world there depending on the path you choose.</div>
<div>
<br /></div>
<div>
Basically with XText there are 3 options:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/variantes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/variantes.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<ol>
<li><b>Generating code</b></li>
<li><b>Inferring (?) code</b></li>
<li><b>Interpreting</b></li>
</ol>
</div>
<br />
We will discuss a little bit the first two options just to give you an idea, and the focus on the last one.<br />
Since, the first two strategies are part of XText documentation and tutorials, but you won't find much info about XText Interpreted languages.<br />
<br />
<h3>
Languages that Generate Code</h3>
<div>
This first options is basically to go visiting all the object instances of your semantic model, once they have been parsed, and somehow generate <b>executable code.</b></div>
<div>
<b><br /></b></div>
<div>
It's abstract like that, because you could generate:</div>
<div>
<ul>
<li><b>Textual code:</b> for example java code, or C#, or python, or even C</li>
<li><b>Binary code: </b>directly executable code.</li>
</ul>
<div>
The first option allows you to use an already functional backend or Virtual Machine like the JVM, so you just get rid of a lot of work what would mean creating your own VM.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/i-generator-o.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/i-generator-o.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The bad part is that your language cannot be directly executed.</div>
<div>
If you generate Java code then to run your program you will need three steps:</div>
<div>
<br /></div>
<div>
<ol>
<li><b>Run the generator:</b> which will produce .java code</li>
<li><b>Compile the Java code</b></li>
<li><b>Execute the compiled Java code</b></li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/generador-java.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="83" src="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/generador-java.png" width="640" /></a></div>
<div>
<b><br /></b></div>
<div>
<b><br /></b></div>
<div>
If you use an interpreted language like Python the just two:</div>
</div>
<div>
<ol>
<li><b>Run the generator:</b> which will produce .py code</li>
<li><b>Execute the Python interpreter</b></li>
</ol>
</div>
Of course you can always wrap up a set of tools and scripts to provide to the end user so that it will encapsulate all this steps, and for him it will just mean running a single command.<br />
<br />
Anyway, the point is that you generate code.<br />
How ?<br />
For textual code, XText already provides you a way to do this implementing the IGenerator interface<br />
<br />
<ol style="color: #333333; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 17.999998092651367px; list-style-position: initial; margin: 0px 0px 0px 33px; padding: 0px; white-space: pre-wrap;">
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #7f0085; font-weight: bold;">class</span><span style="color: #48484c;"> </span><span style="color: #777777;">MiGenerador</span><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">implements</span><span style="color: #48484c;"> </span><span style="color: #777777;">IGenerator</span><span style="color: #48484c;"> </span><span style="color: #555555;">{</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">override</span><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">void</span><span style="color: #48484c;"> doGenerate</span><span style="color: #555555;">(</span><span style="color: #777777;">Resource</span><span style="color: #48484c;"> resource</span><span style="color: #555555;">,</span><span style="color: #48484c;"> </span><span style="color: #777777;">IFileSystemAccess</span><span style="color: #48484c;"> fsa</span><span style="color: #555555;">)</span><span style="color: #48484c;"> </span><span style="color: #555555;">{</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">for</span><span style="color: #555555;">(</span><span style="color: #48484c;">e</span><span style="color: #555555;">:</span><span style="color: #48484c;"> resource</span><span style="color: #555555;">.</span><span style="color: #48484c;">allContents</span><span style="color: #555555;">.</span><span style="color: #48484c;">toIterable</span><span style="color: #555555;">.</span><span style="color: #48484c;">filter</span><span style="color: #555555;">(</span><span style="color: #777777;">Model</span><span style="color: #555555;">))</span><span style="color: #48484c;"> </span><span style="color: #555555;">{</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #48484c;"> </span><span style="color: #555555;">...</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #48484c;"> </span><span style="color: #555555;">}</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="font-size: small;"><span style="color: #48484c;"> </span><span style="color: #555555;">}</span></span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="color: #555555;"><span style="font-size: small;">}</span></span></li>
</ol>
<div>
<span style="color: #555555; font-family: Menlo, Monaco, Consolas, Courier New, monospace;"><span style="line-height: 18px; white-space: pre-wrap;"><br /></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/generador-modelo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/generador-modelo.png" /></a></div>
<div>
<span style="color: #555555; font-family: Menlo, Monaco, Consolas, Courier New, monospace;"><span style="line-height: 18px; white-space: pre-wrap;"><br /></span></span></div>
<blockquote class="tr_bq">
Then like a templating engine you can write string expressions with dynamic parts using xtend RichStrings</blockquote>
<br />
<ol class="linenums" style="background-color: white; color: #333333; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; line-height: 18px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 0px 33px; padding: 0px; white-space: pre-wrap;">
<li class="L0" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="kwd" style="color: #7f0085; font-weight: bold;">def</span><span class="pln" style="color: #48484c;"> compile</span><span class="pun" style="color: #555555;">(</span><span class="typ" style="color: #777777;">Entity</span><span class="pln" style="color: #48484c;"> e</span><span class="pun" style="color: #555555;">)</span><span class="pln" style="color: #48484c;"> </span><span class="str" style="color: #4200bf;">'''</span></li>
<li class="L1" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="str" style="color: #4200bf;"> package «</span><span class="pln" style="color: #48484c;">e</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">eContainer</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">fullyQualifiedName</span><span class="str" style="color: #4200bf;">»;</span></li>
<li class="L2" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="str" style="color: #4200bf;"> </span></li>
<li class="L3" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="str" style="color: #4200bf;"> public class «</span><span class="pln" style="color: #48484c;">e</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">name</span><span class="str" style="color: #4200bf;">» {</span></li>
<li class="L4" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="str" style="color: #4200bf;"> }</span></li>
<li class="L5" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="str" style="color: #4200bf;">'''</span></li>
</ol>
<div>
<span style="color: #4200bf; font-family: Menlo, Monaco, Consolas, Courier New, monospace; font-size: x-small;"><span style="line-height: 18px; white-space: pre-wrap;"><br /></span></span></div>
<div>
<span style="color: #4200bf; font-family: Menlo, Monaco, Consolas, Courier New, monospace; font-size: x-small;"><span style="line-height: 18px; white-space: pre-wrap;"><br /></span></span></div>
What's good about this strategy is that (at first) it is "simple" to generate code. Because you just write it embedded in xtend and replace the dynamic parts with expressions.<br />
<br />
The bad is that eventually if your language not "small" and you start to have a complex semantic model or complex rules for generating code, and you need to reuse templates, and stuff like that, then it tends to get messy an difficult to maintain.<br />
<br />
Also (and this will make sense next when we'll see the second strategy), <b>you could be generating invalid code</b> and your generator could just not be aware about that.<br />
It will explode on the user's face once it will try to run the generated code.<br />
Think of types issues in the generated java code.<br />
For example not importing classes, or incompatible types assignments, etc.<br />
<br />
So...<br />
<br />
<h3>
The JVM Inferrer Model</h3>
<div>
<br /></div>
<div>
The second strategy is also about generating code, but not any kind of code, but just Java code.</div>
<div>
Yeap. Deal with that. You can also generate java code.</div>
<div>
The good news is that you don't need to write the generator in Java. You'll use xtend.</div>
<div>
And the end user of your language won't either write Java code, so, it's just a good an intermediate language to avoid writing something like assembler.</div>
<div>
<br /></div>
<div>
So, the JVM Inferrer also generates java code, but the way it does it is completely different.</div>
<div>
You won't use code templates with just Strings.</div>
<div>
You will use an API to generate code.</div>
<div>
<br /></div>
<div>
So you are not responsable of writing the code "text", but instead to map your semantic model into a model which represents the Java concepts like Class, Method, Field, etc.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/inferrer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1402153838829/conceptos/dsls/domainspecificlanguage/dsl---xtext/inferrer.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The generator is also an xtend class which implements a given interface</div>
<div>
<br /></div>
<div>
<ol style="color: #333333; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 11.818181991577148px; line-height: 17.999998092651367px; list-style-position: initial; margin: 0px 0px 0px 33px; padding: 0px; white-space: pre-wrap;">
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="color: #7f0085; font-weight: bold;">class</span><span style="color: #48484c;"> </span><span style="color: #777777;">DomainmodelJvmModelInferrer</span><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">implements</span><span style="color: #48484c;"> </span><span style="color: #777777;">IJvmModelInferrer</span><span style="color: #48484c;"> </span><span style="color: #555555;">{</span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">override</span><span style="color: #48484c;"> </span><span style="color: #7f0085; font-weight: bold;">void</span><span style="color: #48484c;"> infer</span><span style="color: #555555;">(</span><span style="color: #777777;">EObject</span><span style="color: #48484c;"> model</span><span style="color: #555555;">,</span><span style="color: #48484c;"> </span><span style="color: #777777;">IJvmDeclaredTypeAcceptor</span><span style="color: #48484c;"> acceptor, boolean preIndexPhase</span><span style="color: #555555;">)</span><span style="color: #48484c;"> </span><span style="color: #555555;">{</span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"> ...</li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="color: #48484c;"> </span><span style="color: #555555;">}</span></li>
<li style="color: #bebec5; line-height: 18px; padding-left: 12px;"><span style="color: #555555;">}</span></li>
</ol>
<div>
<span style="color: #555555; font-family: Menlo, Monaco, Consolas, Courier New, monospace;"><span style="font-size: 12px; line-height: 18px; white-space: pre-wrap;"><br /></span></span></div>
</div>
<div>
<br /></div>
<div>
Here's a code snippet which based on an object instanceof Operation from the semantic model it generates a field, a getter and a setter for it as members of a class that is currently generating</div>
<div>
<br /></div>
<div>
<ol class="linenums" style="background-color: white; color: #333333; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; line-height: 18px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 0px 33px; padding: 0px; white-space: pre-wrap;">
<li class="L1" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="typ" style="color: #777777;">Property</span><span class="pln" style="color: #48484c;"> </span><span class="pun" style="color: #555555;">:</span><span class="pln" style="color: #48484c;"> </span><span class="pun" style="color: #555555;">{</span></li>
<li class="L2" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="pln" style="color: #48484c;"> members </span><span class="pun" style="color: #555555;">+=</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">toField</span><span class="pun" style="color: #555555;">(</span><span class="pln" style="color: #48484c;">feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">name</span><span class="pun" style="color: #555555;">,</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">type</span><span class="pun" style="color: #555555;">)</span></li>
<li class="L3" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="pln" style="color: #48484c;"> members </span><span class="pun" style="color: #555555;">+=</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">toGetter</span><span class="pun" style="color: #555555;">(</span><span class="pln" style="color: #48484c;">feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">name</span><span class="pun" style="color: #555555;">,</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">type</span><span class="pun" style="color: #555555;">)</span></li>
<li class="L4" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="pln" style="color: #48484c;"> members </span><span class="pun" style="color: #555555;">+=</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">toSetter</span><span class="pun" style="color: #555555;">(</span><span class="pln" style="color: #48484c;">feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">name</span><span class="pun" style="color: #555555;">,</span><span class="pln" style="color: #48484c;"> feature</span><span class="pun" style="color: #555555;">.</span><span class="pln" style="color: #48484c;">type</span><span class="pun" style="color: #555555;">)</span></li>
<li class="L5" style="color: #bebec5; padding-left: 12px; text-shadow: rgb(255, 255, 255) 0px 1px 0px;"><span class="pln" style="color: #48484c;"> </span><span class="pun" style="color: #555555;">}</span></li>
</ol>
</div>
<div>
<br /></div>
</div>
<div>
There are number of advantages of using this inferrer or mapper</div>
<div>
<br /></div>
<div>
The first one is that it's now code, and you have an API which models all the Java source concepts, so you should be able to design complex code generation logic by applying all the OOP good practices.</div>
<div>
<br /></div>
<div>
But also, the most important part is that XText will keep a link between the Java generated code and the semantic model which generated that part of the code.</div>
<div>
<br /></div>
<div>
In this case XText <b>will know </b>that the generated field, getter and setters where <b>derived from a particular instance of your semantic model</b>.</div>
<div>
And even better XText knows given a semantic model instance from which part of the text came from.</div>
<div>
<br /></div>
<div>
So, it is really clever, and when it detects that the generated java code has a problem (like a compilation error we mentioned before), it will point out the original piece of code that the user wrote.</div>
<div>
<br /></div>
<div>
It will also do more complex features like inferring types from the generated java code and then applying validations back to your language. So it will avoid the user writing code that won't compile in the Java code.</div>
<div>
<br /></div>
<div>
You need to see it with your own eyes. Go there and follow their docs here</div>
<div>
<br /></div>
<div>
<a href="http://www.eclipse.org/Xtext/documentation/104_jvmdomainmodel.html#domain-model-step4">http://www.eclipse.org/Xtext/documentation/104_jvmdomainmodel.html#domain-model-step4</a></div>
<div>
<br /></div>
<div>
There are also some examples of this strategy.</div>
<div>
Otherwise we will create a new tutorial in the future :)</div>
<div>
<br /></div>
<h3>
Interpreted Languages</h3>
<div>
<br /></div>
<div>
The last strategy is to completely avoid generating code.</div>
<div>
We say, Xtext is a Java framework, and it's already instantiating Java objects for our semantic model. We have those objects there available from java, so instead of visiting them to generate code, why don't we just visit them to perform the actual execution ?</div>
<div>
For example for each Greeting, we will print it to console through System.out.println().</div>
<div>
<br /></div>
<div>
And that's basically the interpreted model.</div>
<div>
<br /></div>
<div>
You'll basically need something like a Main class which will receive the file path that you want to interpret.</div>
<div>
It will call Xtext to parse this file into Semantic Model instances, and then go through it to interpret it and do something</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://sites.google.com/site/programacionhm/_/rsrc/1403097339407/conceptos/dsls/domainspecificlanguage/dsl---xtext/interpreter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://sites.google.com/site/programacionhm/_/rsrc/1403097339407/conceptos/dsls/domainspecificlanguage/dsl---xtext/interpreter.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
This is the strategy that we will focus on for the LOGO example.</div>
<div>
The advantages of it is that:</div>
<div>
<ul>
<li>there's no intermediate language</li>
<li>no extra commands or step to execute</li>
<li>at first and if the language is simple, then the interpreter is a really good way to have something working right away.</li>
</ul>
<div>
The disadvantages are more difficult to explain right now. We will wait for the end of the post.</div>
</div>
<div>
But basically it's the fact that the semantic model are not 100% "your classes". They are generated so you cannot touch them. And that adds complexity. That won't allow you to fully desing with OOP (although XText has many cool features for tackling that like multi methods and extension methods).</div>
<div>
Also you are using directly those objects that are kind of AST objects. They are tied to all the eCore and EMF infrastructure.</div>
<div>
So you cannot instantiate them easily. This means that your language core classes are tied up to eclipse technology and frameworks.</div>
<div>
There's also a runtime overhead there (plugins, dependencies, eclipse, osgi, etc).</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<a href="http://blog.uqbar-project.org/2015/06/tutorial-language-development-with_4.html">Next Article of the Tutorial</a></div>
<div>
<br /></div>
<div>
</div>
<br />
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/06414934144608751982noreply@blogger.com2tag:blogger.com,1999:blog-6739892643840943427.post-71221962732358366732015-06-04T23:19:00.000-03:002015-06-05T09:16:03.655-03:00Tutorial: Language Development with XText: A Logo example - Part II: Getting to Know Logo and Our Solution Approach<br />
<h2>
A Little of Context</h2>
<div>
This language was developed as an example language to teach DSLs in the context of Public University subject in Argentina for which some of us are teachers.</div>
<div>
<br /></div>
<div>
We wanted to show a small yet powerful interpreted language.</div>
<div>
And one of the goal was to shows something that will produce some visual effect, so that the student could really appreciate the execution of the language.</div>
<div>
<br /></div>
<div>
But we didn't want to actually spend a lot of time on the graphical part, creating a logo from scratch</div>
<div>
So we just went ahead and searched on Google for an existing Logo project, which was JVM compatible.</div>
<div>
We will just then create the XText language and use an interpreter to read or semantic model and call that Logo to perform the drawing.</div>
<div>
<br /></div>
<div>
That was exactly what we did.</div>
<div>
<br /></div>
<h3>
Tortue</h3>
<div>
So as <b>backend</b> logo we used Tortue a GPL open source project</div>
<div>
<br /></div>
<div>
<a href="http://tortue.sourceforge.net/">http://tortue.sourceforge.net/</a></div>
<div>
<br /></div>
<div>
Here's a screenshot from their site</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://tortue.sourceforge.net/screenshots/windows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://tortue.sourceforge.net/screenshots/windows.png" height="496" width="640" /></a></div>
<div>
<br /></div>
<div>
It actually comes as a full standalone java app.</div>
<div>
But we will just use the classes as if it was an API.</div>
<div>
And also make him draw into a canvas that we will embed into the running eclipse.</div>
<div>
<br /></div>
<h3>
The Language Grammar</h3>
<div>
The logo language is kind of mid-sized. It's not a so small as a common DSL, but it is neither much complex or big as a typed GPL language.</div>
<div>
Still it is a good exercise since it has many elements of a full blown GPL imperative language like C, pascal, Java, etc.</div>
<div>
<br /></div>
<div>
We will see here a couple of example programs to understand the language:</div>
<div>
<br /></div>
<h4>
Moving the Turtle</h4>
<div>
<br /></div>
<div>
This is a really simple program to start getting familiar with the language</div>
<div>
<br /></div>
<div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENDOWN</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> 80</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> 80</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> 80</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> 80</span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Menlo; font-size: 14px;">
</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENUP</div>
<div style="font-family: Menlo; font-size: 14px;">
<br /></div>
If you execute this<br />
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXiFNnkdfya5Nshpp9coI8EHpzJkTdGEBVSHLD38A4ajZJ-1FetUA0zKnMyOR6uCSvtUBbQtOcwSmcah4G-2FDcstCTzr1XtnrJAa_etxqwIAxH1gX9PGcmAR71C5EftChLvv7JTUjD-w/s1600/Screen+Shot+2015-06-04+at+22.32.34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="107" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXiFNnkdfya5Nshpp9coI8EHpzJkTdGEBVSHLD38A4ajZJ-1FetUA0zKnMyOR6uCSvtUBbQtOcwSmcah4G-2FDcstCTzr1XtnrJAa_etxqwIAxH1gX9PGcmAR71C5EftChLvv7JTUjD-w/s320/Screen+Shot+2015-06-04+at+22.32.34.png" width="320" /></a></div>
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;">It will draw the following:</span></div>
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmDKYGrWrgI4JqQXebkTEtImOr9H34wwPYvXyg0pbuF42Cty6aGLgJFgdJOBsxVmFw-IQEtdMy5g6h0Lj2XAdQjooLEkbHTCVuwoUIuPaXHiex_rdFwc6ZIhZuG6guzPS_VCEp6_8FGaQ/s1600/Screen+Shot+2015-06-04+at+22.34.26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmDKYGrWrgI4JqQXebkTEtImOr9H34wwPYvXyg0pbuF42Cty6aGLgJFgdJOBsxVmFw-IQEtdMy5g6h0Lj2XAdQjooLEkbHTCVuwoUIuPaXHiex_rdFwc6ZIhZuG6guzPS_VCEp6_8FGaQ/s320/Screen+Shot+2015-06-04+at+22.34.26.png" width="320" /></a></div>
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
So <b>PENDOWN</b> and <b>PENUP</b> are special <b>Drawing Sentences</b> that control when the turtle should start drawing and when it is not.<br />
They have side-effect, meaning that they change the state of the turtle to "drawing" or just "moving without drawing".<br />
The the others: <b>RIGHT</b>, <b>LEFT</b>,<b> FORWARD, </b>are <b>Move</b> operations for controlling the turtle.<br />
<br />
So, to start seeing some xtext code here is a rule that put together all these <b>moves </b><br />
<b><br /></b>
<div style="font-family: Monaco; font-size: 14px;">
MOVE:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>FORWARD | LEFT | RIGHT | SET_X | SET_Y</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">This is part of our new language grammar in Xtext.</span></div>
We will see each actual rule in the next section.<br />
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<h4>
Using variables</h4>
<div>
Now we can change the previous program to avoid repeating the size of each side of the square, using a variable.</div>
<div>
<br /></div>
<div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENDOWN</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MAKE</span> lado = 80</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> lado</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> lado</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> lado</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FORWARD<span style="color: black;"> lado</span></div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENUP</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">The variable "lado" (spanish for "side") is declared through the keyword "MAKE" which assigns a name and an initial value to it.</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Then we can see that all other operations like FORWARD could either use a simple value like a <b>Number or a Variable Reference</b>.</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">So now we can see the rules for these operations:</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
FORWARD: <span style="color: #3933ff;">'FORWARD'</span> amount=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
LEFT: <span style="color: #3933ff;">'LEFT'</span> amount=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
RIGHT: <span style="color: #3933ff;">'RIGHT'</span> amount=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
SET_X: <span style="color: #3933ff;">'SETX'</span> amount=EXPRESSION;</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
SET_Y: <span style="color: #3933ff;">'SETY'</span> amount=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">We can see there that all of these rules expect a special keyword and then an EXPRESSION.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Which in turn is as we identified:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
EXPRESSION: </div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>VARIABLE_REF | VALUE</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">A value is simply a double number</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
</div>
<div style="font-family: Monaco; font-size: 14px;">
VALUE:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>val=DOUBLE</div>
<div style="font-family: Menlo; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Menlo; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
</div>
<div>
And a Variable reference is a little bit more complicated:</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
VARIABLE_REF: toVar=[REFERENCIABLE];</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">It is a reference (the syntax for that in xtext is to use the square brackets) to a REFERENCIABLE.</span></div>
A Referenciable is:<br />
<br />
<div style="color: #929292; font-family: Monaco; font-size: 14px;">
REFERENCIABLE<span style="color: black;">:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>MAKE | PARAM</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
Make should be familiar for us, since it's the rule that we used in the example to declare a new variable.<br />
So this means that a referencia is a one of those variables or a PARAM, which we haven't seen yet.<br />
But we will soon !<br />
<br />
<h4>
Repeat Loops</h4>
</div>
<div>
We can still simplify the example by reducing duplicated code, using a repeat loop.</div>
<div>
<br /></div>
<div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENDOWN</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MAKE</span> lado = 100</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
REPEAT<span style="color: black;"> 4</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>FORWARD<span style="color: black;"> lado</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
END REPEAT</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENUP</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<br /></div>
It will repeat all the sentences 4 times. You should know this :P<br />
<br />
Lets see the grammar rules for this:<br />
<br />
<div style="font-family: Monaco; font-size: 14px;">
REPEAT:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #3933ff;">'REPEAT'</span> times=EXPRESSION</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>(commands+=SENTENCE)+</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>'END REPEAT'</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
By now you probably already understood that Repeats can also be used with a fixed number or with variable to define how many times it should repeat.<br />
Because "times" is of type EXPRESSION. Which we already see could be a VARIABLE_REF or a Variable.<br />
This means you can do this<br />
<br />
<span style="color: #931a68; font-family: Monaco; font-size: 14px;">MAKE</span><span style="font-family: Monaco; font-size: 14px;"> sides = 4</span><br />
<br />
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
REPEAT<span style="color: black;"> sides</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>FORWARD<span style="color: black;"> lado</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>RIGHT<span style="color: black;"> 90</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
END REPEAT</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
Now, what's a "SENTENCE" ?<br />
We will go a little further fast with this one.<br />
<br />
<div style="font-family: Monaco; font-size: 14px;">
SENTENCE:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>MAKE | CONTENT</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| PROCEDURE_CALL</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| OPERATION</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| CONTROL_SENTENCES</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| MOVE</div>
<br />
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| DRAWING_SENTENCE</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Sentence is probably the most generic rule, since it could be one of the MOVE sentences that we already saw, to control the turtle movement, but also a DRAWING_SENTENCE, that we also saw. It could also be a MAKE, because you can define new variables within a REPEAT, for example.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">And then more stuff we haven't seen yet like: PROCEDURE_CALL, CONTROL_SENTENCES, CONTENT, and OPERATION.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">We will see each of them in further sections</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<h4>
<span style="font-family: Times; font-size: small;">Procedures</span></h4>
</div>
<div>
<span style="font-family: Times; font-size: small;">Our sample program draws a square, but if we want to draw many squares, we don't want to copy and paste that code, so, for reusing certain functionality we can define procedures, than can be called anytime.</span></div>
<div>
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">TO</span> makeASquare</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>PENDOWN</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">MAKE</span> lado = 100</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>REPEAT<span style="color: black;"> 4</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">FORWARD</span> lado</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">RIGHT</span> 90</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>END REPEAT</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>PENUP</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
END TO</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
makeASquare</div>
</div>
<div>
<span style="font-family: Monaco; font-size: 14px;">makeASquare</span></div>
<div>
<span style="font-family: Monaco; font-size: 14px;"><br /></span></div>
<div>
This program first defines a procedure named "makeASquare" and all of its sentences.</div>
<div>
Then the program itself has two procedure calls to the same procedure.</div>
<div>
<br /></div>
<div>
So we have two new concepts for the language.</div>
<div>
<br /></div>
<div>
A procedure definition, which is:</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
TO: </div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #3933ff;">'TO'</span> <span style="color: #bb4300;">name</span>=ID (parameters+=PARAM)*</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>(commands+=SENTENCE)+</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>'END TO'</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Notice that it could have a list of PARAM's. And the body is a list of SENTENCE's (we've already seen that it's basically "anything" -but not a procedure definition, you cannot define one within other-)</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">A param is:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
PARAM:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #3933ff;">':'</span> <span style="color: #bb4300;">name</span>=ID</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">So now we now that from a REPEAT or a FORWARD, RIGHT, etc, you can use a value (double) or reference either a variable (MAKE), or a PARAM, in case you are within a procedure !.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">The other new concept is the procedure call:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
PROCEDURE_CALL:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>to=[TO] (params+=EXPRESSION)*</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Easy, a reference to a procedure (TO), and then an optional list of EXPRESSION, which will be evaluated and passed as the values for each parameter.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Remember EXPRESSION is either a value or a reference (to MAKE or PARAM).</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<h4>
<span style="font-family: Times; font-size: small;">Some Other Syntax Elements</span></h4>
</div>
<div>
There are a couple of other secondary elements in the language for example to control the font and the line color</div>
<div>
<br /></div>
<div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
PENCOLOR<span style="color: black;"> </span>GREEN</div>
<div style="font-family: Monaco; font-size: 14px;">
makeASquare</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Will produce:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjosEfYOsIxbarXSyu3BcClCPBOo5hKwuTBlh6RZZusHJsd5gnYUp2XUa2oL5STwTzPuYOxcbHD0ApSSxBja-niAxt8WF8SaDoMcS1R4RZurKIP2Xw8Weon7uCli8lP2GypJSQE7cQKOsU/s1600/Screen+Shot+2015-06-04+at+23.04.21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjosEfYOsIxbarXSyu3BcClCPBOo5hKwuTBlh6RZZusHJsd5gnYUp2XUa2oL5STwTzPuYOxcbHD0ApSSxBja-niAxt8WF8SaDoMcS1R4RZurKIP2Xw8Weon7uCli8lP2GypJSQE7cQKOsU/s320/Screen+Shot+2015-06-04+at+23.04.21.png" width="320" /></a></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
</div>
<div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
CLEAR</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
HOME</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
CANVASCOLOR<span style="color: black;"> </span>BLACK</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FONTSIZE<span style="color: black;"> 36</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FONTSTYLE<span style="color: black;"> </span>BOLD</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">DRAWSTRING</span><span style="color: black;"> </span>"THIS IS TORTUE TEXT"</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Clear of course will erase the canvas. And home will move the turtle to the starting point (center)</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Canvas color will set the background color.</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Drawstring is as you probably guessed to write a text.</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Here's a cool sample app which combines it with PEN COLOR</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
CLEAR</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FONTSIZE<span style="color: black;"> 36</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
FONTSTYLE<span style="color: black;"> </span>BOLD</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">SETX</span> 140</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MAKE</span> color = 10</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
REPEAT<span style="color: black;"> 24</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">PENCOLOR</span> color 0 color 50</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">LEFT</span> 15</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>PENUP</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>FORWARD<span style="color: black;"> 45</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>PENDOWN</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="color: #931a68;">DRAWSTRING</span><span style="color: black;"> </span>"THIS IS TORTUE TEXT"</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> color = color + 10</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
END REPEAT</div>
<div>
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">This produces the following image:</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2QnbNoxVg5f3QGtKJKEpimQ3EvUgeCiq90nWy35CPoKbTC47b9WcgvSfWlvPP73ZoexUkRo88e1XI_Uq1MrmVcjpTL-88GdnETSEy0lm0N8jiV3yJzMOtOwuS9tiVE9AtL03fuZwTJRQ/s1600/Screen+Shot+2015-06-04+at+23.08.17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2QnbNoxVg5f3QGtKJKEpimQ3EvUgeCiq90nWy35CPoKbTC47b9WcgvSfWlvPP73ZoexUkRo88e1XI_Uq1MrmVcjpTL-88GdnETSEy0lm0N8jiV3yJzMOtOwuS9tiVE9AtL03fuZwTJRQ/s320/Screen+Shot+2015-06-04+at+23.08.17.png" width="320" /></a></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Cool ah ?</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">Thanks Tortue :P</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<h3>
<span style="color: black; font-family: Times; font-size: small;">Operations</span></h3>
</div>
<div>
There are a couple of simple mathematical operations to work with numbers.</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">DIVIDE</span> blue = color / 2</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
</div>
<div>
All of this operations have two effects:</div>
<div>
<ol>
<li>Compute a value (on the right)</li>
<li>Assigns that value into a variable (using a reference)</li>
</ol>
<div>
Here are the others:</div>
</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">SUM</span> forwardamount = i + 1</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MULTIPLY</span> green = J * I</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">Here is a sample program which uses SUM</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
CLEAR</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
HOME</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MAKE</span> i = 1</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #931a68;">MAKE</span> color = 200</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
REPEAT<span style="color: black;"> 500</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">MAKE</span> red = color</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">DIVIDE</span> blue = color / 2</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">MAKE</span> green = color</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">PENCOLOR</span> red green blue 255</div>
<div style="font-family: Monaco; font-size: 14px; min-height: 19px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">MAKE</span> forwardamount = 0</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> forwardamount = i + 1</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">FORWARD</span> forwardamount</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>RIGHT<span style="color: black;"> 70</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> i = i + 1</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> color = color + 1</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">IF</span> color > 255</div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>//<span class="Apple-tab-span" style="white-space: pre;"> </span>MAKE color = 200</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> color = 0 + 200 </div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>END IF</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
END REPEAT</div>
</div>
<div>
<br /></div>
<div>
It draws the following:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXHpp5Ni-7HDU8Et3LEf535YnFFkM0k313H9h1hsh7rT7TcqY6t3w-KFIaSiSnGWq_XcX5x3dNZdQmEt0xHN637NdwiQcwahNA_V42Hd0FyePpVa8SOY3doe4-eC9IQL1rnKyAbaFUyic/s1600/Screen+Shot+2015-06-04+at+23.12.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXHpp5Ni-7HDU8Et3LEf535YnFFkM0k313H9h1hsh7rT7TcqY6t3w-KFIaSiSnGWq_XcX5x3dNZdQmEt0xHN637NdwiQcwahNA_V42Hd0FyePpVa8SOY3doe4-eC9IQL1rnKyAbaFUyic/s320/Screen+Shot+2015-06-04+at+23.12.49.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Lets check the grammar:</div>
<div>
<br /></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
OPERATION:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span> SUM</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| SUBTRACT</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| MULTIPLY</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| DIVIDE</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">And they are all pretty similar:</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
SUM: </div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #3933ff;"> 'SUM'</span> targetVariable=[MAKE] <span style="color: #3933ff;">'='</span> valOne=EXPRESSION <span style="color: #3933ff;">'+'</span> valTwo=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
SUBTRACT: <span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #3933ff;"> 'SUBTRACT'</span> targetVariable=[MAKE] <span style="color: #3933ff;">'='</span> valOne=EXPRESSION <span style="color: #3933ff;">'-'</span> valTwo=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
MULTIPLY:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #3933ff;">'MULTIPLY'</span> targetVariable=[MAKE] <span style="color: #3933ff;">'='</span> valOne=EXPRESSION <span style="color: #3933ff;">'*'</span> valTwo=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
DIVIDE:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="color: #3933ff;">'DIVIDE'</span> targetVariable=[MAKE] <span style="color: #3933ff;">'='</span> valOne=EXPRESSION <span style="color: #3933ff;">'/'</span> valTwo=EXPRESSION;</div>
<div>
<br /></div>
<br />
Basically it has a variable reference. Notice that we don't use REFERENCIABLE here, so this means that you can only use MAKE variables and not PARAM. This means that you cannot reassign PARAMeters.<br />
<br />
Then on the right part they are all binary operations, so they have two operands. Each operand is not exclusively a double number but an EXPRESSION.<br />
So that you can SUM 2 with 2, but also 2 + a, or "a + b"<br />
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
</div>
<h4>
<span style="color: black; font-family: Times; font-size: small;">If</span></h4>
<div>
<span style="color: black; font-family: Times; font-size: small;">You should be getting the idea, this is just more of the same.</span></div>
<div>
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">IF</span> color > 255</div>
<div style="color: #4e9072; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>//<span class="Apple-tab-span" style="white-space: pre;"> </span>MAKE color = 200</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #931a68;">SUM</span> color = 0 + 200 </div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>END IF</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;">This is the grammar for the if</span></div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
<span style="color: black; font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
IF:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #3933ff;">'IF'</span> condition=BOOLEAN_EXPRESSION</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>(commands+=SENTENCE)+</div>
<div style="color: #3933ff; font-family: Monaco; font-size: 14px;">
<span style="color: black;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span>'END IF'</div>
<div style="color: #931a68; font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;">And something cool appears here, the BOOLEAN_EXPRESSION's.</span></div>
<div style="font-family: Monaco; font-size: 14px;">
<span style="font-family: Times; font-size: small;"><br /></span></div>
<div style="font-family: Monaco; font-size: 14px;">
BOOLEAN_EXPRESSION:</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>EQUALS</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| GREATER_THAN</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
<span class="Apple-tab-span" style="white-space: pre;"> </span>| LESSER_THAN</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
<div style="font-family: Monaco; font-size: 14px;">
EQUALS: <span class="Apple-tab-span" style="white-space: pre;"> </span>op1=EXPRESSION <span style="color: #3933ff;">'='</span> op2=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
GREATER_THAN: <span class="Apple-tab-span" style="white-space: pre;"> </span>op1=EXPRESSION <span style="color: #3933ff;">'>'</span> op2=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
</div>
<div style="font-family: Monaco; font-size: 14px;">
LESSER_THAN: <span class="Apple-tab-span" style="white-space: pre;"> </span>op1=EXPRESSION <span style="color: #3933ff;">'<'</span> op2=EXPRESSION;</div>
<div style="font-family: Monaco; font-size: 14px;">
<br /></div>
Notice that the rules are pretty similar to the ones for mathematical operations. The operands are in both cases EXPRESSION's.<br />
<br />
And that's it.<br />
This is pretty much all the syntax of the language</div>
<h4>
<span style="font-family: Times; font-size: small;">Full Tortue Syntax and Commands</span></h4>
<div>
For the complete syntax reference of Tortue you can visit:</div>
<div>
<a href="http://tortue.sourceforge.net/index.php?content=Documentation">http://tortue.sourceforge.net/index.php?content=Documentation</a></div>
<div>
<br /></div>
<h3>
Next</h3>
<div>
In the next part we will start to look at the interpreter and how to give some execution meaning to this grammar :)</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/06414934144608751982noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-25583582913960838982015-05-19T19:40:00.004-03:002015-06-05T09:15:44.352-03:00Java Interface Default Methods. What?<br /><br /><a href="http://blog.uqbar-project.org/2014/10/java8-traits-or-mixins-that-is-question.html" target="_blank">In my last post</a> I’ve presented both traits and mixins, with the promise of identifying the Java 8 Interface Default Methods. So, let’s get on it.<br /><br />First of all, if you don’t know what I’m talking about, <a href="http://blog.10pines.com/2014/10/14/mixins-or-traits/">read my previous post</a> -and please ignore the fact that it took me almost half a year to write this second part :)<br /><br />A quick summary:<br /><ul>
<li><b>Mixins</b>: Abstract subclasses. You can call super from inside the mixin, and can define both methods and variables. Mixins automatically solves conflict by linearization (inserting the mixin in the method lookup chain from left to right).</li>
</ul>
<ul>
<li><b>Traits</b>: Allow us to define behaviour outside the class, but don’t define state. The methods defined in the trait «have the same semantics» as the method defined in the class (Flattening property). It’s like they were copied into the class. You have to handle conflicts by yourself.</li>
</ul>
<br />Now we can fully dive into Java Interface default methods, <a href="http://blog.10pines.com/2015/05/19/java-interface-default-methods/" target="_blank">reading the post here</a> :)Lucashttp://www.blogger.com/profile/04884985370999672819noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-24826797197147473292015-03-16T01:20:00.001-03:002015-03-16T01:31:02.742-03:00Overthinking Scala Parsers<div style="text-align: justify;">
Let me start by telling how much I love Scala's <a href="https://github.com/scala/scala-parser-combinators" rel="nofollow">Parsing Combinators</a> framework. I had a nice experience some time ago, working with tools based on very similar ideas on Haskell, and I felt glad to realize that the Scala guys where able to fully maintain the power and simplicity of functional parser combinators while, at the same time, integrate it so gracefully to the object oriented world and Scala's complex type system.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Anyway, I have no intention to write about the framework itself (It's very well documented and it's not hard to find lots of <a href="https://wiki.scala-lang.org/display/SW/Parser+Combinators--Getting+Started" rel="nofollow">tutorials</a> and <a href="http://booksites.artima.com/programming_in_scala_2ed/examples/html/ch33.html" rel="nofollow">examples</a>), but rather focus on sharing our recent experience dealing with some of it's rough edges. There where mainly two particular subjects that, though subtle, I found interesting. One, once you got your parser to work, what can you do to make it nicer? And two, how do you test it?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Imagine you have some code like this one:</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:scala">object AwesomeParser extends RegexParsers {
val foo: Parser[Foo] = ... // Some foo parser
val bar: Parser[Bar] = ... // Some bar parser
val yetMoreParsers = ...
}
</pre>
<br />
<span style="text-align: justify;">For the sake of the post, let's assume that this is a complete, working example. We could also give for granted that the code is very clean and we attend all the common functional good practices such as avoiding side effects and defining larger parsers as the combination of very small and simple ones. Ok, so the logic is working, and the code is clear; what could possibly be wrong?</span><br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Well... Nothing is "wrong" I guess... But there are a couple of things here that I felt kind of unpleasant. For example, let's say that the day comes that I have to add a new parsers defined as one or more foo and one or more bar.</div>
<div style="text-align: justify;">
<br /></div>
<pre class="brush:scala">object AwesomeParser extends RegexParsers {
val manyFoos = foo.+
val foo: Parser[Foo] = ... // Some foo parser
val bar: Parser[Bar] = ... // Some bar parser
val manyBars = bar.+
val yetMoreParsers = ...
}
</pre>
<br />
<div style="text-align: justify;">
This may still look ok, it will even compile just fine, but truth is the <i>manyFoos</i> implementation is broken. Why? Because it references a value not yet initialized. At this point you may be thinking "Oh, God! Just put the <i>manyFoos</i> val at the bottom, you obsessive freak!" and, sure, that would fix this scenario, but once you have a good fifty something parsers with combinations and recursions finding the right spot to place your parsers can be tricky. Besides I don't want to worry about declaring stuff before using it (What am I, a caveman?).</div>
<div style="text-align: justify;">
We could replace all those <i>vals</i> with <i>defs</i>, but that would also introduce some unnecessary overhead, since parsers would have to be combined every single time they are referenced... I find that the most satisfying alternative (in my experience, of course) is to define parsers as lazy initialized values. That way the parsers would get combined one single time, but you can pretty much place them wherever you want to.</div>
<br />
<pre class="brush:scala">object AwesomeParser extends RegexParsers {
lazy val manyFoos = foo.+
lazy val foo: Parser[Foo] = ... // Some foo parser
lazy val bar: Parser[Bar] = ... // Some bar parser
lazy val manyBars = bar.+
lazy val yetMoreParsers = ...
}</pre>
<br />
<div style="text-align: justify;">
Another annoying thing about this implementation is how dirty the interface is. Sure, the code may look clean and easy now, but wait until you get that <i>AwesomeParser</i> object and press <i>ctrl+space</i>...</div>
<div style="text-align: justify;">
As you may notice, my <i>AwesomeParser</i> object extends the <i>RegexParsers</i> trait (though it may have been any other member of the <i>Parsers</i> subtrait family). These traits pretty much define little parsers ecosystems, along with the types and functions needed to manipulate them. Problem is, the amount of methods and types defined is HUGE (and all the parsers we added don't really help the problem). Also, there is no standar entry point. A RegexParser may be executed using the <i>parse </i>or <i>parseAll</i> methods, while a Json parser provides <i>parseFull </i>and <i>parseRaw.</i></div>
<div style="text-align: justify;">
Adding all up, it is quite bothersome for the parser user to navigate this large interfaces looking for the way to execute the parser and ignoring amost everything else. And even when they find the right parse method, most of it's versions require the user to pass along the parser that should be used to parse. For example, our <i>AwesomeParser </i>may be called like this:</div>
<br />
<pre class="brush:scala">AwesomeParser.parse(AwesomeParser.manyFoos,"foofoofoofoo")</pre>
<br />
<div style="text-align: justify;">
Now, lets face it. It is great to have the possibility to chose the parse approach, but most of the time you don't need that many options. On those cases, a simple way to get a cleaner interface for your parser may be to "hide" it's definition in an inner declaration and just expose the messages you want.</div>
<br />
<pre class="brush:scala">object AwesomeParser {
def apply(input: String) = Definition.parse(Definition.manyFoos, input)
protected object Definition extends RegexParsers {
lazy val manyFoos = foo.+
lazy val foo: Parser[Foo] = ... // Some foo parser
lazy val bar: Parser[Bar] = ... // Some bar parser
lazy val manyBars = bar.+
lazy val yetMoreParsers = ...
}
}</pre>
<br />
<div style="text-align: justify;">
One last thing to object about this implementation is that it is pretty much impossible to extend. A singleton object may seem like a great implementation for a parser; it grants global access and probably leads to a healthy stateless implementation, but what if somebody wants to extend it or make a subtle variation on the grammar? Well, why can't we have booth? It is as simple as offering a trait implementation of your parser and make a default singleton instance to extend it. That way you keep all the perks of a global, well-known parser without sacrificing extensibility.</div>
<br />
<pre class="brush:scala">object AwesomeParser {
def apply(input: String) = Definition.parse(Definition.manyFoos, input)
protected object Definition extends AwesomeParserDefinition
trait AwesomeParserDefinition extends RegexParsers {
lazy val manyFoos = foo.+
lazy val foo: Parser[Foo] = ... // Some foo parser
lazy val bar: Parser[Bar] = ... // Some bar parser
lazy val manyBars = bar.+
lazy val yetMoreParsers = ...
}
}</pre>
<br />
<div style="text-align: justify;">
Now lets talk testing. I can't even imagine developing/maintaining a parser without a full set of tests. The thing is that, in my experience, parser tests tend to be much MUCH larger than the parsers themselves and require lots of attention and care. The simpler and more expresive they are, the easier it will be to implement changes to the parsed grammar. That's why we packed a couple of simple tools we developed to improve the parser testing and published them <a href="https://github.com/uqbar-project/parser-test">here</a> for anyone to use.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And that's all I have to say about that.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
N.</div>
Anonymoushttp://www.blogger.com/profile/00350943351653995927noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-22089541851718889372015-01-07T22:08:00.000-03:002015-01-07T22:08:03.729-03:00Review: Probabilistic techniques, data streams and online learning, from Ruminations of a Programmer<br />
<br />
<a href="http://debasishg.blogspot.com.ar/" target="_blank">Ruminations of a Programmer</a> is <a href="https://plus.google.com/+DebasishGhosh/posts" target="_blank">Debasish Ghosh</a>'s blog. He's the author of <a href="http://manning.com/ghosh/" target="_blank">DSL in Action</a> and <a href="http://manning.com/ghosh2/" target="_blank">Functional and Reactive Domain Modeling</a>. <br />
<br />
RoaP is a interesting site with a lot of functional programing in Scala, and pinches of BigData, NoSQL and streaming algorithms. It's very enjoyable, if you like this kind of things, of course.<br />
<br />
The first post of this year, <a href="http://debasishg.blogspot.com.ar/2015/01/probabilistic-techniques-data-streams.html" target="_blank">Probabilistic techniques, data streams and online learning - Looking forward to a bigger 2015</a>, if we oversee the futurology, is a good start point for this kind of problems, with links to readeables introductions to the principal data structures.<br />
<br />
And the perl of the article is a <a href="https://gist.github.com/debasishg/8172796" target="_blank">collection</a> of must-reads from the autor that keeps in his github.<br />
<br />
To read more:<br />
If you like the foundations of the algorithms, and you are the kind of person who love LaTeX, <a href="http://grigory.us/big-data.html" target="_blank">Sublinear Algorithms for Big Datasets</a> is a good place to visit.<br />
<br />
<br />Tulio Ballarihttp://www.blogger.com/profile/02142527919822139862noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-65791491528538624432014-11-05T03:11:00.001-03:002015-01-07T22:08:45.803-03:00Travis, o cómo elegir un CI para tu proyecto Java open sourceRecientemente me incorporé al equipo de desarrollo de <a href="http://arena.uqbar-project.org/">Arena</a>, nuestro framework de MVVM UI pensado para que alumnos de diversas carreras universitarias den sus primeros pasos en el desarrollo de interfases de usuario. Hicimos <a href="http://blog.uqbar-project.org/2014/10/latest-arena-sprint.html">un sprint</a> para empezar a familiarizarnos con las herramientas y ahí detectamos algunos problemas en la forma de trabajo, que dificultaban un poco la incorporación de nuevos desarrolladores.<br />
Los inconvenientes principales eran:<br />
<ul>
<li>Para trabajar en un proyecto (hoy Arena se compone de 7 proyectos distintos) no había otra opción que compilar todos los demás, ya que al no estar sistematizado el deploy no siempre el SNAPSHOT se correspondía con la última versión del código. Entonces perdía un poco de sentido la separación en artefactos distintos.</li>
<li>Algunas veces se pusheaba al repositorio código que rompía los tests, o incluso no compilaba. Al no tener releases estables, podía darse el caso de que un deploy del SNAPSHOT rompiera los trabajos prácticos de los alumnos de una cursada, como sucedió alguna que otra vez.</li>
<li>Los artefactos se desplegaban en un repositorio propio y no en Maven Central, lo que implicaba un paso extra de configuración a la hora de preparar el entorno de desarrollo. Trataremos este tema en el siguiente post de esta serie.</li>
</ul>
¿Cómo solucionar esto? Automatizando estas tareas repetitivas por medio de un servidor de integración continua. No es el propósito de este artículo discutir los beneficios de esta práctica (para eso puede leerse <a href="http://www.dccia.ua.es/dccia/inf/asignaturas/MADS/2013-14/lecturas/10_Fowler_Continuous_Integration.pdf">este artículo de Martin Fowler</a>), así que vamos a pasar directamente a la solución que puse en marcha.<br />
<h2 id="eligiendo-un-ci-para-arena">
Eligiendo un CI para Arena</h2>
Para los ansiosos, la implementación final de lo que contaré a continuación (incluyendo el próximo post) puede verse en el <a href="https://github.com/uqbar-project/arena">repositorio de Arena en GitHub</a>. De todos modos, recomiendo leer cada una de las decisiones que tomé para entender qué es lo que hace el CI cada vez que se sube código nuevo al repositorio.<br />
<h3 id="cis-candidatos">
CIs Candidatos</h3>
Además de que fuera gratuito para Open Source Software (OSS), se necesitaba que cumpliera tres características:<br />
<ol>
<li>que fuera fácil de configurar y que no necesitara hosting propio.</li>
<li>que soportara Java de forma nativa.</li>
<li>que tuviera algún mecanismo para subir el <em>settings.xml</em>, necesario para poder hacer el deploy a Sonatype.</li>
</ol>
Entonces, en ese orden, descarté estos 3 productos:<br />
<ol>
<li><a href="http://jenkins-ci.org/">Jenkins</a>, quizás el más conocido y flexible de los que voy a mencionar, pero con el overhead de tener que hostearlo en servidor propio y configurar todos los plugins.</li>
<li><a href="https://semaphoreapp.com/">Semaphore</a>, que suele ser mi opción preferida, pero como todavía no soporta Java “out of the box” es necesario bajar Maven en cada build.</li>
<li>Y por último, <a href="https://drone.io/">drone.io</a>, donde no encontré cómo solucionar el problema del <em>settings.xml</em>.</li>
</ol>
Finalmente mi elección fue <a href="https://travis-ci.org/">Travis</a>, obviamente en su versión para OSS. <br />
(Un comentario al margen: Travis tiene también una <a href="https://travis-ci.com/">versión para repositorios privados</a> y, gracias a un acuerdo con GitHub, la ofrecen de manera gratuita e ilimitada para estudiantes mediante el <a href="https://education.github.com/pack">student developer pack</a>.)<br />
<h3 id="configurando-travis">
Configurando Travis</h3>
La configuración de Travis está basada en el principio de <a data-new-link="http://www.wikiwand.com/en/Convention_over_configuration" data-noreplace="1" href="http://www.wikiwand.com/en/Convention_over_configuration">convention over configuration</a>. Para empezar a compilar y correr nuestros tests, basta crear un archivo llamado <code>.travis.yml</code> e indicar en su interior en qué lenguaje está realizado nuestro proyecto, en nuestro caso Java. El primer archivo de configuración se veía así:<br />
<pre><code>language: java
</code></pre>
¿En serio? ¿ya está? No del todo, pero ya estamos en condiciones de probar que funciona avisándole a Travis que monitoree el proyecto (esto se hace desde <a href="https://travis-ci.org/profile">tu perfil</a>) y luego haciendo un <code>git push</code> de algún cambio (aunque una mejor idea sería crear una branch de prueba y hacer un pull request). <br />
Por defecto, Travis empezará a monitorear el repositorio y disparará un build por cada commit que se suba a cualquiera de sus branches, incluyendo pull requests. Una vez concluido dicho build, se encargará de notificar a GitHub el resultado, quien a su vez nos lo mostrará a nosotros como se ve en la siguiente imagen:<br />
<img alt="Pull requests validados por Travis" src="https://lh4.googleusercontent.com/-wt4a6wwsLzs/VE8ynKf0OFI/AAAAAAAATpY/LZXtf6ZtcLg/s0/Screenshot+from+2014-10-28+03%253A05%253A30.png" title="Así se ven algunos pull requests validados por Travis :)" /><br />
Con esa simple línea de configuración que le dimos, lo que se ejecuta es el <a href="http://docs.travis-ci.com/user/languages/java/">default para Java</a>, que consta de dos pasos:<br />
<ol>
<li><code>mvn install -DskipTests=true</code>, baja todas las dependencias y compila el proyecto. ¿Y para qué le pone ese flag si también queremos que corra los tests? Cuando algo anda mal, Travis diferencia entre un build <em>errored</em> y uno <em>failed</em>, donde el primer estado está asociado con un error en la instalación (no compila, no se encontró alguna dependencia) y el segundo con alguna validación que se ejecuta (normalmente un test fallido). Entonces si llegara a fallar la instalación, ni siquiera se corren los tests y sabemos con certeza que el resultado es <em>errored</em></li>
<li><code>mvn test</code> (no necesita explicación)</li>
</ol>
Hasta acá llega el primer post de esta duología. En el siguiente post explicaré los pasos necesarios para publicar la aplicación en el <a href="http://search.maven.org/">Maven Central Repository</a>, utilizando <a href="https://oss.sonatype.org/">Sonatype OSS</a> como intermediario.<br />
¡No dejen de compartir sus proyectos, ideas o experiencias en los comentarios!Faloihttp://www.blogger.com/profile/16769596139148943603noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-60939974175039342032014-10-14T15:23:00.000-03:002015-05-19T19:41:43.909-03:00Java8: Traits or Mixins? That is the question<div style="background-color: white; border: 0px; color: #333333; font-family: 'PT Sans', Arial, Georgia, Times, 'Times New Roman', serif; line-height: 1.618rem; margin-bottom: 1.618rem; padding: 0px; vertical-align: baseline;">
A couple of days ago, a discussion came up in one of our mailing list about the <a href="http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html" target="_blank">Java 8 Interfaces Default Methods</a>. They were named as «mixins», but I corrected them and called «traits without flattening».</div>
<div style="background-color: white; border: 0px; color: #333333; font-family: 'PT Sans', Arial, Georgia, Times, 'Times New Roman', serif; line-height: 1.618rem; margin-bottom: 1.618rem; padding: 0px; vertical-align: baseline;">
After sending the mail, that last sentence kept ringing in my head, so I proposed myself to try to understand why was I calling them like that, and I came up with <a href="http://blog.10pines.com/2014/10/14/mixins-or-traits/" target="_blank">this post</a>.</div>
<div style="background-color: white; border: 0px; color: #333333; font-family: 'PT Sans', Arial, Georgia, Times, 'Times New Roman', serif; line-height: 1.618rem; margin-bottom: 1.618rem; padding: 0px; vertical-align: baseline;">
<span style="line-height: 1.618rem;">Please, leave your comments below and don't forget to check the blog for the part 2!</span></div>
<div style="background-color: white; border: 0px; color: #333333; font-family: 'PT Sans', Arial, Georgia, Times, 'Times New Roman', serif; line-height: 1.618rem; margin-bottom: 1.618rem; padding: 0px; vertical-align: baseline;">
<span style="line-height: 1.618rem;">Lucas.-</span></div>
<div style="background-color: white; border: 0px; color: #333333; font-family: 'PT Sans', Arial, Georgia, Times, 'Times New Roman', serif; line-height: 1.618rem; margin-bottom: 1.618rem; padding: 0px; vertical-align: baseline;">
P.S.: If you didn't notice the link above, here it is again :) <a href="http://blog.10pines.com/2014/10/14/mixins-or-traits/">http://blog.10pines.com/2014/10/14/mixins-or-traits/</a></div>
Lucashttp://www.blogger.com/profile/04884985370999672819noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-4018034574464742012014-10-07T12:14:00.000-03:002014-10-07T12:14:04.379-03:00Latest Arena Sprint<span style="font-family: Arial, Helvetica, sans-serif;">The last Saturday, we have had another Sprint of the <a href="http://arena.uqbar-project.org/">Arena Project</a>. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Arena is one of the flagship projects of the Uqbar Foundation. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Arena is an MVVM UI framework that strongly encourages the separation between model and ui classes. Although based on automatic bidirectional bindings and small single-responsability reusable controllers. Through this it clearly shape the core concepts of object design applied to UI-development.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">It also implements a transparent AOP-based mechanism for object-level transactions and observability (object properties). This makes extremely easy the developer tasks in order to bind UI components with domain, by reducing repeatable domain code such as triggering events or handling transactions.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Arena is being used now since 2010 in several Argentinean Public Universities in order to teach the core concepts of object-oriented user interfaces.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The sprint was a really successful, 11 developers gathered to work in the project. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The main objective of the Sprint was the integration of new developers to the project. Everybody getting a working development environment and through the use of pair programming everybody started improving Arena. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The results of the sprint are amazing:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A new Continuous Integration effort has been started. The idea is to have an automatically integrated process to release and publish the changes. Every time a developer submit a change the process is fully automatic.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The whole project was migrated to Scala 2.11.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The documentation has been improved, with all the things the main developer show to everybody.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The site of Arena has been improved and fully integrated with the Maven building process.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">We have started the process to integrate all the repositories and the migration to Git.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also the process to get a copy of Arena into the main central repositories of Maven has been started.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also a number of issues has been resolved and improvements added:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Now you can bind tooltips to the controls</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The window can have a initial size.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The labels resize when the content is longer than previously</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The tables can have a minimal number of rows to show.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can know bind the visible property of panels.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The check boxes can be read only.</span></li>
</ul>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Even though the main idea was to integrate new developers to the project, we could achieve lots of issues and improvements.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Some nice pictures of the people working:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjETeccrlZUH3fhh5nReulurz579dXLR5TZSsUX93QjAN6gJB1YCgyhZjiglYBxNVVpGOcQO1Blb-QV-mX2tU88puQfA-C5sGUpKJjVcK_AEKnVPM9P2u6RJs_wKbTC6pjCSa6OWZE4VU/s1600/10246448_791202444256604_7427873615563044596_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjETeccrlZUH3fhh5nReulurz579dXLR5TZSsUX93QjAN6gJB1YCgyhZjiglYBxNVVpGOcQO1Blb-QV-mX2tU88puQfA-C5sGUpKJjVcK_AEKnVPM9P2u6RJs_wKbTC6pjCSa6OWZE4VU/s1600/10246448_791202444256604_7427873615563044596_n.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1dF2AEY4LjBtvPJl481XXuU_84UdVmFLN_PdhRMc-INhKIc9_ix9E0WzN_pNQWbVZ4ZtUFYpy2my1Tw30VYfyT6txGXGueZlRbABdEHqwVOMLe6gU4gzblcuD5qdHY-R9QxktYqr5E6U/s1600/10383660_791202494256599_1655665487575297999_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1dF2AEY4LjBtvPJl481XXuU_84UdVmFLN_PdhRMc-INhKIc9_ix9E0WzN_pNQWbVZ4ZtUFYpy2my1Tw30VYfyT6txGXGueZlRbABdEHqwVOMLe6gU4gzblcuD5qdHY-R9QxktYqr5E6U/s1600/10383660_791202494256599_1655665487575297999_n.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtOL3D-3DVGPjFsjAOZPHkvanjSZz_PxvYCbD0sCG1ZkAK_DN-DuA4ILI6qbno7FRlC2dkHFqmTbNPpcSzAtZ1JV3X-_-dGOEf1AXYCESaOpYRkiU9cM_mN_vUm7DuriV8d_fNLhde9JY/s1600/10612702_791202497589932_1250873756954343763_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtOL3D-3DVGPjFsjAOZPHkvanjSZz_PxvYCbD0sCG1ZkAK_DN-DuA4ILI6qbno7FRlC2dkHFqmTbNPpcSzAtZ1JV3X-_-dGOEf1AXYCESaOpYRkiU9cM_mN_vUm7DuriV8d_fNLhde9JY/s1600/10612702_791202497589932_1250873756954343763_n.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52Htyz_IeWse-USHSeb79iU5lwiVrjna9wJV2N7OYYmVx2_BSBlNnpRvqn-r4Gf5IAj76BME-AAoVkVKtncSPy3A0HcI6fyyVmGVNrbVGXAW6bB3XdMqZ618AWUOHcRkCaNXRCYhTKUg/s1600/10665777_791202490923266_1103683595417198196_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52Htyz_IeWse-USHSeb79iU5lwiVrjna9wJV2N7OYYmVx2_BSBlNnpRvqn-r4Gf5IAj76BME-AAoVkVKtncSPy3A0HcI6fyyVmGVNrbVGXAW6bB3XdMqZ618AWUOHcRkCaNXRCYhTKUg/s1600/10665777_791202490923266_1103683595417198196_n.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh10UtIRRCjky20vpOY0aa8vuo6AlvEJX1fBaUYJD0TatAYTV8UHJUAZWgi5QrUXzLvV8h2l-VUTVMYY1NaViIQs0k-oHjbjnSqfDhoBNR8mPfsY_vpLsZ1G9ZfALDrcmT0ydh0xDXlktA/s1600/10710880_791202630923252_6769978671870143480_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh10UtIRRCjky20vpOY0aa8vuo6AlvEJX1fBaUYJD0TatAYTV8UHJUAZWgi5QrUXzLvV8h2l-VUTVMYY1NaViIQs0k-oHjbjnSqfDhoBNR8mPfsY_vpLsZ1G9ZfALDrcmT0ydh0xDXlktA/s1600/10710880_791202630923252_6769978671870143480_n.jpg" height="240" width="320" /></a></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/02417806265487074597noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-63583523574772736622014-09-15T22:14:00.001-03:002014-10-01T14:31:08.774-03:00Workshop WISIT 2014 - Convocatoria de Presentación de Trabajos<div style="color: #500050;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: #232323;">La fundación </span><span style="color: #003965;"><b>Uqbar</b></span><span style="color: #232323;">, con el apoyo de
la <b>Universidad Tecnológica Nacional</b> (UTN) FRBA, organiza el <b>Workshop
de Ingeniería en Sistemas y Tecnologías de Información
(WISIT)</b>. </span></span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: #232323;">Se desarrollará los dias <b>28
y 29 de noviembre </b>en </span><span style="color: #222222;">el </span><b style="color: #222222;">Aula Magna de la UTN.BA, ubicada en Av. Medrano 951,
Ciudad Autónoma de Buenos Aires.</b></span></div>
<div>
<span style="color: #232323; font-family: Arial;"><br /></span></div>
<div>
<b style="color: #3d85c6; font-family: 'trebuchet ms', sans-serif; font-size: large;">Mas información </b></div>
<div>
<div>
<div>
<a href="http://www.uqbar-project.org/events/wisit-2014" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-image: url(https://ssl.gstatic.com/sites/p/a09ed8/system/app/themes/solitudeolive/bg_link.gif); background-origin: initial; background-position: initial; background-repeat: repeat-x; background-size: initial; font-family: Arial; font-weight: bold; padding: 2px;" target="_blank">http://www.uqbar-project.org/events/wisit-2014</a>) </div>
<div>
<span style="color: #232323; font-family: Arial;"><br /></span></div>
<div>
<b style="color: #3d85c6; font-family: 'trebuchet ms', sans-serif; font-size: large;">Presentación de Trabajos (call for papers)</b></div>
<ul style="background-attachment: initial; background-clip: initial; background-image: url(https://ssl.gstatic.com/sites/p/a09ed8/system/app/themes/solitudeolive/bg_link.gif); background-origin: initial; background-position: initial; background-repeat: repeat-x; background-size: initial; color: rgb(0, 57, 101) !important; font-weight: bold; line-height: 1.5; padding: 2px;"><ul>
<li><a href="https://sites.google.com/site/proyectouqbar/events/wisit-2014/instrucciones-papers" style="background-attachment: initial; background-clip: initial; background-image: url(https://ssl.gstatic.com/sites/p/a09ed8/system/app/themes/solitudeolive/bg_link.gif); background-origin: initial; background-position: initial; background-repeat: repeat-x; background-size: initial; color: rgb(0, 57, 101) !important; line-height: 1.5; padding: 2px;" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Presentación de Papers para el Track Investigación</span></a></li>
<li><a href="https://sites.google.com/site/proyectouqbar/events/wisit-2014/instrucciones-experiencias" style="background-attachment: initial; background-clip: initial; background-image: url(https://ssl.gstatic.com/sites/p/a09ed8/system/app/themes/solitudeolive/bg_link.gif); background-origin: initial; background-position: initial; background-repeat: repeat-x; background-size: initial; color: rgb(0, 57, 101) !important; line-height: 1.5; padding: 2px;" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Presentación de Charlas para el Track Experiencias</span></a></li>
<li><a href="https://sites.google.com/site/proyectouqbar/events/wisit-2014/instrucciones-handson" style="background-color: #e7e7e7; color: rgb(0, 57, 101) !important; line-height: 1.5; padding: 2px;" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Presentación de Talleres/Tutoriales para el Track Hands
On</span></a></li>
</ul>
</ul>
</div>
<div>
<br /></div>
</div>
Lucas Spigariolhttp://www.blogger.com/profile/15615574267218290352noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-43737824548743992742013-10-10T09:11:00.003-03:002013-10-15T13:46:38.614-03:00Uqbar Workshop'13 (Español)<br />
La fundación Uqbar y la Universidad Nacional de San Martín orgullosamente los invitamos a participar en la primera edición del workshop.<br />
Su principar objetivo es generar un espacio para comunicar, compartir y discutir entre profesionales del área, orientado a la innovación e investigación. El workshop será <b>el 16 de noviembre de 9hs a 18hs en la Universidad de San Martín</b>, Provincia de Buenos Aires, Argentina.<br />
La asistencia y participación en el workshop es gratuita. Sin embargo, pedimos una subscripción al evento para asegurar el lugar y recursos necesarios para llevarlo a cabo.<br />
<br />
Si además presentás una charla, llená el formulario para proponer la charla y lo tendremos en cuenta.<br />
Más información en:<a href="http://www.uqbar-project.org/events/workshop2013">http://www.uqbar-project.org/events/workshop2013</a>Anonymoushttp://www.blogger.com/profile/02417806265487074597noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-7611860190434517962013-10-09T17:53:00.003-03:002013-10-10T09:17:16.861-03:00Uqbar Workshop'13 (English)The Uqbar Foundation and the Universidad Nacional de San Martín proudly invite you to participate in the first edition of the Uqbar Workshop.<br />
Its main objective is to generate an space for communication, sharing and discussion between professionals in the area, oriented to innovation and research. The workshop will be held on november 16, from 9hs to 18hs, in Universidad de San Martín, Provincia de Buenos Aires, Argentina.<br />
<br />
Assistance and participation in the workshop is for free. However, we'd like to ask you for a minimal subscription to account places and resources to locate.<br />
<br />
If you will present a talk in addition, just fill the talk submission form and we will account you from there.<br />
<br />
More information in: <a href="http://www.uqbar-project.org/events/workshop2013">http://www.uqbar-project.org/events/workshop2013</a>Anonymoushttp://www.blogger.com/profile/02417806265487074597noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-55301258600268516852013-09-21T23:39:00.000-03:002013-09-21T23:40:14.765-03:00Type-safe bindings (reflection) for Arena<h2>
Arena </h2>
Arena is UI framework strongly based on a pure MVC pattern through bindings and the ApplicationModel idea.<br />
<br />
The UI elements are connected to the model through bindings, which are in charge of propagating changes between the two parties. If the model changes, then it will update the ui (view), and of course if the view changes because of user interaction (like changing a textbox value) then it will also change the model.<br />
This simple idea reduces a lot of UI code, and introduces a new way for developing UI's.<br />
Plus the fact that Arena makes your model object observables, transparently by means of AOP.<br />
<br />
<h2>
Sample Distance Converter Application</h2>
<br />
Here's a sample really small app whose functionality is to convert miles to kilometers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4u9pbI98kzOGYpnLdE-8VFPARKkUApe_UCY0OaMrMmJhj1lh8g88OjgVXLZHTrc4FXdF2rTRSUPmBHic4sACNBHYk-UV9gV-cigoebtFQDaXJk9RFTs4NwFgBbKAmBr3n1JBSVWSbe2A/s1600/Screenshot+from+2013-09-21+22:27:14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4u9pbI98kzOGYpnLdE-8VFPARKkUApe_UCY0OaMrMmJhj1lh8g88OjgVXLZHTrc4FXdF2rTRSUPmBHic4sACNBHYk-UV9gV-cigoebtFQDaXJk9RFTs4NwFgBbKAmBr3n1JBSVWSbe2A/s1600/Screenshot+from+2013-09-21+22:27:14.png" /></a></div>
<br />
Here's the model (in xtend language):<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">@Observable<br /><span style="color: #990000;"><b>class</b></span> DistanceConverter {<br /> @Property Double miles<br /> @Property Double kilometers <br /> <br /> <span style="color: #990000;"><b>def</b></span> convert() {<br /> kilometers = miles * 1.60934<br /> }<br />}</span><br />
<br />
And here's the View, in terms of control objects.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span></span> DistanceConverterWindow </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span><b> </b>MainWindow<DistanceConverter> {<br /> <br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span>() { </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>super</b></span></span></span>(</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> DistanceConverter) }<br /><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>override</b></span></span></span> createContents(Panel mainPanel) {<br /> title = <span style="color: blue;">"Miles To Kilometer Converter"</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> mainPanel.layout = </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span><b> </b>VerticalLayout <br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> Label(mainPanel).text = <span style="color: blue;">"Input in miles"</span><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> TextBox(mainPanel)<br /><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> Button(mainPanel) => [<br /> caption = <span style="color: blue;">"Convert"</span><br /> ]<br /><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> Label(mainPanel) => [</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> background = Color.ORANGE</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> ]<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span> Label(mainPanel).text = <span style="color: blue;">" km"</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><br />}</span><br />
<br />
As you are probably thinking or maybe wondering, this is not the actually functional View implementation.<br />
It is not actually <b>connected</b> to the model. If we start this app it will indeed show pretty much as the one on the screenshot but clicking on the button won't do anything. Changing the textbox neither. And we'll never actually see any converted kilometers.<br />
<br />
That's because we are missing the <b>Bindings</b>. The stuff that glues together view + model.<br />
<br />
<h2>
Bindings</h2>
<br />
As you can see the UI is a direct view of the domain. Whenever the user changes the value of the textbox it will modify the "miles" <b>property</b>. When he presses the button it will call the "convert" method which doesn't receive any parameter (the converter already knows the input miles), and also doesn't return anything (because the converter also "remembers" the converted km value, it's one of its responsabilities).<br />
<br />
All this wiring between the UI and the model is done through bindings.<br />
Here's a sample drawing:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qLVDG0Q-nkdlU8QotL6YmJ-uRqDuW-asXTM00ycbclWquMiJoB327EDNL5jx8XCqXXa84HxzTrf03E2-yqWPVpSCJNrP6MHciYd8AIKg5YIDf5xh9U8Z95EdJJy2KdXgbbpEcqdc0M4/s1600/arena-converter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qLVDG0Q-nkdlU8QotL6YmJ-uRqDuW-asXTM00ycbclWquMiJoB327EDNL5jx8XCqXXa84HxzTrf03E2-yqWPVpSCJNrP6MHciYd8AIKg5YIDf5xh9U8Z95EdJJy2KdXgbbpEcqdc0M4/s320/arena-converter.png" width="320" /></a></div>
<br />
Now lets change the UI code in order to express this bindings.<br />
<br />
The textbox value will be sync'd with the "millas" property from the model<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span> TextBox(mainPanel) => [<br /> bindValueToProperty(<span style="color: blue;">"miles"</span>)<br /> ]</span><br />
<br />
The background colored label is also bound to the "kilometers" property. This time as the label is a "read-only" ui control it won't ever change the value from the model, it will just display it.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span> Label(mainPanel) => [<br /> background = Color.ORANGE<br /> bindValueToProperty(<span style="color: blue;">"kilometers"</span>)<br /> ]</span><br />
<br />
And at last the button's on click should execute the model's "convert" method.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span> Button(mainPanel) => [<br /> caption = "Convert"<br /> onClick [ | </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>this</b></span></span></span></span></span>.modelObject.convert ]<br /> ]</span><br />
<br />
Here we sue the power of xtend blocks/closures :)<br />
<br />
<h2>
Bindings, Reflection & Strings</h2>
Probably you are familiar with this kind of code. Frameworks are generic pieces of software, that provide some sort of functionality or lifecycle. But they don't do anything along. You "use" them. Or actually they "use" your code/objects. But anyway, eventually you need to instruct them in order to use your objects.<br />
Because they know how to handle any object, but none in particular.<br />
<br />
So they use metaprogramming techniques, and specifically Reflection API's in order to manipulate your objects.<br />
Some examples of this are hibernate where you instruct it by means of mappings, for example in xml, or in the form of annotations. Or spring framework's xml, etc.<br />
<br />
In our example Arena uses reflection for the bindings, in particular for reading and modifying the model's properties.<br />
<br />
One of the big drawbacks of reflection in java is that there's no way to refer to a property in a safe way. The only way is to use a string, whose value is the "name" of property or method.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">bindValueToProperty(<span style="color: blue;">"miles"</span>)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
So, what's the problem with it ?<br />
Well, that you are in a statically compile-time checked language, but the compiler won't be able to help you on this one.<br />
For it the "miles" is just that, a string. So it won't check if it's actually a valid property name, or if it exists a getMiles() method in the model class.<br />
<br />
If you are building a middle/big sized application, and all the windows, panels and controls binds themselves in this way then you'll face a maintenance complexity.<br />
For example:<br />
<ul>
<li>if you change the name of the model's property in a refactor, then the IDE won't be able to help you changing this strings. And this will blow-up in runtime.</li>
<li>if you want to lookup references to a given method or property, then again the IDE won't help you. Then you might think that a property is not used by anyone, and go ahead and delete it. Again.. booom! only at runtime. Lucky you if you catch it before your user =)</li>
</ul>
So well, this is pretty bad ! But indeed we don't want to lose reflection. It's a very powerful mechanism !<br />
<br />
<h2>
Avoiding String problems when using reflection using constants</h2>
There are some tricks to tackle this problem list having the string declared as a constant string in only one place.<br />
For example:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span></span></span> DistanceConverter {<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>public static </b></span></span></span></span></span>String MILES = <span style="color: blue;">"miles"</span><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>public static</b></span></span></span></span></span></span> String KILOMETERS = <span style="color: blue;">"kilometers"</span><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>public static</b></span></span></span></span></span></span> String CONVERT = <span style="color: blue;">"convert"</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> ...</span><br />
<br />
And now from the UI:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span> TextBox(mainPanel) => [<br /> bindValueToProperty(<b>DistanceConverter.MILES</b>)<br /> ]</span><br />
<br />
So now we can look up references to the constant for usages. Also if we change the name of the property we'll only have to change the string value in on place, the constant.<br />
<br />
But this still not perfect.<br />
There's a better way :)<br />
But first we need to see some other idea.<br />
<br />
<h2>
What's the mocking frameworks approach</h2>
Mocking frameworks face some similar problem. By nature they need to work with our own defined classes, but they cannot be coupled to them, of course. They don't know anything about our DistanceConverter for example.<br />
But also they don't know what to expect and assert, so you need to instruct them.<br />
<br />
But instead of using reflection with strings or a complicated API for expressing the expected behavior they use a quite interesting idea.<br />
For example <a href="http://code.google.com/p/mockito/" target="_blank">Mockito</a>...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://mockito.googlecode.com/svn/wiki/images/stubbing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="http://mockito.googlecode.com/svn/wiki/images/stubbing.png" width="400" /></a></div>
What's interesting here is the line:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">when(<b>mockedList.get(0)</b>).thenReturn("first");</span><br />
<br />
We are not actually interested in executing the "mockedList.get(0)". Instead we are "instructing" mockito telling him "when some calls the "get" method with a "0" as parameter, then you need to return the "first" string).<br />
<br />
A normal string based reflection approach would be:<br />
<br />
whenSomeoneCalls(<b>"get"</b>).on(mockedList).with(0).thenReturn("first")<br />
<br />
(and this is still actually a good fluent API, could be really worst).<br />
<br />
So, in conclusion, they found a way of actually using the type information and therefore the compiler in a statical way, to instruct a framework.<br />
<br />
So the whole idea of this post was to get here. Can we do that same thing for Arena bindings ?<br />
<br />
<h2>
Type-Safe Arena Bindings</h2>
Yes we can !<br />
This is just a really draft proof of concept that was done just in 30 minutes, so there's still a lot of work to be done, and many things to think about.<br />
Let's get directly to the code:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span> TextBox(mainPanel) => [<br /> bindValue(</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>this</b></span></span></span></span></span></span>, [ miles ])<br /> ]</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"> ...</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span> Label(mainPanel) => [<br /> background = Color.ORANGE<br /> bindValue(</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>this</b></span></span></span></span></span></span>, [kilometers])<br /> ]</span><br />
<br />
Compare to the previous version. This one doesn't have any string for "miles" and "kilometers".<br />
<br />
The new "bindValue" method receives an xtend block whose first and only parameter is the window's model object (that gets bound by means of generic types).<br />
<br />
So [ miles ] here can be read as<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">[ it.miles]</span><br />
<br />
Or<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">[ converter | converter.miles ]</span><br />
<br />
Or even in the longest way<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">[ DistanceConverter converter | converter.miles ]</span><br />
<br />
So in case you didn't notice this is code. We have a line of code that calls the "miles" property, and therefore it gets checked by the compiler.<br />
<br />
But it's actually a trick. Pretty similar to the one that Mockito uses.<br />
This code is not actually executed to get the property. We are not writting "[ miles ]" to execute it right away, but just to "instruct" arena "miles is the property I want you to bind to".<br />
<br />
And it works flawlessly ! :)<br />
<br />
In case you are interested in the implementation, what the "bindValue" does is:<br />
<ul>
<li>receives your block</li>
<li>it gets the actual model (the converter) and with its class, it creates a new proxy instance. Kind of a "ghost" object of the same class.</li>
<li>it then calls your block with that proxy.</li>
<li>Your code sends the message "miles" (actually getMiles()).</li>
<li>The proxy "records" all the methods you called into it.</li>
<li>So, after the block finishes up, the next thing the bindValue does is to ask the proxy "hey, what property the guy accessed ?".</li>
<li>In this case the proxy will tell "the miles property",</li>
<li>"Ah.. ok, then we need to bind to that one.</li>
</ul>
It's not as black magic as one thinks initially looking at Mockito. And it's all there. Just enter the "when" method and explore some code !<br />
<br />
<h2>
Further work </h2>
We still need to work on this, because we will like to add this feature to Arena's new version.<br />
There are still many things to think about, like what if the developer writes some side-effect weird or long lines of code in the block ?.<br />
How to support nested properties ? Like [ customer.address.street.number ]<br />
Etc.<br />
We should also remove the first parameter "this" on the bindValue method, but that's not easy because we will lose the typing of the closure (now bound to the window's generic type, the model class).<br />
<h2>
More about Arena</h2>
If you are interested in Arena framework here are a couple of links:<br />
<ul>
<li><a href="http://arena.uqbar-project.org/uqbar-scala-parent/arena/" target="_blank">Maven generated site</a> </li>
<li><a href="http://code.google.com/p/uqbar-arena/" target="_blank">Google code site</a> </li>
<li><a href="http://xp-dev.com/svn/uqbar/examples/ui/arena/" target="_blank">Samples (svn)</a> </li>
<li><a href="https://sites.google.com/site/programacionui/material/herramientas/arena" target="_blank">More info</a> (sorry this one is only in Spanish at the moment)</li>
</ul>
Anonymoushttp://www.blogger.com/profile/06414934144608751982noreply@blogger.com0tag:blogger.com,1999:blog-6739892643840943427.post-62712370615069614362013-09-05T16:32:00.001-03:002013-09-06T08:35:43.903-03:00Extending classes with polymorphic extension methods in XTend<br />
<br />
This is a purely just "playing-around" post.<br />
<br />
In <a href="http://www.uqbar-project.org/" target="_blank">Uqbar Project</a> we are now using several new languages both as part of teaching programming in a couple of universities, but also as one of our main/many languages of development for research projects.<br />
<br />
But I'm not going to bore you with that right now. Probably this will be the start of a series of post related to this language (an why not some other regarding scala and groovy) and rethinking our programming practices and design decisions with its particular mechanisms.<br />
At the end maybe some kind of summary post.<br />
<br />
Anyway back to the original point then I wanted to try out extension methods.<br />
But not just adding methods to a class. That's easy. Beyond just methods, OOP most important feature is polymorphism. So, how extension methods relates to polymorphism ??<br />
<br />
Then, wait, maybe you are wondering what's this extension method thing ?<br />
<br />
<h2>
Extension Methods Explained</h2>
<br />
For those who are not familiar with the term <b>extension methods</b> <i>is a language-level support for defining new behavior (methods) for existing classes, without actually touching the original classes.</i><br />
And of course, then use those as regular methods.<br />
<br />
Usually this takes the form of a method whose first parameter is the target object. Belonging to the class we are extending.<br />
<br />
For example you could add a "toCamelCase" method to the String class with something like this:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> def</b></span> String toCamelCase(String aString) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"> // .... </span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<br />
And then call it on any string:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> println(<span style="color: #0b5394;">"Hi there"</span>.toCamelCase())</span><br />
<i> </i><br />
<br />
<br />
There are several different implementations of this concepts in many languages.<br />
But they are not always exactly the same and don't give you the same posibilites (power)<br />
For example C# <b>"Extension Methods" </b>can only be defined as static methods.<br />
<br />
<h2>
Adding polymorphic Extension Methods</h2>
<br />
So enough of introduction. Maybe we will create a separated post to compare the different extension method mechanisms in several languages.<br />
And we could create another post just to talk about xtend's extension methods.<br />
<br />
Adding a method to a class is great as you have seen to add some kind of "atomic" functionality. Like all utility classes that we use like CollectionUtils, ReflectionUtils, ListUtils, etc.<br />
<br />
Now, can we use it to add polymorphic behavior ??<br />
<br />
The short answer is ... <u><b>YES</b></u> !<br />
<br />
<br />
<h3>
Long answer: extension methods + multimethods</h3>
<br />
<i>This can be achieved <u><b>by combining extension methods with multiple dispatch,</b></u> another nice feature of xtend.</i><br />
<br />
Remember that the target object is the first parameter of the extension method.<br />
Also remember that multiple dispatch is the ability to select the method implementation based on the actual type of the arguments.<br />
<br />
So they complement each other quite well.<br />
<br />
We can create an extension method, which is actually a set of different methods one for each target type (first argument).<br />
Then call it as if it was a regular method with different implementations on each class. Like a regular polymorphism with classes overriding.<br />
<br />
And here's a piece of code that demonstratse it.<br />
<br />
Suppose we have some kind of <a href="http://es.wikipedia.org/wiki/Candy_Crush_Saga" target="_blank">CandyCrush</a> object model.<br />
There are Candy's and different classes for Movements (Move): to go North (move up a candy), go South, East, and West.<br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> Move {<br /><span style="color: #38761d;"> //...Some behavior here</span><br />}</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> North </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span> Move { <span style="color: #38761d;">/* ... */</span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> South </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move { </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> East </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move { </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> West </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move { </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span><br />
<br />
<br />
A candy has a coordinate and knows how to move itself a delta (x-delta, and y-delta)<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span> Candy {<br /> @Property Pair<Integer, Integer> coordinates;<br /><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def</b></span></span> move(</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>int</b></span></span> deltaX, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>int</b></span></span> deltaY) {<br /> coordinates = </span><br />
<span style="font-family: "Courier New",Courier,monospace;">coordinates.key + deltaX -> coordinates.value + deltaY<br /> }<br />}</span><br />
<br />
Suppose the "Move" class don't actually have a method to move a candy (ok, sounds silly, but just for the sake of the example).<br />
<br />
We will like to add a new method ----> Ahá !, Extension methods !!<br />
But wait, each Move subclass will have a different implementation ! We need polymorphism !!! -----> Ahá!, Multiple dispatch !<br />
<br />
So we will like to do this:<br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> def static void</b></span> main(String[] args) {<br /> <span style="color: #990000;"><b>val</b></span> candy = <span style="color: #990000;"><b>new</b></span> Candy => [ coordinates = (0 -> 0) ]<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> Use().moveIt(candy)<br /> }<br /> <br /> <span style="color: #660000;"><b>def</b></span> moveIt(Candy candy) {<br /> #[</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> North, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> East, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> South, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> West]<br /> .forEach[<br /> m| <span style="color: red;">m.moveCandy(candy)</span><br /> println(candy.coordinates)<br /> ]<br /> }</span><br />
<br />
<br />
The "moveCandy" is the actual polymorphic method that we want to add.<br />
<br />
And it's defined in an extension class:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span> CandyExtensions {<br /> <br /> <span style="color: #990000;"><b>def dispatch void</b></span> moveCandy(North north, Candy candy) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, 1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> <span style="color: #990000;"><b>def dispatch void</b></span> moveCandy(South north, Candy candy) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, -1)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> <span style="color: #990000;"><b>def dispatch void</b></span> moveCandy(West north, Candy candy) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(-1, 0)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> <span style="color: #990000;"><b>def dispatch void</b></span> moveCandy(East east, Candy candy) {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(1, 0)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br />}</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">Eclipse's tooltip helps to see this:</span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVjsq2iwME67C3nk5BcW18mFk0oG91xK4XTWr22EBdVTGw1Devp-r2-FrXbEFKMmQY_EZl37lAtv2YqgsxTg3oa82LH9rSRHcucs4HiVCb6OB5EEX9akWAZ9nFKGfaHP4KC3U94DvoRow/s1600/Screenshot+from+2013-09-05+14:09:46.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVjsq2iwME67C3nk5BcW18mFk0oG91xK4XTWr22EBdVTGw1Devp-r2-FrXbEFKMmQY_EZl37lAtv2YqgsxTg3oa82LH9rSRHcucs4HiVCb6OB5EEX9akWAZ9nFKGfaHP4KC3U94DvoRow/s320/Screenshot+from+2013-09-05+14:09:46.png" width="320" /></a></div>
<br />
<h2>
<span style="font-family: Arial,Helvetica,sans-serif;">Regular solution without extension methods</span></h2>
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">So even if we coded several methods (4), conceptually we have just added one method and several implementations for concrete types.</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;">Without extensions it would be something like this:</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: Arial,Helvetica,sans-serif;"></span></span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> Move {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> def void</b></span> moveCandy(Candy candy) </span></span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> North </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span> Move {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>override</b></span></span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> void</b></span> moveCandy(Candy candy) {</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, 1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> South </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move {</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>override</b></span></span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> void</b></span> moveCandy(Candy candy) {</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, -1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"></span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> East </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move {</span><span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>override</b></span></span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b> void</b></span> moveCandy(Candy candy) {</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(1, 0) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> West </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span> Move {</span><span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #990000;"><b>override void</b></span> moveCandy(Candy candy) {</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(-1, 0) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><br />
<br />
Not it's actually 5 methods, 4 impl + the abstract declaration in Move<br />
<br />
<h2>
Limitations</h2>
That sounded great !! I can add polymorphic method to existing classes.<br />
But can I do it to any class ?<br />
Can I, from the outside, make two different classes polymorphic in respect to a new method ?<br />
Yes, you can, but it will have some drawbacks.<br />
<br />
In our example we added a polymorphic behavior to classes which already where polymorphic as part of being in the same hierarchy.<br />
<br />
But what if they weren't ? What if they were just completely different classes with no hierarchy ?<br />
<br />
Let's remove the Move class:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> North </span><span style="font-family: "Courier New",Courier,monospace;">{ <span style="color: #38761d;">/* ... */</span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> South </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span>{ </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> East </span><span style="font-family: "Courier New",Courier,monospace;">{ </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span> West </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span>{ </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">/* ... */</span></span> }</span> <br />
<br />
<br />
Well there's still a multiple-dispatch method. That's fine.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDbj1JckE3FREtT6utybVWRbuQyVC6HhrEQ79OVU9crobkOrkA_I1n6IY9ko4tAGcaIPrKZ0U9Elz6rCWmKeDBMp0dzbCMaLpFvxqRu8Qyc5Ewc9M-uxezHZRpOwLOPSQaUlg-zqX5g9M/s1600/Screenshot+from+2013-09-05+16:02:15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDbj1JckE3FREtT6utybVWRbuQyVC6HhrEQ79OVU9crobkOrkA_I1n6IY9ko4tAGcaIPrKZ0U9Elz6rCWmKeDBMp0dzbCMaLpFvxqRu8Qyc5Ewc9M-uxezHZRpOwLOPSQaUlg-zqX5g9M/s320/Screenshot+from+2013-09-05+16:02:15.png" width="320" /></a></div>
<br />
<br />
It's just that it applies to any Object.<br />
Mmm... that's not good, but, well.. at least it's there and it still can be used in our main !<br />
<br />
<br />
But what then if we call it with something else:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #660000;"><b>def</b></span> moveIt(Candy candy) {<br /> #[</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> North, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> East, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> South, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span> West, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><b>new</b></span> Banana</span></span>]<br /> .forEach[<br /> m| m.moveCandy(candy)<br /> println(candy.coordinates)<br /> ]<br /> }</span><br />
<br />
Of course.. boom !<br />
<br />
<span style="color: red;"><span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">Exception in thread "main" java.lang.IllegalArgumentException: <b>Unhandled parameter types: [org.uqbar.xtend.playground.extensionpolymorphism.Banana@51d92803,</b> org.uqbar.xtend.playground.extensionpolymorphism.Candy@7d206f0]<br /> at org.uqbar.xtend.playground.extensionpolymorphism.Extensions.moveCandy(Extensions.java:44)<br /> at org.uqbar.xtend.playground.extensionpolymorphism.Use$3.apply(Use.java:54)<br /> at org.eclipse.xtext.xbase.lib.IterableExtensions.forEach(IterableExtensions.java:399)<br /> at org.uqbar.xtend.playground.extensionpolymorphism.Use.moveIt(Use.java:59)<br /> at org.uqbar.xtend.playground.extensionpolymorphism.Use.main(Use.java:43)</span></span></span><br />
<br />
So, in conclusion, you could add polymorphic methods to unrelated classes, but as you won't have any common type to bound it with, it will kind of confusing to use, and you'll need to be careful when using it. Kind of what happens with languages with run-time message checking (instead of compile-time) <br />
<br />
<br />
<h2>
Further Questions and Relation to other Concerns</h2>
<h4>
AOP</h4>
An advantage of the polymorphic extension methods approach is that of course, it allows to add that behavior from outside of the class. Sometimes you cannot change the original classes.<br />
But also another one (that could also be seen as a disadvantage) is that it groups together all the "move" behavior into a single place. Kind of a <b>concern applied in AOP</b>.<br />
<br />
<h4>
Visitor</h4>
<br />
<br />
This effect is also similar and sometimes part of the intention also present in the <b>Visitor Pattern</b>. Where the visited class only knows how to transverse each other in a general algorithm, then each visitor implements the actual logic for each visited class in a custom method. In order for this to work you need to simulate multimethods with double-dispatch.<br />
<br />
So what happens with the visitor pattern now that we have multimethods, but also we can combine them with extension methods to actually "inject" the polymorphic behavior ?<br />
Does it still make any sense ?<br />
<h4>
Structural Types and Duck-Typing</h4>
<br />
Last, we have saw that you can use this mechanism even for unrelated classes, but then you end up using Object, because you can add methods from outside, but you cannot change the type hierarchy or force classes to start implementing interfaces (like for example in AOP with weaving).<br />
Related to this, there languages like Scala which implement a duck-typing in a strongly typed environment (checks on compile-time). These are a form of <a href="http://en.wikipedia.org/wiki/Structural_type_system" target="_blank">StructuralTypes</a>.<br />
Through extensions we have actually defined some kind of new "structural type". A new type which represents objects which can "move a candy".<br />
<br />
Why should we type any other method that receives such an object via parameter with "object" ?<br />
Would it make sense (or be possible) to introduce new types, using the extension type itself as a nominal type on top of the structural type defined by the extension methods ?<br />
<br />
Would it be possible to combine ext.methods + multiple-dispath + duck typing ?<br />
<br />
If you check our Extension class after we've removed the hierarchy you'll see that there's enough information for a clever compiler to see our modified main and know that it will fail !<br />
It just needs to inspect all the dispatch methods to know which types are valid and which one are NOT !<br />
Banana isn't a valid type.<br />
<br />
This opens up a new world to explore !! :)<br />
<br />
<br />
<h4>
Different Extensions implementations</h4>
<br />
Extensions
don't need to be static methods (as in C#) therefore they are
implemented in instances of a class. Therefore, into an object.<br />
But then you just call with the first arg as target.<br />
Eventually there's an automatic delegation or dispatch to the method into the <b>extension object instance</b> that you have (from the piece of code you are calling it).<br />
<br />
The
extension itself is an object and a regular class, therefore you could
create a hierarchy an use polymorphism, having different sets of
implementations for the extension themselves.<br />
<br />
Here's a silly new implementation for our extensions introducing a hierarchy:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>abstract class</b></span></span></span> AbstractExtensions {<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def void</b></span></span></span></span> moveCandy(Move north, Candy candy)<br />}</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span></span></span> ExtensionImpl </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span></span> AbstractExtensions {<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span> moveCandy(North north, Candy candy)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, 1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span> moveCandy(South north, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, -1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span> moveCandy(West north, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(-1, 0) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span> moveCandy(East east, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(1, 0)</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span></span></span></span> InversedExtensionImpl </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>extends</b></span></span></span></span></span> AbstractExtensions {<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span></span> moveCandy(North north, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, -1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span></span> moveCandy(South north, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(0, 1) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span></span> moveCandy(West north, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(1, 0) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def dispatch void</b></span></span></span></span></span></span></span> moveCandy(East east, Candy candy) { </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> candy.move(-1, 0) </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;">}</span> <br />
<br />
Then in our main or piece of code that actually uses the moveCandy method we can control the real implementation of the set of methods:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>class</b></span></span></span></span></span></span></span></span> Use {<br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>var</b></span></span></span></span></span></span></span></span> extension AbstractExtensions myExtensions = </span><span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><b>new</b></span></span></span></span></span></span></span> ExtensionImpl<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>def</b></span></span></span></span></span></span></span></span> moveIt(Candy candy) {<br /> #[</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span> North, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> East, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> South, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> West]<br /> .forEach[<br /> m| m.moveCandy(candy)<br /> println(candy.coordinates)<br /> ]</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> println(<span style="color: #134f5c;">"----------: new extension impl"</span>)<br /><span style="color: #38761d;"> //change IT !</span><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>this</b></span></span></span></span></span></span></span></span>.myExtensions = </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span></span></span> InversedExtensionImpl</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> #[</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span> North, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> East, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> South, </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>new</b></span></span></span></span></span></span></span> West]<br /> .forEach[<br /> m| m.moveCandy(candy)<br /> println(candy.coordinates)<br /> ]</span> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"> /* ... main ...*/</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;">} </span><br />
<br />
In this case we have it just hardcoded there in the initialization. But the extension instance could be injected. Also note that we are also changing the extension instance with the new one.<br />
This prints:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">0->1<br />1->1<br />1->0<br />0->0<br />----------: new extension impl<br />0->-1<br />-1->-1<br />-1->0<br />0->0</span><br />
<br />
Therefore just by changing the reference to the extension (like if it was a prototype's parent object) we change the implementation of all methods that affects several classes (North, South, etc). Also kind of changing an aspects implementation.Anonymoushttp://www.blogger.com/profile/06414934144608751982noreply@blogger.com0