tag:blogger.com,1999:blog-350921342024-03-08T01:22:23.458+01:00Just my thoughtsA little bit on new technologies, software architecture, programming languages and whatever else.miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.comBlogger209125tag:blogger.com,1999:blog-35092134.post-9978663470816481462012-03-26T23:15:00.000+02:002012-03-27T00:44:39.014+02:00Migración completada<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4J8J60Wymp5KYxEQdIikH3Lz6RCHn2Hk-L5jWmpzbDNGQDGDk-fzSRs11dg-Vm1Ks8UvaNs3n-BNOUHO1d5n5KSZnBovRIoIYlV5NBkFRmSxjrxZNqQZTRTT61BrAz75LI5a-/s1600/Done.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4J8J60Wymp5KYxEQdIikH3Lz6RCHn2Hk-L5jWmpzbDNGQDGDk-fzSRs11dg-Vm1Ks8UvaNs3n-BNOUHO1d5n5KSZnBovRIoIYlV5NBkFRmSxjrxZNqQZTRTT61BrAz75LI5a-/s320/Done.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
Finalmente he terminado la migración del blog. No es que fuera una gran tarea pero siempre me han surgido "mejores cosas" que hacer. Mantendré este blog activo durante unas semanas y posteriormente lo eliminaré por completo.</div>
<br />
A partir de ahora el blog estará alojado en la siguiente dirección:<br />
<h3 style="text-align: center;">
<a href="http://migue.github.com/">http://migue.github.com/</a></h3>
por lo que NO habrá más entradas en este blog.<br />
<br />
Hasta pronto!<br />
<br />
Miguemiguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-20492241288365785282012-03-09T00:35:00.000+01:002012-03-09T00:35:03.846+01:00Migrando el blogO al menos intentándolo . . .<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.apu.edu/blog/wp-content/uploads/2012/02/under-construction_l9wi2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.apu.edu/blog/wp-content/uploads/2012/02/under-construction_l9wi2.jpg" /></a></div>
<br />
<br />
Estos días no he escrito nada por aquí porque he estado barajando la posibilidad de migrar el blog a una plataforma que me permita una mayor versatilidad a la hora de escribir. Mi idea es que el nuevo blog esté aloajdo en mi cuenta de GitHub: <a href="http://migue.github.com/">migue.github.com</a>.<br />
<br />
Espero que la migración no sea demasiado complicada y que pueda tener el blog operativo cuanto antes.<br />
<br />
Cuando el proceso de migración esté completado avisaré por aquí. Mientras tanto no creo que postee nada nuevo por aquí!<br />
<br />
Espero tener noticias cuanto antes!<br />
<br />
Miguemiguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-71078905255360150502012-02-25T12:02:00.000+01:002012-02-25T12:02:03.572+01:00Mi visión del Spring I/O 2012<br />
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
Dicen qu<span style="font-size: 13px;">e más vale tarde que nunca así que, aunque con un poco de retraso, aquí va vi visión del Spring I/O de este año.</span></div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
<span style="font-size: 13px;"><br /></span></div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
La semana pasada asistí a la tercera edición del evento Spring I/O que se celebra en Madrid. El año pasado estuve dando una charla acerca de Hadoop, Cloud y Spring pero este año simplemente he asistido como oyente (de momento el niño me deja poco tiempo libre . . . .).</div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
<br /></div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px; text-align: justify;">
Fueron dos días bastante intensos (estuvimos allí desde las ocho y media de la mañana hasta las siete de la tarde) que me dejaron un sabor agridulce. </div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px; text-align: justify;">
<br /></div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px; text-align: justify;">
Por una parte la organización del evento ha sido magnífica: aplicación para el móvil con la agenda, algún regalillo, multitud de información, coffee breaks, algo de comida, etc. Sobre el papel venía gente de mucho renombre: Adrian Colyer (CTO SpringSource), Matt Raible, Rob Harrop, Graeme Rocher (Grails Team Leader), Peter Ledbrok (Grails Team Leader), James Ward (Heroku Evangelist), el CTO de ZeroTurnaround (ahora mismo no recuerdo su nombre) . . . . y sin embargo el nivel de las charlas ha sido un poquito, bajo mi punto de vista, decepcionante: pocos contenidos novedosos, cosas muy básicas, etc. Puede ser que a medida que me voy haciendo viejo me esté volviendo un poco cascarrabias o que mi listón para medir las cosas esté demasiado alto; no lo tengo claro.</div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
<br /></div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
No pretendo convertir esta entrada en un ladrillo así que dare alguna pincelada sobre alguna de las charlas a las que asistí.</div>
<div style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;">
<ul>
<li style="margin-left: 15px;"><b>Application Development in the Cloud Era</b>. Esta charla fue impartida por Adrian Colyer y estuvo hablando, de manera muy genérica, sobre Rich clients, Cloud Computing, CQRS, Server Side. Lo mejor de la charla fue una frase en la que dijo "it is a good time to be a server side developer". No podría estar más de acuerdo :). Fue una de las charlas más entretenidas a las que asistí.</li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>Running Spring Apps on the Cloud with Heroku</b>. James Ward hizo una presentación de la plataforma PaaS Heroku. Durante el transcurso de la misma estuvo contando algunas generalidades sobre dicha plataforma y realizó una pequeña demo sobre como podemos desplegar nuestra aplicación en dicha plataforma. Ya conocía Heroku porque había hecho algunas cosillas para el doctorado aunque nunca está de más que una persona como James te lo cuente. Personalmente, me sigo quedando con Cloud Foundry, creo que está un escalón por encima. </li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>Polyglot Messaging with RabbitMQ</b>. Presentación de RabittMQ en la que se habla sobre esta plataforma de mensajes y cómo, gracias a su agnosticismo, se pueden escribir programas en multitud de lenguajes. El ponente presentó ejemplos (hablo de memoria) en Java, Erlang, Haskell, Python, . . . y seguro que me dejo alguno. La primera parte de la charla estuvo más o menos entretenida puesto que contó de manera general el funcionamiento de RabbitMQ. Sin embargo, la segunda parte comenzó a escribir ejemplos en multitud de diferentes lenguajes, a cambiar de editor a una velocidad de vértigo, ahora me funciona, ahora no, esto no me compila, . . .</li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>Comparing JVM Web Frameworks</b>. Comparación de algunas de los frameworks de desarrollo web más populares. Establece diversos factores de comparación entre plataformas como Struts, Grails, Lift, Rails, Vaadim, Play!. Poco puedo decir de esta charla que no se haya dicho ya. La verdad que la comparativa está muy bien realizada y puede ayudar a una persona a decantarse en la elección de un framework de desarrollo web. </li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>NoRedeploys: Instant updates in dev and prod</b>. Presentación de JRbel y LiveRebel. Durante mucho tiempo estuve utilizando JRebel tengo que decir que es un producto que me encanta. Fui a la charla con la expectativa de que iban a contar cosas técnicas de cómo hacen internamente las cosas y lo que me encontré fue una presentación con un cierto grado de tendencia comercial. Ojo, no estoy diciendo que eso este mal; sino que simplemente me esperaba otros contenidos en la charla.</li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>Spring Data y JPA</b>: Charla muy bien presentada, con ejemplos y mecanismos de como funciona. No me gusta mucho el enfoque que la ha dado la gente de Spring al proyecto (te tienes que acoplar muchísimo a sus clases) pero he de reconocer que fue una charla muy entretenida.</li>
</ul>
<ul>
<li style="margin-left: 15px;"><b>MongoDB</b> en un proyecto real. Charla presentada por David Gomez, no hemos tenido la suerte de desvirtualizar, en la que presenta el uso de MongoDB en una aplicación que han desarrollado para la gestión de puertos. Para aquella gente que no conozca mucho el mundo de NoSQL y conceptos como CAP, BASE, . . . creo que la primera parte de la charla es un muy buen punto introductorio. Luego se le echó el tiempo encima y tuvo que ir bastante deprisa.</li>
</ul>
<div>
Especialmente malas fueron la de Graeme Rocher hablando sobre Grails 2.0 (por cierto, como el reloading de las clases funcione igual de mal que durante su presentación . . . .) y la de novedades de Spring 3.1 a Spring 3.2 por Sam Brannen, básicamente porque de Spring 3.2 contó bien poco, por no decir nada.</div>
<div>
<br /></div>
<div>
Como decía al principio, me he quedado con un sabor de boca agridulce. </div>
<div>
<br /></div>
<div>
Ya para terminar, me gustaría agradecer a toda la gente que hace que este evento sea posible: organizadores, ayudantes, patrocinadores, . . . </div>
<div>
<br /></div>
<div>
Hasta pronto!</div>
<div>
<br /></div>
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-25681406241487476222012-02-21T22:14:00.000+01:002012-02-21T22:14:03.393+01:00Scala Implicits: simple examples<div style="text-align: justify;">
Durante la <a href="http://miguelinlas3.blogspot.com/2012/02/scala-implicits-i.html">entrada anterior</a> analizábamos los conceptos básicos de los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> en <span style="font-family: 'Courier New', Courier, monospace;">Scala</span> desde un punto de vista "teórico", dejando a un lado los ejemplos de código con el objetivo de no convertir el post en algo completamente inmanejable e incomprensible. A lo largo de la entrada que nos ocupa analizaremos diversos ejemplos de aplicación, describiendo con la mayor exactitud posible el mecanismo de funcionamiento de los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> aquí descritos.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Como punto de partida realizaremos un sencillo ejemplo en el que veremos como realizar conversiones automáticas a un tipo determinado (el compilador las realizará por nosotros). Supongamos que disponemos de la siguiente definición de clase</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">class User (private val username:String)</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
y que deseamos obtener instancias de la clase anterior sin la necesidad de realizar llamadas del tipo </div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">val user:User = new User("migue")</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
El primer paso que debemos dar será llevar a cabo la definición del <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> correspondiente. En este caso la conversión deberá realizarse desde <span style="font-family: 'Courier New', Courier, monospace;">String</span> hacia <span style="font-family: 'Courier New', Courier, monospace;">User</span>. Para ello definimos algo como lo que sigue:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">object UserImplicits {</span></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;"> <b>implicit</b> def stringToUsername(user: String) = new User(user)</span></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">}</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Nuestra siguiente tarea será hacer que el <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> anterior esté disponible en el ámbito donde lo queramos utilizar (una buena práctica suele ser realizar la definición de todos nuestros <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> en un singleton object llamado <span style="font-family: 'Courier New', Courier, monospace;">Preamble</span> e importar dicho objeto al comienzo de nuestras clases):</div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">import UserImplicits.stringToUsername</span></div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">val user:User = "migue"</span></div>
<div style="text-align: justify;">
<br />
¿De verdad el código anterior compila? ¿Que está pasando? El proceso es "<i>muy sencillo</i>", el compilador detecta que hay un error de tipos puesto que no puede asignar una cadena a una variable de tipo <span style="font-family: 'Courier New', Courier, monospace;">User</span>. Antes de declarar que existe un error ocasionado por una asignación de tipos incorrecta, el compilador busca si existe una conversión implicita disponible que le permita resolver el error encontrado. En este caso, el compilador buscará si existe un <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> que nos permita convertir una cadena de texto en un objeto de la clase <span style="font-family: 'Courier New', Courier, monospace;">User</span>. Si revisamos la definición de nuestro primer <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> veremos que disponemos de una función que cumple los requisitos que el compilador está intentando satisfacer, por lo que este último, de manera interna, realizará algo similar a</div>
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">val user:User = stringToUsername("migue")</span></div>
<div style="text-align: justify;">
<br />
El segundo ejemplo de uso de los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> que vamos a tratar son las conversiones de objetos sobre los que se realiza la llamada de un método. Nuestro objetivo será añadir nuevos métodos a una clase externa que podría estar definida en una librería third-party sobre la que no tenemos ningún tipo de control.<br />
<br />
Imaginemos la siguiente definición de clase en una librería externa (por sencillez esta clase estará definida en el propio archivo de código fuente junto al resto de ejemplos)<br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">class ExternalClass {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>def f1() = {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>"f1"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>def f2() = {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>"f2"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
en la que nos gustaría incluir el método def <span style="font-family: 'Courier New', Courier, monospace;">f3() = {"f3"}</span>. Para llevar a cabo nuestra tarea construiremos una clase auxiliar en la que definiremos el método que deseamos incluir:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">class MethodHelper {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>def f3(): String = {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>"f3"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
e incorporamos un nuevo <span style="font-family: 'Courier New', Courier, monospace;">implicit</span><br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">implicit def newMethodsToExternalClass(externalClass:ExternalClass) : MethodHelper = {</span><span style="font-family: 'Courier New', Courier, monospace;">new MethodHelper </span><span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
<br />
<br />
A continuación podremos escribir un código similar al que sigue:<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">import UserImplictis.newMethodsToExternalClass</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">println("Method f3() is added via an implicit conversion: " + externalClass.f3())</span><br />
<br />
<br />
¿Qué está ocurriendo en esta ocasión? Durante el proceso de compilación, <span style="font-family: 'Courier New', Courier, monospace;">Scala</span> detectará que existe un error puesto que el método <span style="font-family: 'Courier New', Courier, monospace;">f3()</span> no forma parte de la definición de la clase <span style="font-family: 'Courier New', Courier, monospace;">ExternalClass</span>. Antes de emitir un error, el compilador buscará una conversión implícita en la que se convierta el objecto receptor de la llamada del método f3() en un objeto que realmente posea dicho método. En nuestro ejemplo <span style="font-family: 'Courier New', Courier, monospace;">newMethodsToExternalClass</span> es el elemento que nos permite que el código anterior compile correctamente. ¿Que está ocurriendo internamente? El compilador estará emitiendo un código similar al siguiente:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">newMethodsToExternallClass(externalClass).f3()</span><br />
<br />
Como último ejemplo para esta entrada, revisaremos cómo podemos hacer uso de parámetros implícitos en las llamadas a funciones. Incorporemos el siguiente método a la definición de la clase <span style="font-family: 'Courier New', Courier, monospace;">User</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">def encodePassword(password:String)(implicit encoder: Encoder) : String = {</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>encoder.encode(password)<span class="Apple-tab-span" style="white-space: pre;"> </span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
Fijémonos que hemos marcado el segundo argumento de la función como <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> por lo que el compilador intentará completar las llamadas a la función añadiendo los parámetros necesarios. Definamos un encoder de ejemplo (que no realiza ningún tipo de operación útil) y utilizemos<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">implicit object IdentityEncoder extends Encoder {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> override def encode(password:String): String = password</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">import UserImplictis.IdentityEncoder</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">user2.encodePassword("foo")</span><br />
<div>
<br /></div>
<div>
Como podemos observar en el fragmento del código anterior en ningún momento estamos indicando el segundo parámetro de la función <span style="font-family: 'Courier New', Courier, monospace;">encodePassword</span> sino que es el propio compilador el que está intentado incluir en la lista de parámetros alguno de los <span style="font-family: 'Courier New', Courier, monospace;">implictis</span> disponibles de manera que la llamada de la función sea correcta.</div>
<div>
<br /></div>
<div>
Ha sido una entrada un poco larga pero he considerado que todos los ejemplos encajarían mucho mejor en una misma entrada de manera que pudieramos realizar un comparativa de los diferentes puntos de utilización de este poderoso mecanismo.</div>
<div>
<br /></div>
<div>
Importante: los snippets de código que aparecen a lo largo de esta entrada no están listos para ejecutarse en el REPL por lo que os aconsejo que, si quereis jugar con el código fuente, utilicéis aquel que está disponible <a href="https://github.com/migue/blog-examples/tree/scala-blog-examples">aquí</a> (realizaré el merge de esta rama sobre master tan pronto como me sea posible).</div>
<div>
<br /></div>
<div>
Hasta pronto!</div>
<div>
<br /></div>
<div>
Migue</div>
<br />
<br />
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-78992269371069472592012-02-20T18:23:00.001+01:002012-02-20T18:23:11.506+01:00Scala implicits (I)<div style="text-align: justify;">
Durante numerosas entradas hemos estado hablando del lenguaje de programación Scala, analizando algunas de sus principales características y/o la interacción con otros lenguajes: conceptos básicos, traits, parser combinators, combinando AspectJ y Scala, . . . Podéis encontrar todas las entradas relacionadas en el siguiente enlace: <a href="http://miguelinlas3.blogspot.com/search/label/Scala">http://miguelinlas3.blogspot.com/search/label/Scala</a> y un pequeño documento en el que se realiza una somera introducción al lenguaje: <a href="https://github.com/migue/blog-examples/tree/master/scala-intro">https://github.com/migue/blog-examples/tree/master/scala-intro</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Durante las siguientes entradas me gustaría ahondar en algunas características más "avanzadas" del lenguaje como "<span style="font-family: 'Courier New', Courier, monospace;">type parametrization</span>", "<span style="font-family: 'Courier New', Courier, monospace;">abstract members</span>" o "<span style="font-family: 'Courier New', Courier, monospace;">implicitis</span>" (estás últimas las abordaremos durante la entrada que nos ocupa).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
El principal problema que se nos presenta cuando trabaja mos con una librería de terceros es la dificultad de extender y/o modificar el comportamiento de la misma. A lo largo de los diferentes lenguajes existentes podemos encontrar numerosas alternativas, cada una con sus ventajas e inconvenientes, como las <span style="font-family: 'Courier New', Courier, monospace;">open classes de Ruby</span> o el <span style="font-family: 'Courier New', Courier, monospace;">ExpandoMetaclass de Groovy</span>.<br />
<br />
La respuesta de Scala al problema que nos ocupa son los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span>. El compilador intentará incluir en nuestro código fuente aquellos <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> que se encuentren disponibles con el objetivo de solventar cualquier "<i>problema de tipos</i>". De manera general, se rigen por las siguientes reglas:<br />
<br />
<ul>
<li>Sólo estarán disponibles para el compilador aquellas definiciones que nosotros marquemos de manera explícita como <span style="font-family: 'Courier New', Courier, monospace;">implicit</span>.</li>
</ul>
<ul>
<li>Los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> deben estar disponibles en el ámbito de uso.</li>
</ul>
<ul>
<li>El compilador solamente intentará incluir un <span style="font-family: 'Courier New', Courier, monospace;">implicit</span> de cada vez</li>
</ul>
<ul>
<li>El compilador no reemplazará código correcto.</li>
</ul>
<ul>
<li>¿Dónde se utilizan los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span>?</li>
<ul>
<li>Conversiones a un tipo determinado</li>
<li>Conversiones del objeto que recibe la llamada a un método</li>
<li>Parámetros de funciones</li>
</ul>
</ul>
<div>
Hemos visto una pequeña introducción sobre la teoría de los <span style="font-family: 'Courier New', Courier, monospace;">implicits</span> en Scala, las reglas que rigen el funcionamiento de los mismo y las aproximaciones que otros lenguajes utilizan. Puede que con este contenido la entrada se quede un poquito escueta pero he preferido dividirlo en dos entradas independientes por lo que en el próximo post realizaremos un ejemplo práctico y veremos las aplicaciones reales de esta potente (y a veces compleja) funcionalidad que el lenguaje nos brinda.</div>
<div>
<br /></div>
<div>
Hasta pronto!</div>
<div>
<br /></div>
<div>
Migue</div>
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-16842758706559694982012-01-02T17:55:00.000+01:002012-01-02T17:55:25.597+01:00Algunos libros para comenzar el año<div style="text-align: justify;">
Unos cuantos libros para comenzar el año de la mejor manera posible: aprendiendo cosas nuevas.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://ecx.images-amazon.com/images/I/51gA7MWpBYL._SL500_AA300_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: justify;"><img border="0" src="http://ecx.images-amazon.com/images/I/51gA7MWpBYL._SL500_AA300_.jpg" /></a></div>
<div style="text-align: justify;">
The Garbage Collection Handbook. Este libro ofrece una visión actualizada del estado del arte de los sistemas de recolección de basura y la gestión automática de memoria. He leido varias críticas de Gil Tene (CTO de Azul Systems) y en todas ellas pone al libro por las nubes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
No he tenido ocasión de leerlo, todavía, pero está en las primeras posiciones de la lista de libros que me gustaría leer este comienzo de año.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://ecx.images-amazon.com/images/I/51gLGwJ-0xL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: justify;"><img border="0" src="http://ecx.images-amazon.com/images/I/51gLGwJ-0xL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" /></a></div>
<div style="text-align: justify;">
Para aquellos que estéis interesados en los sistemas distribuidos y/o trabajeis con ellos aquí podréis encontrar una magnífica y extensa referencia sobre este tipo de sistemas: fundamentos, algoritmos , etc.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
No estoy seguro si ya he hablado de este libro con anterioridad pero la verdad es que se trata de una magnífica y reconfortante lectura en la que se pueden aprender infinidad de cosas.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://ecx.images-amazon.com/images/I/51lGZVrE1JL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_AA278_PIkin4,BottomRight,-31,22_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://ecx.images-amazon.com/images/I/51lGZVrE1JL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_AA278_PIkin4,BottomRight,-31,22_AA300_SH20_OU01_.jpg" /></a></div>
<div style="text-align: justify;">
Excelente lectura si os gusta conocer los "internals" del sistema operativo Linux y cómo funcionan la mayoría de sus principales subsistemas: gestión de procesos, gestión de memoria, etc. Posiblemente nunca escribamos ni una línea de código relacionada con el núcleo de este sistema operativo pero estoy convencido de que esta lectura puede ayudarnos como desarrolladores a escribir mejores programas.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Hasta pronto!</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-25672393892636223942012-01-02T12:12:00.000+01:002012-01-02T12:12:30.804+01:00Propósitos para 2012<div style="text-align: justify;">
Un año nuevo que comienza cargado de ilusiones, apasionantes retos personales y profesionales y grandísimas noticias. Al igual que el año anterior me gustaría escribir esta pequeña entrada en la que plasmar todas las buenas intenciones para este nuevo año que acaba de comenzar. Sobra decir que, tal y como ha ocurrido con las intenciones de hace doce meses, algunas se cumplirán y algunas no; esperemos que con tesón, perseverancia y muchas muchas ganas muchas de ellas sean algo más que meras intenciones. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Algunas de las cosas que tengo en mente:</div>
<div style="text-align: justify;">
</div>
<ul>
<li><b>Pasar el máximo tiempo posible con mi hijo y mi novia</b>. Como tod@s ya sabéis el pasado mes de noviembre hemos sido padres por primera vez y quiero disfrutar al máximo del niño y de todo lo que lo rodea.</li>
</ul>
<ul>
<li style="text-align: justify;"><b>Casarme</b>. La única duda que tengo respecto a este tema es el tipo de celebración que vayamos a realizar aunque todo indica que no llevaremos a cabo una "boda tradicional" cientos de invitados sino que será algo extremadamente simple.</li>
</ul>
<ul>
<li style="text-align: justify;"><b>Retomar el tema del doctorado</b>. Acontecimientos de diversa índole como la parálisis facial, la operación de corazón de mi suegra, el nacimiento de Sergio y algunas cosas más hicieron que durante el segundo semestre del año pasado me costara mucho más poner orden y determinación. Esperemos que en este año que comienza sea capaz de organizarme de manera mucho más eficaz y pueda retomar las diferentes cosas del doctorado que ahora mismo tengo en un estado de abandono absoluto.</li>
</ul>
<ul>
<li style="text-align: justify;"><strike>Ponerme en forma </strike><b>Practicar algo de deporte</b>. Creo que practicar algo de deporte es algo muchto más realista. Soy consciente de que recuperar el estado de forma que tenía cuando jugaba al fútbol y practicaba surf es una utopía con lo que me conformaré con salir a correr de vez en cuando y perder unos cuantos kilillos que he cogido durante el último viaje a EEUU y estas navidades (que todavía no han tocado a su fin y tengo unas cuantas citas pendientes) .</li>
</ul>
<div style="text-align: justify;">
No podía terminar este post sin hacer mención a las cosas ligadas al mundo de la tecnología que me gustaría hacer durante este año:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<ul>
<li><b>Asistir a alguna conferencia más que el año anterior</b>. El año pasado estuve hablando en Spring I/O sobre Hadoop y este año tenía medio preparada una presentación sobre los internals de Cloud Foundry aunque finalmente no tuve tiempo de enviarla por lo que este año, en caso de que pueda asistir, será unicamente como oyente. </li>
</ul>
De momento ya tengo la entrada para los <a href="http://days2012.scala-lang.org/">Scala Days 2012</a> (todavía tengo que gestionar el hotel y el viaje)</div>
<div style="text-align: justify;">
<ul>
<li><b>Aprender nuevas cosas y mejorar muchas de las que yo conozco</b>. Mejorar mis habilidades con Scala, participar más activamente en algunos proyectos en los que he hecho algunas cosillas, dar "pasos mucho más serios" en otros lenguajes como <a href="http://golang.org/">Go</a> y <a href="http://www.haskell.org/haskellwiki/Haskell">Haskell</a>, profundizar mis conocimientos de sistemas distribuidos, . . . .</li>
</ul>
<ul>
<li>Impulsar el grupo de escalabilidad en español: <a href="https://groups.google.com/forum/#!forum/spain-scalability-users">https://groups.google.com/forum/#!forum/spain-scalability-users</a></li>
</ul>
<div>
Tenía algunas cosas más en mente pero tengo que cortar aquí porque está el niño llorando y tengo que ocuparme de el.</div>
<div>
<br /></div>
<div>
Feliz año 2012 a tod@s y esperemos que no sea tan malo como lo pintan!</div>
<div>
<br /></div>
<div>
Hasta pronto!</div>
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-76732039863327462682011-11-28T22:56:00.001+01:002011-11-28T23:46:08.680+01:00Algunos libros sobre Java y JVMDurante estas últimas semanas he tenido la ocasión de terminar varios de los libros que tenía pendientes así como de realizar alguna nueva adquisición que, de momento, está encolada en mi lista de lectura.<br />
<div>
<br /></div>
<div>
Me gustaría aprovechar esta entrada para compartir con vosotros algunos de los libros anteriores que, bajo mi punto de vista, podrían resultar interesantes para tod@s aquell@s que os dediquéis, de algún modo, a trabajar con la plataforma Java (lenguaje y/o máquina virtual).</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://ecx.images-amazon.com/images/I/51PMR3OVSXL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_AA278_PIkin4,BottomRight,-32,22_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://ecx.images-amazon.com/images/I/51PMR3OVSXL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_AA278_PIkin4,BottomRight,-32,22_AA300_SH20_OU01_.jpg" /></a></div>
<div>
El primero de ellos es <a href="http://www.amazon.com/dp/B005OR9NA2/ref=rdr_kindle_ext_tmb">Java Performance from The Java Series</a>. Escrito por Charlie Hunt, JVM performance lead engineer en Oracle, y Binu John, senior performance engineer en Ning. Ha sido mi última adquisición y únicamente he podido leer los dos primeros capítulos pero creo que estamos ante uno de las lecturas obligatorias para tod@s aquell@s que se dedican y/o les gusta el mundo del rendimiento de aplicaciones sobre la JVM.</div>
<div>
<br /></div>
<div>
JVM Tuning, profiling, mediciones, herramientas, escritura de benchmarks, internals de la JVM, algoritmos de recolección de basura y tuneo de los mismos, gestión de la memoria, . . . son sólo algunas de las temáticas tratadas en este magnífico manuscrito.</div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.manning.com/evans/evans_cover150.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://www.manning.com/evans/evans_cover150.jpg" /></a></div>
<div style="text-align: left;">
Otro magnífica referencia relativa al mundo Java: <a href="http://www.manning.com/evans/">The well-grounded Java developer</a>. Se trata de un early access por lo que sólo he podido leer los capítulos disponibles hasta el momento. Pensado para desarrolladores con unos sólidos conocimientos de Java el libro abarca un amplio espectro de temáticas como pueden ser:</div>
<div style="text-align: left;">
<ul>
<li>Algunas de las novedades de Java 7</li>
<li>Nuevo mecanismo de IO y concurrencia</li>
<li>Classfiles y bytecode</li>
<li>Inyección de dependencias</li>
<li>Lenguajes alternativos en la JVM: Clojure, Groovy y Scala</li>
<li>Integración continua</li>
<li>. . .</li>
</ul>
En lineas generales creo que se trata de una lectura recomendada (a la espera de que se publique la segunda mitad del libro). Los capítulos pueden ser leidos de manera independiente, saltándose aquellos en los que ya se conoce de manera profunda la temática tratada en el mismo.</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://jcip.net/images/jcip-cover.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="http://jcip.net/images/jcip-cover.jpg" width="243" /></a></div>
<div style="text-align: left;">
Un libro que había leido hace tiempo y que he vuelto a leer hace unas semanas ha sido <a href="http://jcip.net/">Java Concurrency in Practice</a>. Poco puedo decir de este libro que no se haya dicho ya. Otra de las lecturas obligatorias para todos aquellos desarrolladores que trabajen con el lenguaje Java.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Ofrece una visión práctica de cómo se deben escribir programas escalables y seguros aprovechando la capacidad de las nuevas arquitecturas hardware.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://akamaicovers.oreilly.com/images/0636920021667/cat.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://akamaicovers.oreilly.com/images/0636920021667/cat.gif" /></a></div>
<div style="text-align: left;">
<a href="http://shop.oreilly.com/product/0636920021667.do">Functional Programming for Java Developers</a>. Escrito por Dean Wampler. Es un libro en el que se introducen los conceptos básicos de la programación funcional (que está "renaciendo" gracias a lenguajes como Scala o Clojure, además de sus beneficios a la hora de escribir programas concurrentes entre otras muchas cosas).<br />
<br />
Es un libro muy cortito aunque personalmente no me ha entusiasmado demasiado. Si no tenéis ninguna experiencia en programación funcional puede ser un buen punto de partida. No se cubren mónadas, laziness ni combinators.
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com1tag:blogger.com,1999:blog-35092134.post-68528051061457068782011-10-06T23:47:00.000+02:002011-10-07T07:55:55.286+02:00Escalabilidad, disponibilidad y estabilidad<div style="text-align: justify;">
En algunas ocasiones hemos hablado de temas de escalabilidad y disponibilidad de sistemas aunque siempre desde un punto de vista muy práctico, haciendo referencia a los problemas que ocupan nuestro día a día. Me gustaría recopilar, a lo largo de una serie de posts, algunos de los patrones y/o tecnologías más populares relacionados con la escalabilidad, la concurrencia o la alta disponibilidad.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Me gustaría dejar claro desde un principio que lo aquí expuesto son simplemente mis ideas, adquiridas a lo largo del tiempo gracias a la experiencia acumulada en la construcción de diversos sistemas software, mis estudios de doctorado, leer y practicar mucho, aprender de los maestros y pasarme muchas, pero muchas muchas, horas aporreando el teclado. Por tanto, las cosas que aquí aparecen podrían ser erróneas y/o incompletas.<br />
<br />
Me gustaría comenzar con una tecnología relacionada con la concurrencia: la memoria transaccional (STM en adelante).<br />
<br />
Escribir programas concurrentes es una tarea sumamente complicada y, habitualmente, no determinista; ¿cuantas veces habremos probado un programa multihilo en nuestros sistemas de integración continua y , tras poner el sistema en producción, nos hemos encontrado con nuevos errores? Tan real como la vida misma.<br />
<br />
Habitualmente las inmutabilidad (hablaremos de ella en el futuro) es un gran aliado a la hora de escribir programas concurrentes dado que resulta mucho más sencillo razonar sobre información cuyo estado permanece estable. Sin embargo, como en la mayoría de las situaciones, la inmutabilidad no es una bala de plata que soluciona todos los problemas por lo que tendremos que lidiar con información cuyo estado puede variar y con toda la problemática asociada a la misma. Llegados a esta situación, y siguiendo con el enfoque con el que estamos más familiarizados, estaríamos peleándonos con bloqueos, granularidad de los mismos, etc.<br />
<br />
<b><u><span style="font-family: 'Trebuchet MS', sans-serif;">Un vistazo a la STM</span></u></b><br />
<br />
La STM puede ayudarnos a resolver el problema anterior de manera mucho más sencilla visualizando la memoria (heap + pila) como si de un dataset transaccional se tratara. Algunas de las características más relevantes:<br />
<br />
<ul>
<li>Concepto muy similar al de una base de datos tradicional. Se llevan a cabo operaciones como begin, commit o abort/rollback</li>
</ul>
<ul>
<li>En caso de que se produzca una colisión la transacción será relanzada de manera automática</li>
</ul>
<ul>
<li>Se realiza un proceso de rollback sobre la memoria cuando se produce una operación de abort.</li>
</ul>
<ul>
<li>Las transacciones se pueden componer y anidar</li>
</ul>
<br />
Un aspecto sumamente importante que debemos tener en cuenta a la hora de utilizar la memoria transaccional es que todas las operaciones englobadas en el ámbito de una transacción deberán ser idempotentes (anteriormente hablábamos del relanzamiento automático en caso de que se produjera una colisión).<br />
<br />
Existen numerosas implementaciones disponibles para la máquina virtual de Java (JVM) entre las que destacan:<br />
<br />
<ul>
<li>Multiverse: <a href="http://multiverse.codehaus.org/overview.html">http://multiverse.codehaus.org/overview.html</a></li>
<li>Akka: <a href="http://akka.io/docs/akka-1.0/stm-java.html">http://akka.io/docs/akka-1.0/stm-java.html</a></li>
<li>Clojure STM: <a href="http://clojure.org/refs">http://clojure.org/refs</a></li>
<li>CCSTM: <a href="http://ppl.stanford.edu/ccstm/site/index.html">http://ppl.stanford.edu/ccstm/site/index.html</a></li>
<li>Deuce STM: <a href="https://sites.google.com/site/deucestm/">https://sites.google.com/site/deucestm/</a></li>
</ul>
<div>
En la siguiente entrada realizaremos varios ejemplos prácticos de uso de la memoria transaccional y analizaremos cuales son los escenarios más propicios para la utilización de esta solución.</div>
<div>
<br /></div>
<div>
Hasta pronto!</div>
<div>
<br /></div>
<div>
Migue</div>
</div>
miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-15698741454035282632011-10-05T00:48:00.002+02:002011-10-05T00:49:30.508+02:00[Off-Topic] Poniéndome al día y buenas noticiasHola a tod@s,<br />
<br />
<div style="text-align: justify;">
Hace más de un mes y medio de la última entrada en el blog pero es que me está costando mucho más de lo esperado retomar todas las cosas pendientes y/o atrasadas por lo que últimamente me estoy agobiando un poquito. De todos modos el objetivo de la entrada no era aburriros con mis "problemas" sino comentaros una buena noticia, al menos para mi :), aunque seguro que muchos de los que os pasáis por aquí ya lo sabréis: ¡<b>vamos a ser papás</b>!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Así es; si todo sigue como hasta ahora, dentro de cuatro semanas aproximadamente tendremos a nuestro hijo Sergio entre nuestros brazos.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbNvJLW_zuTB7KgkdC853HQeIvX4AmhU9B4QR-KuQ8Ew2nbw_eox1_Zfr_HHovt1yolBR_-AIH_qQomNX5OzyWia6PiPguOi_iqH70f6tGcLNknEGe-PaaZJ0i1HTxfd-kihJd/s1600/IRATXE_DINIZ_SERNA__SERGIO__20110820132904_1344061.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbNvJLW_zuTB7KgkdC853HQeIvX4AmhU9B4QR-KuQ8Ew2nbw_eox1_Zfr_HHovt1yolBR_-AIH_qQomNX5OzyWia6PiPguOi_iqH70f6tGcLNknEGe-PaaZJ0i1HTxfd-kihJd/s320/IRATXE_DINIZ_SERNA__SERGIO__20110820132904_1344061.bmp" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Estos últimos meses han sido, sin lugar a dudas, los mejores meses de mi vida. Meses de cambio, de preparar la casa, de descubrir cosas que ni siquiera sabía que existían o de convertirme en un "manitas".</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHLgTTmhw7kCYkUBEmCsPrOeQGP6iDT4riGPmVooDN8lJXVV54NWuxFZP37_Kf6gvQmZYuY7U8U6Y7D3hAKIiYI3X7nv05SsfbvUs3Y6KbZgMh0m_hCl2lcNlELjpPSZRwN4iJ/s1600/P1040372.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHLgTTmhw7kCYkUBEmCsPrOeQGP6iDT4riGPmVooDN8lJXVV54NWuxFZP37_Kf6gvQmZYuY7U8U6Y7D3hAKIiYI3X7nv05SsfbvUs3Y6KbZgMh0m_hCl2lcNlELjpPSZRwN4iJ/s320/P1040372.JPG" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Con toda seguridad los cambios serán mucho más notables cuando el pequeño nazca pero de momento prefiero no adelantar acontecimientos y centrarnos en disfrutar del "poquito" tiempo de embarazo que nos queda.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl9aKC0385rcOd3eOadrhyphenhyphen-pCjfPFpvYkzgiUs0S_ZfRsrk9oUEdICAANautDBgh_LcdacZuPPuoo_fGa4FiHXcdIP5bzbzXwFgu4QauL5Bwqy0X1TboN39ctdzVNwQ-u_ifOe/s1600/P1040297.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl9aKC0385rcOd3eOadrhyphenhyphen-pCjfPFpvYkzgiUs0S_ZfRsrk9oUEdICAANautDBgh_LcdacZuPPuoo_fGa4FiHXcdIP5bzbzXwFgu4QauL5Bwqy0X1TboN39ctdzVNwQ-u_ifOe/s320/P1040297.JPG" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Dentro de poco tendré que repartir mimos y cuidados entre mis dos amores aunque mi gordita dice que nada de dividir, que como mínimo duplicar así que . . . difícil tarea me espera.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Hasta pronto!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Migue</div>
miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-22777639794609646872011-08-26T23:16:00.000+02:002011-09-14T23:18:13.400+02:00De regresoYa estoy de vuelta.<br />
<br />
Por suerte ya me he recuperado por completo de mi parálisis facial (finalmente "solo" me duró once días aproximadamente) con lo que de nuevo estoy online.<br />
<br />
La entrada no será muy larga :) , simplemente quería que supierais que me encuentro perfectamente. <br />
<br />
Espero retomar el blog durante los próximos días aunque con lo que tenemos en camino tengo una agenda en la que el tiempo libre brill a por su ausencia.<br />
<br />
Hasta pronto!<br />
<br />
Migue<br />
<br />
PD: he escrito la entrada desde el iPad y la verdad que se escribe mucho más rápido de lo que uno podría esperar en un principio.<br />
<br />
miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-91331711252205130012011-08-02T13:01:00.000+02:002011-08-02T13:01:00.368+02:00OfflineDurante los próximos días estaré "offline" por completo. Nada de ordenador, IPad, Internet y similares :). Voy a ver si consigo desconectar por completo durante estos días y termino de recuperarme de mi parálisis facial.<br />
<br />
Hasta pronto!<br />
<br />
Miguemiguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com1tag:blogger.com,1999:blog-35092134.post-72747687729075350272011-07-30T22:22:00.000+02:002011-07-30T22:22:55.496+02:00Parálisis facial<div style="text-align: justify;">Hacía muchísimo tiempo que no me ponía enfermo pero esta vez me ha tocado. Será que me estoy haciendo mayor . . . :(. La doctora me ha diagnosticado parálisis facial.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Gracias a Dios suena mucho más aparatoso de lo que es: tengo la mitad de la cara dormida (es una sensación similar a la que se presenta cuando regresas del dentista) y se me cierra un poco el ojo con lo que a veces se me cansa la vista y no puedo enfocar demasiado bien. Las buenas noticias es que no es doloroso aunque si bastante incómodo. Las malas es que me puede durar desde tres días hasta tres meses y que "del mismo modo que viene se va" (palabras textuales de la doctora).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Espero recuperarme cuanto antes y seguir dando un poco de guerra!</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Hasta pronto!</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Migue</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-22555159808243667562011-07-19T22:43:00.000+02:002011-07-19T22:43:22.265+02:00Grupo de escalabilidad: mapa clusterizadoTras los resultados de la encuesta que realizamos durante la semana pasada hemos creado un pequeño mapa geográfico en el que se muestran a modo de clúster los distintos miembros que componemos el grupo de escalabilidad en español y dónde estamos ubicados cada uno de nosotros:<br />
<br />
<div id="ss-frame"></div><script src="http://sharedspaces.googlelabs.com/embed_api.js">
</script><script>
new google.sharedspaces.Embed({div:document.getElementById("ss-frame"), id: "m2vgpQwYHv", width: 525, height: 600, title: true, sidepanel: false, border: true})
</script><small>Embedded from Google Shared Spaces. <a href="http://sharedspaces.googlelabs.com/">Create your own space.</a></small><br />
<br />
El registro el libre y cada una de las personas que aparece en el mapa anterior se ha registrado de manera propia.<br />
<br />
Si estáis interesados en alguna temática relacionada con la escalabalidad de sistemas de información os animo a que os registréis en el <a href="https://groups.google.com/forum/#!forum/spain-scalability-users">grupo</a> y también os apuntéis en el mapa!<br />
<br />
Hasta pronto!<br />
<br />
Miguemiguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-62140301751518223832011-07-13T20:42:00.000+02:002011-07-13T20:42:40.077+02:00Evento sobre escalabilidad de sistemas<div style="text-align: justify;">Desde el <a href="https://groups.google.com/forum/#!forum/spain-scalability-users">grupo de escalabilidad en español </a>hacía tiempo que estábamos barajando la posibilidad de organizar un evento relativo a la escalabilidad de sistemas y finalmente hemos dado un paso adelante.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Es una primera aproximación en la que estamos intentando recabar el mayor conjunto de información posible con el objetivo de llegar al mayor número de gente posible.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">No voy a repetir todo el rollo que hemos escrito en otros sitios :) así que simplemente os dejo los enlaces donde podréis encontrar toda la información de la que disponemos hasta este momento:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"></div><ul><li><a href="https://groups.google.com/forum/#!topic/spain-scalability-users/Z-FqVch1NCY">Topic en el grupo google</a></li>
</ul><ul><li><a href="http://mpermar.polldaddy.com/s/evento-de-escalabilidad">Encuesta</a></li>
</ul><ul><li><a href="http://brigomp.blogspot.com/2011/07/consulta-sobre-evento-sobre.html">Entrada en el blog de Martín Pérez</a></li>
</ul><div>Estaremos encantados de recibir vuestras críticas, sugerencias y/o propuestas.</div><div><br />
</div><div>Hasta pronto!</div><div><br />
</div><div>Migue</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-39576235538853718392011-06-29T18:31:00.000+02:002011-06-29T18:31:02.508+02:00AspectJ y Scala (y III)<div style="text-align: justify;">Última entrada (en esta ocasión mucho menos ladrillo) de esta mini-comparativa que estamos llevando a cabo entre AspectJ y Scala (podéis consultar las anteriores entradas en los siguientes enlaces: <a href="http://miguelinlas3.blogspot.com/2011/06/aspectj-y-scala-i.html">AspectJ y Scala (I)</a>, <a href="http://miguelinlas3.blogspot.com/2011/06/aspectj-y-scala-ii.html">AspectJ y Scala (II)</a>.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Hemos estado revisando cómo llevar a cabo la aplicación de varias funcionalidades como el uso de cachés o la gestión de transacciones mediante el uso de AspectJ y Scala, haciendo hincapié en las ventajas y desventajas de las dos aproximaciones. Nótese que hemos estado hablando de funcionalidad transversal como las transacciones y la caché pero no hemos hablado de otro tipo de funcionalidades las cuales abarcan un espectro mucho más amplio como por ejemplo FFDC (First Faiulure Data Capture), Profiling, gestión de la concurrencia, etc. En este tipo de situaciones el uso de Scala y HFOs resultaría mucho más tedioso que los ejemplos vistos en las entradas anteriores; derivando en los síntomas clásicos de funcionalidad "difuminada" por toda nuestra apliación.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">¿Conclusión? El uso de cualquiera de las dos aproximaciones que hemos estado analizando dependerá, como en el 90 por ciento de todas las situaciones, del problema que estemos resolviendo, por lo que tendremos que escoger la "herramienta" más adecuada para el problema que se nos plantea.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">¿Y por qué no un mixin de las anteriores? Esta es una de las alternativas que más me convence:</div><div style="text-align: justify;"></div><ul><li>Compilamos nuestros programas Scala de la manera habitual.</li>
</ul><ul><li>Definimos nuestros aspectos para llevar a cabo la funcionalidad transversal deseada.</li>
</ul><ul><li>Realizamos un proceso de binary weaving (ya sea build time o load time)</li>
</ul><div>Mediante el mecanismo anterior estaremos aplicando nuestros aspectos a nuestro código Scala compilado.</div><div><br />
</div><div>En mi cuenta de <a href="https://github.com/migue/blog-examples">GitHub</a> podréis encontrar dos proyectos Eclipse (<b>scala-simple-service </b>y<b> aspectj-advice-scala</b>) que deben ser utilizados de manera conjunta. Mediante estos dos pequeños proyectos de ejemplo se ilustra cómo podemos utilizar conjuntamente aspectos escritos en AspectJ que hagan advice sobre código Scala compilado.</div><div><br />
</div><div>Hasta pronto!</div><div><br />
</div><div><br />
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-57863805638020654432011-06-28T00:11:00.001+02:002011-06-28T00:14:57.183+02:00AspectJ y Scala (II)<div style="text-align: justify;">En <a href="http://miguelinlas3.blogspot.com/2011/06/aspectj-y-scala-i.html">la entrada anterior</a> analizamos algunas de las similitudes y diferencias existentes entre Scala y AspectJ, llevando a cabo una implementación de una caché extremadamente simple en ambos lenguajes, describiendo las ventajas y desventajas presentes en cada una de las aproximaciones. Durante esta entrada analizaremos un ejemplo de aplicación de una funcionalidad transversal como la gestión de transacciones. </div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El ejemplo que aquí nos ocupa no persigue realizar una implementación detallada de control de transacciones sino simplemente ilustrar como podríamos aplicar una funcionalidad transversal mediante el uso de AspectJ o Scala.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Del mismo modo que en el post anterior, comenzamos por la aproximación basada en AspectJ. Para ello en primer lugar definimos una simple anotación que nos sirva como elemento de marcado de aquellas clases y/o métodos que se deben ejecutar bajo un contexto transaccional.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Una vez definida la anotación anterior definiremos un aspecto que sea capaz de detectar aquellos joint point en los que deseamos establecer un contexto transaccional. </div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"></div><div class="p1"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><i><span class="s1">pointcut</span> transactionalOperation() : <span class="s1">execution</span>(<span class="s2">@Transactional</span> * * (..) );</i></span></div><div class="p1"><br />
</div><div class="p1">Con el pointcut anterior estaremos capturando las llamadas realizadas sobre cualquier método anotado con nuestra anotación @Transactional. Ahora necesitaremos definir un advice en el que llevamos a cabo la gestión de la transacción (nótese que este gestor de transacciones es completamente absurdo y simplemente imprime por pantalla la funcionalidad real que debería ser llevada a cabo por un gestor de transacciones operativo)</div><div class="p1"><br />
</div><script src="http://pastie.org/2103676.js">
</script><br />
<div class="p1">En muchas ocasiones todos los métodos de una clase necesitarán ser transaccionales, y no querremos anotar todos los métodos de dicha clase. En este supuesto podríamos utilizar <b>anotaciones a nivel de clase</b> que nos permitan seleccionar aquellos métodos que deseemos (por ejemplo, todos los métodos públicos).<br />
<br />
Adicionalmente, podríamos hacer uso de los ITD y establecer la transaccionalidad a todas aquellas clases que nosotros deseemos. Por ejemplo, supongamos que todos los nombres de nuestros servicios, los cuales deseamos que sean transaccionales, terminan con el sufijo Service. Podríamos, mediante el uso de un aspecto, añadir la anotación @Transactional a todos nuestros servicios.<br />
<br />
<div class="p1"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="s1">declare</span> <span class="s1">@type</span> : *Service : <span class="s2">@Transactional</span> ;</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br />
</span></div>Dicho aspecto, en conjunción con el anterior, provocaría que todos nuestros servicios fueran transaccionales<br />
<br />
En Scala, de nuevo, haremos uso de funciones de alto nivel (high order functions) de manera muy similar a la solución de la caché descrita en la entrada anterior:</div><div><script src="http://pastie.org/2131238.js">
</script></div><br />
Si deseamos que un método de uno de nuestros servicios sea transaccional no tendremos más que extender de la clase abstracta y utilizar la HOF anterior:<br />
<div><script src="http://pastie.org/2131252.js">
</script></div><br />
Si comparamos las soluciones aportadas por cada una de las dos alternativas tendremos que<br />
<ul><li>En el caso de AspectJ no necesitamos anotar cada método de manera independiente puesto que podríamos hacer uso de anotaciones a nivel de clase. El nivel de granularidad que podemos alcanzar está definido a nivel de método (aunque tampoco es un problema excesivamente grande puesto que podríamos utilizar el patrón Extract Method para extraer la funcionalidad transaccional a un método sobre el cual podríamos aplicar nuestro aspecto).</li>
<li>En el caso de Scala necesitaremos recubrir nuestra lógica con la HOF definida en nuestro ejemplo anterior. En esta situación, el nivel de granularidad es notablemente superior puesto que podemos recubrir una simple parte de nuestro método</li>
</ul>Durante esta segunda entrada hemos vuelto a confrontar Scala y AspectJ a la hora de aplicar una funcionalidad transversal, intentando plasmar las ventajas y desventajas de cada uno de ellos.<br />
<br />
En la siguiente y última entrada de esta serie analizaremos cómo aunar lo mejor de ambos mundos en un ejemplo práctico que nos sirva como base para futuros ejemplos.<br />
<br />
Como siempre podéis encontrar el código fuente de todos los ejemplos del blog (o casi todos :) ) en mi cuenta de <a href="https://github.com/migue/blog-examples">GitHub</a>, bajo el proyecto blog-examples.<br />
<br />
Hasta pronto!<br />
<br />
PD: perdón por el ladrillo de entrada :(.miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-74880549585294637012011-06-21T00:09:00.000+02:002011-06-21T00:09:04.804+02:00AspectJ y Scala (I)<div style="text-align: justify;">¿Podemos establecer alguna conexión entre estos dos mundos? Si nos detenemos por un instante veremos que comparten muchas más cosas de las que a simple vista podría parecer:</div><div style="text-align: justify;"></div><ul><li>Son lenguajes de tipado estático.</li>
<li>Ambos producen código compatible con la máquina virtual de Java (JVM)</li>
<li>Las funciones de alto nivel de Scala comparten algunas características con los advices de AspectJ</li>
<li>Los traits de Scala comparten algunas características con el static crosscuting de AspectJ.</li>
</ul><br />
<div style="text-align: justify;">Durante el resto de la entrada que nos ocupa (y la siguiente) realizaremos una pequeña comparativa en la que pondremos de manifiesto el modo en que cada uno de estos lenguajes resuelve determinado tipo de problemas. Pongámonos manos a la obra.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><span class="Apple-style-span" style="font-size: large;"><b>Cachés</b></span></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">A través de este ejemplo se pretende presentar el modo en que ambos lenguajes solucionan el problema de aplicar una funcionalidad transversal en un punto determinado del código. Implementaremos un mecanismos de caché extremadamente sencillo de manera que podamos centrar nuestra atención en los aspectos relevantes de las alternativas que estamos planteando</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En el caso de AspectJ se está tendiendo a utilizar las anotaciones como un elemento de marcado (y parece que está siendo recibido con una aceptación más que notable). Nuestro primer paso será definir la anotación con la que realizaremos el "marcado" de aquellos métodos que deseamos establecer como cacheados:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"></div><div class="p1"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><b><span class="s1">@Retention</span>(RetentionPolicy.<span class="s2">RUNTIME</span>)</b></span></div><div class="p2"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><b>public<span class="s3"> </span>@interface<span class="s3"> </span><span class="s1">Cachable</span><span class="s3"> {</span></b></span></div><div class="p1"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><b><span class="Apple-tab-span"></span> String scriptKey () <span class="s4">default</span> <span class="s5">""</span>;</b></span></div><div class="p1"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><b>}</b></span></div><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El atributo keyScript de la anotación anterior actuaría (en una caché real), como un pequeño lenguaje de scripting de manera que pudiera ser evaluado por la caché para generar la clave bajo la que se almacenará una determinada llamada (obviaremos esta parte para intentar no distraernos de nuestro principal objetivo).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Una vez definido el elemento de marcado, definiremos nuestro aspecto, el cual será capaz de capturar las llamadas de aquellos métodos anotados con @Cacheable y realizar la lógica necesaria de nuestra sencilla caché</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;" width="10%"><script src="http://pastie.org/2074516.js">
</script></div><br />
<div style="text-align: justify;">En el caso de Scala llevaremos a cabo nuestra funcionalidad transversal mediante el uso de funciones de primer nivel (high order functions)</div><div style="text-align: justify;"><script src="http://pastie.org/2098190.js">
</script></div><br />
Gracias a la funcionalidad anterior, podemos pasar al método cache una función que será ejecutada en caso de ser necesario, devolviendo los valores de la caché en el supuesto de que haya sido calculado en un paso anterior.<br />
<br />
Si comparamos las dos alternativas que hemos planteado hasta este momento:<br />
<ul><li>En el caso de AspectJ, cada uno de los elementos que deseamos cachear tendremos que anotarlos con, valga la redundancia, la anotación que hemos definido anteriormente. Mientras tanto, en el caso de Scala, tendremos que recubrir cada uno de los métodos que deseamos cachear con la función de alto nivel (high order function).</li>
</ul><ul><li>En el caso de AspectJ estamos utilizando un "lenguaje" externo que actua como elementos de las claves de nuestra caché mientras que en el caso de Scala estamos utilizando el propio lenguaje de manera nativa, con el consiguiente beneficio que ello conlleva.</li>
</ul><div style="text-align: justify;">Esta ha sido nuestra primera aproximación a Scala y AspectJ. Durante las siguientes entradas analizaremos algunos ejemplos adicionales y veremos como podemos integrar lo mejor de ambos mundos.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Podéis encontrar el código fuente de los ejemplos anteriores en el siguiente repositorio de <a href="https://github.com/migue/blog-examples/">GitHub</a>, concretamente en los proyectos AspectJCacheExample y ScalaCacheExample.<br />
<br />
Hasta pronto!</div><blockquote><ul></ul></blockquote>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-79566745764963547952011-06-03T21:47:00.000+02:002011-06-03T21:47:50.411+02:00Mecanismo de Load Time Weaving (LTW)<div style="text-align: justify;">Durante la <a href="http://miguelinlas3.blogspot.com/2011/05/weaving-en-aspectj-i.html">última entrada</a> analizábamos de manera introductoria los diferentes mecanismos de tejido ofrecidos por AspectJ así como las principales características de los mismos. Durante esta entrada nos acercaremos un poquito más al mecanismo de tejido en tiempo de carga, por normal general más desconocido, desde mi punto de vista, que el mecanismo de tejido en tiempo de construcción (durante todos los ejemplos que hemos visto en anteriores entradas siempre hemos utilizado el tejido en tiempo de construcción).<br />
<br />
Los pasos que tenemos que seguir cuando utilizamos el tejido en tiempo de carga son los siguientes:<br />
<br />
<ul><li>Iniciar nuestra aplicación con el archivo aspectjweaver.jar el actuando como un agente (hablaremos de agentes en otra entrada). Para ello podríamos utilizar una línea como la siguiente</li>
</ul><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><div style="text-align: center;">java -javaagent:<path>/aspectjweaver.jar <more options=""> <mainclass></mainclass></more></path></div></span><ul><li>Durante el proceso de inicialización del agente (llevado a cabo por la máquina virtual) el propio agente recupera aquellos archivos existentes en el classpath que coincidan con META-INF/aop.xml (en el caso de encontrar múltiples llevará a cabo la combinación de los mismos).</li>
</ul><ul><li>Carga de los aspectos indicados.</li>
</ul><ul><li>El agente se registra como un listener del evento de carga de clases de la máquina virtual. Mediante este mecanismo se tiene acceso a la definición de la clase, permitiendo incluso la modificación de la misma.</li>
</ul><ul><li>Continua el proceso normal de carga de nuestro aplicación.</li>
</ul><ul><li>Cada vez que una nueva clase es cargada la máquina virtual notifica al agente dicha situación. En ese momento es posible examinar la clase en cuestión y determinar si algunos de los aspectos cargados con anterioridad necesita ser tejido. En caso afirmativo, la clase será tejida con el aspecto en cuestión, retornando el bytecode resultante a la máquina virtual.</li>
</ul><ul><li>La máquina virtual utiliza el bytecode resultante como elemento de definición de la clase.</li>
</ul></div><div style="text-align: justify;">Mediante el conjunto de pasos anteriores, aquellas clases que hayan hecho matching con las definiciones de nuestros aspectos tendrán incorporada la funcionalidad definida en éstos últimos.<br />
<br />
El agente anterior utiliza un interfaz de la máquina virtual conocido como <a href="http://download.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html">JVMTI</a> (Java Virtual Machine Tools Interface) que ha sido introducido a partir de Java 5. En el caso de que utilicéis una versión anterior podréis hacer uso de este mecanismo mediante una versión basada en classloaders específicos.</div><div style="text-align: justify;"><br />
</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-14190014045515630282011-05-27T21:29:00.000+02:002011-05-27T21:29:56.869+02:00Weaving en AspectJ (I)<div style="text-align: justify;">Hace un tiempo escribí una serie de entradas relacionadas con la orientación a aspectos en general y AspectJ en particular (podéis encontrar dichas entradas <a href="http://miguelinlas3.blogspot.com/search/label/AOP">aquí</a>) que posteriormente agrupé en un <a href="http://www.slideshare.net/miguelinlas3/aop-4570210">documento</a>.<br />
<br />
Hasta este momento nos hemos centrado en la teoría de la orientación a aspectos, cómo escribir los mismos y algunas de sus posibles aplicaciones. Sin embargo, no hemos prestado especial atención al modo en el que los aspectos se combinan con las clases para componer nuestro sistema final. Durante esta entrada y las siguientes profundizaremos en diferentes aspectos del proceso de tejido (weaving).<br />
<br />
El mecanismo de tejido es aquel que nos permite combinar la definición de nuestras clases y de nuestros aspectos en un ente ejecutable que conforma nuestro sistema final.<br />
<br />
Podemos clasificar los diferentes modelos en base al momento en el que llevan a cabo el tejido. En este caso tendríamos:<br />
<br />
<ul><li><b>Build time</b>. Las clases y los aspectos son combinados durante el proceso de construcción de nuestra aplicación.</li>
</ul><ul><li><b>Load time (LTW)</b>. En este caso el tejido se realiza en el momento en el que una clase se carga en la máquina virtual, por lo que en este caso no será necesario llevar a cabo ningún proceso adicional en nuestro proceso de construcción. </li>
</ul><div>Otra posible clasificación podría establecerse en función del los tipos de entrada del proceso de weaving</div><div><ul><li><b>Source code weaving</b>. La entrada al proceso son archivos de código fuente (clases y aspectos)</li>
</ul><ul><li><b>Weaving binario (bytecode)</b>. La entrada al proceso es el <i>bytecode</i> obtenido como resultado del proceso de compilación de nuestras clases</li>
</ul></div><div>De manera esquemática, a continuación se reflejan las diferente combinaciones ofrecidas por el <i>weaver</i> de AspectJ:<br />
<br />
<ul><li>Tiempo de construcción: las entradas admitidas son tanto código fuente como clases compiladas (bytecode)</li>
</ul><ul><li>Tiempo de carga: las entradas pueden ser bytecode o un archivo xml (lo veremos más adelante)</li>
</ul><br />
Con esta pequeña entrada nos hemos aproximado de manera sencilla a los procesos de tejido presentes en <i>AspectJ</i> de una manera teórica. En futuras entradas analizaremos con un poco más de detalle los contenidos aquí presentados, haciendo especial hincapié en los mecanismos de tejido en tiempo de carga.<br />
<br />
Hasta pronto!</div></div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-69544385307536374752011-05-21T09:25:00.000+02:002011-05-21T09:25:14.299+02:00Libros: últimas y futuras lecturas (II)<div style="text-align: justify;">Esta es la primera entrada que escribo desde mi reciente adquisición: un IMac 27''. Lo siento, tenía que decirlo :). A ver si me acostumbro a este, para mi, nuevo sistema operativo y le comienzo a sacar partido.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En la <a href="http://miguelinlas3.blogspot.com/2011/05/libros-ultimas-y-futuras-lecturas-i.html">entrada anterior</a> hablaba sobre algunas de las últimas y/o futuras lecturas realizadas durante esta última temporada. Puesto que no quería convertir dicha entrada en un ladrillo, se me quedaron algunos libros en el tintero que analizaremos a continuación.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://ecx.images-amazon.com/images/I/51C7NLhY2aL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://ecx.images-amazon.com/images/I/51C7NLhY2aL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" width="200" /></a></div><div><br />
</div><div style="text-align: justify;">Este libro llego a mis manos gracias a un profesor visitante de la UPM que estuvo impartiendo un seminario sobre wait free computing. Siento no recordar ahora su nombre (vaya cabeza que tengo).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Los profesores Maurice Herlihy, uno de los precursores de la memoria transaccional, y Nir Shavit nos ofrecen una visión novedosa de los nuevos paradigmas de programación para arquitecturas multinúcleo.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Los primeros capítulos son más teóricos, dejando la parte más divertida para la segunda mitad del libro. No he tenido ocasión de leérmelo de principio a fin pero si que me he leído capítulos independientes y he de reconocer que me han parecido mucho mejor de lo que esperaba. Espero sacar un poco de tiempo libre para poder leerlo al completo porque todo apunta que se puede convertir en uno de mis libros favoritos.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://ecx.images-amazon.com/images/I/41-CJxuUV+L._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://ecx.images-amazon.com/images/I/41-CJxuUV+L._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" width="200" /></a></div><div style="text-align: justify;">Desde que programo en Scala he aprendido muchas cosas nuevas, ya no sólo del lenguaje, sino de la programación funcional en general.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Siempre he querido dar mis primeros pasos en Haskell pero nunca he tenido tiempo y, sinceramente, me parecía un poco complicado. Tras el inicio de mi andadura en Scala creo que lo veo con otros ojos así que, en la medida de lo posible, voy a intentar dar mis primeros pasos en este lenguaje. </div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Todas las referencias que tengo de este libro son muy buenas pero ni siquiera lo tengo así que, cuando me decida a dar el paso, creo que será mi próxima adquisición.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://joyofclojure.com/cover.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://joyofclojure.com/cover.jpg" width="159" /></a></div><div style="text-align: justify;">Mi fascinación por la máquina virtual java crece por momentos (creo que ya quedó patente en la entrada anterior).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Clojure es un lenguaje dinámico (dialecto de Lisp) que se ejecuta sobre la JVM (compila directamente a bytecode). Destaca, y esto es lo que más me gusta, por su eficiente infraestructura para la programación multihilo.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Básicamente es un lenguaje puramente funcional que destaca por su amplio abanico de estructuras de datos inmutables y persistentes. En aquellos casos en los que el cambio es algo necesario, Clojure incluye en el propio lenguaje un sistema de memoria transaccional.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">De nuevo se me quedan en el tintero muchos otros libros pero, de nuevo, no quiero que la entrada sea demasiado larga. En futuras entradas apostaré por comentar de uno en uno los libros ya leídos, intentando profundizar un poquito más de manera que si alguien estaba dudando si leérselo o no, puede tener una opinión más al respecto.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Hasta pronto! </div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-28302415012477508582011-05-14T09:33:00.000+02:002011-05-14T09:33:46.177+02:00Libros: últimas y futuras lecturas (I)<div style="text-align: justify;">Durante estos últimos meses mi tiempo libre se ha convertido en un bien escaso (prácticamente nulo) por lo que muchas de las cosas que me gusta hacer las he tenido que ir aplazando hasta encontrar un mejor momento. Una de ellas es actualizar el blog con una frecuencia un poco mayor a la habitual, y aprovechando que estoy en Esslingen (Alemania), que todo el mundo está durmiendo y que llevo rondando por ahí desde las seis y veinte de la maniana he decidido pasarme un rato por aquí :).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En esta ocasión me gustaría compartir con vosotros algunos de los últimos libros que me he leído, estoy leyendo, o tengo intención de leer.</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://www.artima.com/images/pins2Cover500x500.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://www.artima.com/images/pins2Cover500x500.gif" width="200" /></a></div><div style="text-align: justify;">Me he leído la primera edición y ahora estoy terminando la segunda. Creo que se trata de una referencia excelente tanto para aquellas personas que desean comenzar su andadura en Scala así como para desarrolladores más experimentados con conocimientos del lenguaje.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Si nunca habéis programado en Scala os recomiendo que le echéis un vistazo, os aseguro que no os defraudará. En este blog podréis encontrar una pequenia guía de introducción (en espaniol) así como numerosas entradas relacionadas con diferentes aspectos del lenguaje (espero que en un futuro este tipo de entradas puedan ir incrementando, tanto en calidad como en cantidad)</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://imagery.pragprog.com/products/227/vspcon.jpg?1300488499" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://imagery.pragprog.com/products/227/vspcon.jpg?1300488499" width="164" /></a></div><div style="text-align: justify;">Una de mis últimas adquisiciones. Está en Beta pero ya me lo he leído. Necesitará una lectura completa de nuevo, aunque en esta ocasión tendrá que ser delante de una pantalla de manera que pueda "ensuciarme" :) las manos.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En este libro se tratan algunas de las técnicas/plataformas más novedosas de programación concurrente sobre la máquina virtual java. Nuevos mecanismos de concurrencia en las últimas versiones de Java, análisis de las bondades de Clojure para la programación concurrente, memoria transaccional, modelos de actores, Akka (hablaremos de Akka en futuras entradas), Scala, GPars.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Una lectura recomendable para aquellos que quieran sacarle partido a los procesadores multinúcleo o que quieran actualizar sus conocimientos sobre programación concurrente.</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://www.manning.com/ghosh/ghosh_cover150.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://www.manning.com/ghosh/ghosh_cover150.jpg" width="161" /></a></div><div style="text-align: justify;">Qué son DSL? Para que se utilizan? Cómo escribo un DSL? En este libro , Debasish Ghosh desgrana hasta el último detalle de un temática tan popular en la actualidad como los lenguajes de dominio específicos. Una visión pragmática sobre la creación y utilización de lenguajes de dominio específicos ante la que ninguno se quedará indiferente. </div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">A lo largo del libro se desarrollan numerosos ejemplos (complejos en muchas ocasiones) de diversa índole. Scala, Groovy, Clojure, Ruby y Java son los lenguajes utilizados en el desarrollo de los ejemplos por lo que, este libro, además de la temática principal, puede servir como una primera toma de contacto con alguno de los lenguajes de la máquina virtual Java que están adquiriendo una notable popularidad en estos días.</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://www.packtpub.com/sites/default/files/imagecache/productview/8068EN_MockupCover_1.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://www.packtpub.com/sites/default/files/imagecache/productview/8068EN_MockupCover_1.jpg" width="164" /></a></div><div style="text-align: justify;">En este caso de trata de una recomendación de <a href="http://brigomp.blogspot.com/">Matín Pérez</a> a la que hacía tiempo que tenía ganas de meterle mano. No tengo una opinión forjada porque sólo llevo leídos dos capítulos pero la verdad que hasta el momento me está gustando mucho, tanto por la temática como por la manera que está escrito.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Recientemente he tenido la suerte de hacer algunas "cosillas" con la JVM pero por lo que he podido ver hasta el momento, este libro adquiere un nivel de detalle notable.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Prometo un post independiente cuando lo termine por completo pero me quedo con la idea de que este libro puede ayudar a escribir mejor código.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">No quiero convertir esta entrada en un ladrillo (si no lo he hecho ya :) ) así que vamos a detenernos aquí. Continuaremos en la siguiente entrada con alguno que se ma quedado en el tintero.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Hasta pronto!!</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">PD: Espero que no haya demasiadas faltas de ortogafía; me está costando escribir desde este teclado alemán.</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-45577064187073506512011-05-07T17:40:00.002+02:002011-05-07T17:46:32.085+02:00Parser Combinators: Parsing simple bytecode<div style="text-align: justify;">Anteriormente, <a href="http://miguelinlas3.blogspot.com/2011/03/parser-combinators-un-poco-de-teoria.html">http://miguelinlas3.blogspot.com/2011/03/parser-combinators-un-poco-de-teoria.html</a>, introducíamos de manera somera el concepto de parser combinators y parte de la teoría relacionada con los mismos. Durante esta entrada vamos a construir un sencillo parser que nos permita analizar un conjunto mínimo de instrucciones de la máquina virtual java (simplemente permitiremos la definición de funciones y la capacidad de ejecución de las mismas).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">No analizaremos en detalle el funcionamiento de la máquina virtual java ni el conjunto de instrucciones de la misma (podríamos llevarnos algo más que unos cuantos posts :) ) dado que el objetivo principal de esta entrada es profundizar en el concepto de parser combinators y presentar un ejemplo de uso real de los mismos. Pongámonos manos a la obra.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El código fuente que nos servirá como conductor de la entrada será el de la función factorial mostrado a continuación:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">static int fact(int);</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Code:</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Stack=2, Locals=3, Args_size=1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">0: iconst_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">1: istore_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">2: iconst_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">3: istore_2</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">4: iload_2</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">5: iload_0</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">6: if_icmpgt 19</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">9: iload_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">10: iload_2</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">11: imul</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">12: istore_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">13: iinc 2, 1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">16: goto 4</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">19: iload_1</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">20: ireturn</span></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Podréis objener el código desensamblado como el mostrado anteriormente mediante el comando <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">javap -v Class</span> donde Class represente un archivo bytecode.<br />
<br />
El proceso de parsing se lleva a cabo mediante el uso de parser combinators (no perdamos de vista el objetivo de nuestra entrada ;) ) y presenta las siguientes características<br />
<br />
<ol><li>Para cada una de las diferentes tipos de instrucciones soportadas definimos un parser combinator que es el encargado de parsear este tipo de instrucciones.</li>
<li>Cada uno de los parsers anteriores sabe cómo generar un objeto del tipo correspondiente. Se utiliza una jerarquía de tipos en la que cada una de las instrucciones bytecode soportadas está representada mediante una clase Scala.</li>
<li>El parser global construye un AST (en este caso es un simple lista de objetos) y un conjunto de infraestructura adicional con el objetivo de implementar un intérprete que ejecute la secuencia de instrucciones obtenida (fuera del ámbito de esta entrada podéis echarle un vistazo al código fuente)</li>
</ol><div>¿Cómo actúan nuestros diferentes parsers? Analicemos por ejemplo el componente encargado de parsear las instrucciones ISTORE</div><div><br />
</div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lazy val beginInstructionFragment: Parser[Int] = integer <~ ":" ^^ { _.toInt}</span></div><div><br />
</div><div><div style="text-align: left;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">lazy val iStoreBytecode: Parser[List[BytecodeInstruction]] = beginInstructionFragment ~> "istore_" ~ integer ^^ {</span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> case name ~ value => new IStoreInstruction(name,value) :: List()</span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> }</span></div></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br />
</span></div><div><div style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;">El parser </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">beginInstructionFragment</span><span class="Apple-style-span" style="font-family: inherit; font-size: small;"> es el encargado de parsear la primera parte de la instrucción, la que corresponde al lugar que ocupa la instrucción en el array de instrucciones. </span></div><div style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;"><br />
</span></div><div style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;">El segundo parser hace uso del primero y además sabe cómo parsear el texto restante de manera adecuada. En este caso nuestro este analizador es capaz de parsear las instrucciones istore_N donde N representa un número entero positivo cualquiera y devolver un objeto (dentro de una lista) de tipo IStoreInstruction en el que se incluyen el nombre de la instrucción y el entero correspondiente.</span></div><div style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;"><br />
</span></div><div style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;">Como seguramente a muchos de los lectores de este post el fragmento de código anterior les suene un poco raro intentaremos analizar las diferentes opciones de combinaciones de parsers disponibles</span><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: small;">:</span></div><div><ul><li>Si escribimos un parser en el que utilizamos una cadena, como por ejemplo "istore", el resultado es la propia cadena.</li>
<li>Podemos utilizar expresiones regulares, como por ejemplo, <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">"[A-Z]".r</span> . En este caso el resultado también sería la propia cadena</li>
<li>Si utilizamos el símbolo ~ (composición secuencial) el resultado del proceso de parseo será la combinación de ambos resultados. Por tanto, si A devuelve "X" y B devuelve "true", el resultado de A~B sería ~("X","true") (el tipo de este resultado sería una <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">case class</span> de tipo ~ . Adicionalmente podemos hacer uso de los operadores <~ y ~> los cuales mantienen los valores a la izquierda y a la derecha respectivamente.</li>
<li>Otro elemento de combinación de parsers sería | . En este caso el valor de retorno sería el de aquel parser que pudiera parsear la entrada con éxito.</li>
<li><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">rep(P) o rep(P,separator)</span> retornan una lista de las múltiples ejecuciones de P.</li>
<li>opt(P) retorna una instancia de tipo <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Option</span>.</li>
</ul><div>Adicionalmente a la combinación de los parsers, necesitaremos un mecanismo que nos permita reescribir la salida de los mismos, en nuestro caso para instanciar los objetos de tipo necesario y configurar nuestro AST. Para ello tendremos que hacer uso del operador de transformación ^^.</div></div><div><br />
</div><div>Una definición formar del operador anterior sería: Dado un parser P y una funcion f cualesquiera, una expresión del tipo P^^f implica que para cada resultado R de P el resultado de la expresión global es f(R) </div><div style="font-family: 'Courier New', Courier, monospace; font-size: small;"><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: small;"><br />
</span></div><div>En el ejemplo que estamos tratando nuestra función es un simple pattern matching que transforma la case class retornada por nuestra combinación de parsers en un objeto de tipo <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">IStoreInstruction.</span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br />
</span></div><div><span class="Apple-style-span" style="font-size: x-small;"><span class="Apple-style-span" style="font-family: inherit; font-size: small;">No me ha resultado sencillo ponerlo por escrito y tampoco estoy seguro de que me haya explicado con la mayor claridad posible. Si estáis interesados os recomiendo que clonéis el repositorio alojado en</span><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: small;"> <a href="https://github.com/">GitHub</a></span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: small;"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">git://github.com/migue/parser-combinators.git</span></div><div><br />
</div><div>Hasta pronto!</div></div></div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com0tag:blogger.com,1999:blog-35092134.post-63492474578047880672011-04-29T18:58:00.000+02:002011-04-29T18:58:04.169+02:00Nuevo disco de Natch<div style="text-align: justify;">El nuevo disco de Natch Scratch, <b>Mejor que el silencio,</b> únicamente puede calificarse como algo ABSOLUTAMENTE INCREÍBLE.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Una de las canciones que más me gusta:<br />
<br />
</div><div style="text-align: justify;"><iframe allowfullscreen="" frameborder="0" height="349" src="http://www.youtube.com/embed/ntVCYd3BGGo?rel=0" width="500"></iframe><br />
<br />
Hasta pronto!<br />
<br />
PD: este finde intentaré continuar con el tema de los combinator parsers en Scala</div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com1tag:blogger.com,1999:blog-35092134.post-5884778281259444482011-03-30T00:02:00.002+02:002011-05-07T17:40:32.751+02:00Parser Combinators: un poco de teoría<div style="text-align: justify;">Puede que en algunas ocasiones os hayais tenido que enfrentar con la necesidad de escribir un pequeño lenguaje que realice una tarea muy concreta (profundizaremos en el tema de los DSLs en un post futuro): como, por ejemplo, procesar determinados archivos de configuración de vuestra aplicación o la definición de interfaces de usuario de manera sencilla.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Independientemente de las razones por las que estamos desarrollando este componente, necesitaremos un parser que nos ayude a transformar el lenguaje de entrada en una estructura de datos que nuestro programa pueda comprender y procesar. Algunas de las alternativas que se nos plantean son:</div><div style="text-align: justify;"></div><ul><li><b>Escribir nuestro propio parser</b> (conllevaría escribir también el analizador léxico). Si no somos expertos en la materia estaremos enfrentándonos a una tarea relativamente complicada.</li>
</ul><ul><li><b>Utilizar herramientas para la generación de parsers como Antlr,Bison o JavaCC</b> entre otras muchas. En este caso la dificultad estriba en la necesidad de aprender a manejar una nueva herramienta/lenguaje e integrarlo en nuestro desarrollo y ecosistema.</li>
</ul><div style="text-align: justify;">Durante esta entrada, y posiblemente la siguiente, vamos a presentar un enfoque alternativo a las dos opciones anteriores. En lugar de utilizar un DSL externo como podría ser el ofrecido por Antlr, vamos a utilizar un DSL interno. Dicho DSL estará formado por <b>parser combinators</b> (funciones y operadores definidos en Scala que servirán como base para la construcción de nuestros futuros parsers).</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Siendo originales :), imaginemos que deseamos cosntruir un parser de expresiones aritméticas de números enteros. En primer lugar, definamos la gramática de nuestro lenguaje:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">expr ::= term {"+" term | "-" term}. </span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">term ::= factor {"*" factor | "/" factor}.</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">factor ::= integer | "(" expr ")".</span></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El fragmento de código anterior representa una gramática libre de contexto (no vamos a profundizar en este tema porque tendríamos que escribir miles de posts) que modela nuestro lenguaje de expresiones aritméticas de números enteros. ¿Y ahora?</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Una vez definida la gramática anterior hemos llevado a cabo la tarea más complicada de todas. Si utilizais los <b>parser combinators</b> ofrecidos por Scala tendremos casi todo el trabajo sucio realizado. A modo de ejemplo:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">import scala.util.parsing.combinator._</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br />
</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">class IntegerArithmetics extends JavaTokenParsers {</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> def expr: Parser[Any] = term~rep("+"~term | "-"~term)</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> def term: Parser[Any] = factor~rep("*"~factor | "/"~factor)</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> def factor: Parser[Any] = integer | "("~expr~")"</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">}</span></div><div><br />
</div></div><div style="text-align: justify;">Si comparamos el código Scala con la definición en notación EBNF de nuestra gramática observaremos que podríamos inferir nuestro código fuente Scala sin más que realizar una serie de reemplazos en nuestra notación EBNF:</div><div style="text-align: justify;"><ol><li>Cada regla se convierte en un método por lo que tendremos que prefijarlas con <b>def</b>.</li>
<li>El tipo de retorno de cada uno de los métodos anteriores es <b>Parser[Any]</b> (veremos en la siguiente entrada que significa esto) por lo que tendremos que cambiar el símbolo "<b>::=</b>" por "<b>:Parser[Any] =</b>"</li>
<li>Insertar el símbolo ~ entre todos los elementos de cada una de las reglas (en la notación EBNF esto es implícito)</li>
<li>La repetición se refleja mediante el uso de <b>rep(...)</b> en lugar de <b>{...}</b></li>
<li>El punto al final de cada regla no es necesario (podríamos poner ; si lo deseamos)</li>
</ol></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Esto no ha sido más que una toma de contacto con el mundo de los parser combinators en Scala. En la siguiente entrada descubriremos cómo realizar construcciones más complejas, formatear la salida de manera que podamos construir las estructuras de datos requeridas para nuestro procesamiento o ejecutar nuestros parsers. </div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Para todo ello diseñaremos y construiremos un pequeño parser que nos permita analizar el bytecode de la máquina virtual una vez desemsamblado (para los más inquietos <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">javap -v ClassFile</span> (sin .class))</div></div>miguehttp://www.blogger.com/profile/00380329298723040751noreply@blogger.com2