Wednesday, October 3, 2018

Giving new life to existing Om legacy SPAs with re-om


We’re pleased to announce that our client GreenPowerMonitor has allowed us to open-source re-om, an event-driven functional framework which is giving new life to an existing legacy SPA that uses Om.

Why re-om?

1. The problem with our SPA: imperative programming everywhere.

We are working on a legacy ClojureScript SPA, called horizon, that uses Om.

This SPA might have had some kind of architecture in some moment in the past but technical debt, lack of documentation and design flaws had blurred it. Business logic (in this case, pure logic that decides how to interact with the user or data transformations) and effectful code were not clearly separated.

This lack of separation of concerns was making the SPA hard to evolve because its code was difficult to understand and to test. This resulted in a very low test coverage that amplified even more the problems to evolve the code safely and at a sustainable pace. This was generating a vicious circle.

Even more, conflating pure and effectful code destroys the advantages of functional programming. It doesn’t matter that we’re using a language like Clojure, without clear isolation between pure and effectful code, you’ll end up doing imperative programming.

2. A possible solution: effects and coeffects.

Using effects and coeffects is a way of getting the separation of concerns we were lacking. They help achieve a clear isolation of effectful code and business logic that makes the interesting logic pure and, as such, really easy to test and reason about. With them we can really enjoy the advantages of functional programming.

Any piece of logic using a design based on effects and coeffects is comprised of three parts:

  1. Extracting all the needed data from “the world” (using coeffects for getting application state, getting component state, getting DOM state, etc).
  2. Using pure functions to compute the description of the side effects to be performed (returning effects for updating application state, sending messages, etc) given what was extracted from “the world” in the previous step (the coeffects).
  3. Performing the side effects described by the effects returned by the pure functions executed in the previous step.

At the beginning, when re-om wasn’t yet accepted by everyone in the team, we used coeffects and effects which were being manually created to improve some parts of the SPA, (have a look at Improving legacy Om code (I) and Improving legacy Om code (II)), but this can get cumbersome quickly.

3. An event-driven framework with effects and coeffects: re-frame.

Some of us had worked with effects and coeffects before while developing SPAs with re-frame and had experienced how good it is. After working with re-frame, when you come to horizon, you realize how a good architecture can make a dramatic difference in clarity, testability, understandability and easiness of change.

Having a framework like re-frame removes most of the boilerplate of working with effects and coeffects, creating clear boundaries and constraints that separate pure code from effectful code and gives you a very clear flow to add new functionality that’s very easy to test and protect from regressions. In that sense re-frame’s architecture can be considered what Jeff Atwood defined as a pit of success because it is:

“a design that makes it easy to do the right things and annoying (but not impossible) to do the wrong things.”

4. Why not use re-frame then?

In principle using re-frame in our SPA would have been wonderful, but in practice this was never really an option.

A very important premise for us was that a rewrite was out of the question because we would have been blocked from producing any new feature for too long. We needed to continue developing new features. So we decided we would follow the strangler application pattern, an approach which would allow us to progressively evolve our SPA to use an architecture like re-frame’s one, while being able to keep adding new features all the time. The idea is that all new code would use the new architecture, if it were pragmatically possible, and that we would only change bit by bit those legacy parts that needed to change. This means that during a, probably long, period of time inside the SPA, the new architecture would have to coexist with the old imperative way of coding.

Even though, following the strangler application pattern was not incompatible with introducing re-frame, there were more things to consider. Let’s examine more closely what starting to use re-frame would have meant to us:

4. 1. From Om to reagent.

re-frame uses reagent as its interface to React. Although I personally consider reagent to be much nicer than Om because it feels more ‘Clo­jur­ish’, as it is less verbose and hides React’s complexity better that Om (Om it’s a thinner abstraction over React that reagent), the amount of view code and components developed using Om during the nearly two years of life of the project made changing to reagent too huge of a change. GreenPowerMonitor had done a heavy investment on Om in our SPA for this change to be advisable.

If we had chosen to start using re-frame, we would have faced a huge amount of work. Even following a strangler application pattern, it would have taken quite some time to abandon Om, and in the meantime Om and reagent would have had to coexist in our code base. This coexistence would have been problematic because we’d have had to either rewrite some components or add complicated wrapping to reuse Om components from reagent ones. It would have also forced our developers to learn and develop with both technologies.

Those reasons made us abandon the idea of using re-frame, and chose a less risky and progressive way to get our real goal, which was having the advantages of re-frame’s architecture in our code.

5. re-om is born.

André and I decided to do a spike to write an event-driven framework using effects and coeffects. After having a look at re-frame’s code it turned out it wouldn’t be too big of an undertaking. Once we had it done, we called it re-om as a joke.

At the beginning we had only events with effects and coeffects and started to try it in our code. From the very beginning we saw great improvements in testability and understandability of the code. This original code that was independent of any view technology was improved during several months of use. Most of this code ended being part of reffectory.

Later our colleague Joel Sánchez added subscriptions to re-om. This radically changed the way we approach the development of components. They started to become dumb view code with nearly no logic inside, which started to make cumbersome component integration testing nearly unnecessary. Another surprising effect of using re-om was that we were also able to have less and less state inside controls which made things like validations or transformation of the state of controls comprised of other controls much easier.

A really important characteristic of re-om is that it’s not invasive. Since it was thought from the very beginning to retrofit a legacy SPA to start using an event-driven architecture with an effects and coeffects system, it’s ideal when you want to evolve a code base gradually following a strangler application pattern. The only thing we need to do is initialize re-om passing horizon’s app-state atom. From then on, re-om subscriptions will detect any changes made by the legacy imperative code to re-render the components subscribed to them, and it’ll also be able to use effect handlers we wrote on top of it to mutate the app-state using horizon’s lenses and do other effects that “talk” to the legacy part.

This way we could start carving islands of pure functional code inside our SPA’s imperative soup, and introduced some sanity to make its development more sustainable.

re-om & reffectory

We’ve been using re-om during the last 6 months and it has really made our lives much easier. Before open-sourcing it, we decided to extract from re-om the code that was independent of any view technology. This code is now part of reffectory and it might be used as the base for creating frameworks similar to re-om for other view technologies, like for example rum, or even for pure Clojure projects.


We’d like to thank GreenPowerMonitor for open-sourcing re-om and reffectory, all our colleagues at GreenPowerMonitor, and the ones that are now in other companies like André and Joel, for using it, giving feedback and contributing to improve it during all this time. We’d also love to thank the re-frame project, which we think is a really wonderful way of writing SPAs and on which we’ve heavily inspired re-om.

Give it a try.

Please do have a look and try re-om and reffectory. We hope they might be as useful to you as they have been for us.

Originally published in Codesai's blog.

Sunday, September 30, 2018

Books I read (January - September 2018)

- The Plateau Effect: Getting from Stuck to Success, Bob Sullivan & Hugh Thompson
- The Thirty-Nine Steps, John Buchan
- Memento Mori, Muriel Spark
- Cosmonauta, Pep Brocal
- The Man Who Was Thursday: A Nightmare, G. K. Chesterton
- Ébano, Alberto Vázquez-Figueroa
- The Subtle Art of Not Giving a F*ck: A Counterintuitive Approach to Living a Good Life, Mark Manson
- The Importance of Being Earnest, Oscar Wilde

- The Maltese Falcon, Dashiell Hammett
- This Is Water, David Foster Wallace
- Judas, Amos OZ
- Never Let Me Go, Kazuo Ishiguro.
- Microservice Architecture: Aligning Principles, Practices, and Culture, Mike Amundsen, Matt McLarty, Ronnie Mitra, Irakli Nadareishvili

- On Anarchism, Noam Chomsky
- The Fire Next Time, James Baldwin
- Esperanza en la oscuridad, La historia jamás contada del poder de la gente (Hope in the Dark: Untold Histories, Wild Possibilities), Rebecca Solnit
- The Dispossessed: An Ambiguous Utopia, Ursula K. Leguin
- Release It!: Design and Deploy Production-Ready Software, Michael T. Nygard

- Sin blanca en Paris y Londres (Down and Out in Paris and London), George Orwell
- The Garden of the Finzi-Continis (Il giardino dei Finzi-Contini), Giorgio Bassani
- Test Driven Development: By Example, Kent Beck (2nd time)
- Just Enough: Tools for Creating Success in Your Work and Life, Laura Nash and Howard Stevenson
- The Left Hand of Darkness, Ursula K. Leguin
- The Heat of the Day, Elizabeth Bowen

- Radetzky March (Radetzkymarsch), Joseph Roth
- Death of a Salesman, Arthur Miller
- A Raisin in the Sun, Lorraine Hansberry
- Improve Your People Skills: Build and Manage Relationships, Communicate Effectively, Understand Others, and Become the Ultimate People Person, Patrick King
- Flatland: A Romance of Many Dimensions, Edwin Abbott
- The Hard Truth About Soft Skills: Workplace Lessons Smart People Wish They'd Learned Sooner, Peggy Klaus

- The Little Guide to Empathetic Technical Leadership, Alex Harms
- Patria, Fernando Aramburu
- How to Be an Imperfectionist: The New Way to Fearlessness, Confidence, and Freedom from Perfectionism, Stephen Guise
- Dragon's Egg, Robert L. Forward

- Deep Work: Rules for Focused Success in a Distracted World, Cal Newport
- Essay and report writing skills, The Open University
- El candelabro enterrado (Der begrabene Leuchter), Stefan Zweig
- To Engineer Is Human: The Role of Failure in Successful Design, Henry Petroski
- La evolución de Calpurnia Tate (The Evolution of Calpurnia Tate), Jacqueline Kelly
- The Secret Agent: A Simple Tale, Joseph Conrad
- Men Explain Things to Me, Rebecca Solnit
- Facts And Fallacies Of Software Engineering, Robert L. Glass

- The Lonely Londoners, Samuel Selvon
- El poder y la palabra: 10 ensayos sobre lenguaje, política y verdad, (Spilling the Spanish Beans, New Words, Literature and Totalitarianism, Pamphlet Literature, Propaganda and Demotic Speech, The Prevention of Literature, Politics and the English Language, In Front of Your Nose, Writers and the Leviathan, The Principles of Newspeak), George Orwell
- Comportarse como adultos: mi batalla contra el establishment europeo, (Adults in the Room: My Battle With Europe's Deep Establishment), Yanis Varoufakis
- Patterns of Software: Tales from the Software Community, Richard P. Gabriel
- Passing, Nella Larsen
- Why Information Grows: The Evolution of Order, from Atoms to Economies, César A. Hidalgo
- The Martians of Science: Five Physicists Who Changed the Twentieth Century, István Hargittai

- On Dialogue, David Bohm
- The Alteration, Kingsley Amis
- Pavane, Keith Roberts
- The Logic of Failure: Recognizing and Avoiding Error in Complex Situations, Dietrich Dörner
- Extending and developing your thinking skills, The Open University

Tuesday, September 11, 2018

Cursos en abierto en Canarias

En la primera mitad de este año no habíamos podido hacer ningún curso de TDD en abierto. Nos absorbió el trabajo diario, la agenda de eventos en los que participamos, y todas las reuniones, decisiones y papeleos que tuvimos para lanzar nuestra cooperativa. Era una pena porque nos encanta hacer cursos en abierto por el entusiasmo y las ganas de trabajar y de aprender con las que vienen las personas que asisten a ellos. Para nosotros estos cursos son también muy interesantes porque nos permiten conocer a personas, que, en ocasiones, acaban colaborando con Codesai. Ese fue, por ejemplo, mi caso o el de Luis.
Por eso, justo después de constituir la cooperativa, Fran y yo decidimos liarnos la manta a la cabeza y anunciar que haríamos un curso en abierto en Tenerife un mes después, a mitad de Julio, justo antes del comienzo de las vacaciones para muchos. Teníamos muy poco tiempo para anunciarlo, pero era una oportunidad muy buena para empezar a movernos como cooperativa y para seguir refinando el nuevo material que ya habíamos usado en los cursos de TDD que hemos hecho este año en Merkle y Gradiant. Una vez empezamos a organizarlo, pensé que podría dar otro curso en Gran Canaria con Ronny para aprovechar el viaje. Con lo que al final dimos dos cursos en abierto en una semana: el 9 y 10 de Julio en Las Palmas de Gran Canaria y el 12 y 13 de Julio en Santa Cruz de Tenerife.

Al curso de Gran Canaria vinieron seis personas. La mayoría de ellas trabajaban en AIDA, una empresa con la que trabajamos durante muchos años y con la que tenemos una relación muy cercana. El curso fue intenso porque el nivel de conocimiento de las personas que vinieron era muy dispar. Trabajamos mucho con las parejas durante los ejercicios prácticos e incluso hicimos una sesión extra una semana después en las oficinas de AIDA en la que terminamos de hacer el último ejercicio del curso. Ronny y yo acabamos muy satisfechos y recibimos muy buen feedback de los asistentes, tanto en persona, como en los formularios para dejar tu opinión de forma anónima que siempre suelo enviar unas semanas después. El curso nos sirvió también para experimentar con algunas nuevas secciones sobre cómo usar dobles de prueba de forma sostenible, y sacamos bastante información para aplicar en próximos cursos.

Al día siguiente volé a Tenerife, donde me esperaba Fran en el aeropuerto, y nos fuimos a su casa donde hicimos los últimos preparativos, y descansamos hasta el día siguiente en que empezaba el curso. Al curso de Tenerife asistieron siete personas que venían de diferentes empresas. La gran mayoría eran personas que habían sido antiguos compañeros de Fran, entre ellos, algunos de sus antiguos mentores, por lo que fue un curso muy especial para él. Yo también disfruté mucho. En este curso el nivel de los asistentes era bastante alto y salieron debates muy interesantes. De nuevo recibimos muy buen feedback al terminar.

Una novedad de estos cursos fue que ofrecimos por primera vez un descuento del 50% para colectivos poco representados en la tecnología. Este descuento es algo que hemos decidido ofrecer de ahora en adelante en nuestros cursos en abierto.
Viendo los cursos en perspectiva después de unos meses, creo que aprendimos varias cosas:
  • Un mes es muy poco tiempo para promocionar un curso (cómo no ㋡), sobre todo en un mercado tan pequeño como Canarias. Sólo gracias a nuestra red de contactos y a empresas con las que ya habíamos trabajado en el pasado individualmente o como Codesai pudimos conseguir gente suficiente para hacer el curso rentable.
  • El nuevo material está funcionando bastante bien. Estamos consiguiendo mantener el nivel de satisfacción que había con el curso anterior, al mismo tiempo que estamos pudiendo profundizar en temas que el material anterior no tocaba o lo hacía de forma muy superficial.
  • Los canales de comunicación que usamos habitualmente para promocionar nuestros cursos, Twitter y LinkedIn no fueron suficiente para atraer a personas de colectivos poco representados en la tecnología. Sólo dos asistentes aprovecharon el descuento del 50%. Tenemos que buscar otras formas de llegar a estas personas. De hecho, si lees esto y conoces a gente a la que le pudiese interesar, por favor, corre la voz.
Personalmente me alegro mucho de haber decidido mover estos cursos, porque he conocido a gente muy interesante y muy agradable con la que espero seguir en contacto, ¡muchas gracias a todos!, por la satisfacción del trabajo en sí mismo, y por los buenos ratos y conversaciones que tuve con mis compañeros Ronny y Fran. Esto es algo que es muy valioso e importante porque al estar distribuidos en diferentes regiones (e incluso países) y trabajar en diferentes clientes se echa de menos el contacto humano con los compañeros. Por eso cada curso y/o cada consultoría presencial que hacemos en pareja es una gran oportunidad para reforzar la relación que nos une. Ronny, Fran, muchísimas gracias por la acogida y todos los buenos ratos.

Antes de terminar quería dar las gracias a Manuel Tordesillas por el gran trabajo que hizo preparando todas las katas del curso en C#.
PS: Nuestro próximo curso en abierto de TDD será el 18 y 19 de Octubre en Barcelona, y de nuevo haremos un descuento del 50% para colectivos poco representados en la tecnología. Corre la voz ㋡

Originally published in Codesai's blog.