Articulos recientes
PyCon Argentina 2009
Ago 18, 2009 Links Leave a comment
Copiado textualmente de ¡Vamos todos a PyCon Argentina! (del blog de Facundo Batista)
Está abierta la inscripción para participar de PyCon Argentina 2009, la primera conferencia en castellano sobre el lenguaje de programación Python, a realizarse los días 4 y 5 de septiembre en la sede de la Universidad de Belgrano, Zabala 1837, en la Ciudad de Buenos Aires.
En esta primera edición contaremos con la participación de Jacob Kaplan-Moss (creador de Django) y Collin Winter (core developer de Python) como invitados especiales del evento, y con más de 30 charlas sobre Python y temas relacionados, desde tutoriales para principiantes hasta charlas de nivel avanzado. Miren el cronograma de charlas, ¡está buenísimo!
La entrada es libre y gratuita. Para evitar contratiempos, confirmar su asistencia y recibir credencial y demás materiales de la conferencia, se recomienda realizar inscripción previa en el sitio web.
Va a estar genial.
Yo voy a ir, hay varias charlas que me interesan, seguramente me vean en la audiencia de:
- Python como lenguaje de hacking.
- Extendiendo PostgreSQL con Python.
- Hacking Django, mismo framework, distintos paradigmas.
- Escribi menos codigo, pensa como un (buen) matematico.
- Twisted para seres humanos.
Y los plenarios de Jacob Kaplan-Moss y Collin Winter.
RE: Writing good code requires you to perform experiments
Ago 17, 2009 Articulos, Respuestas 2 Comments
Acabo de leer el articulo Writing good code requires you to perform experiments. El titulo me llamo bastante la atencion, siempre “experimento” con pequeños snippets de código cuando estoy programando, de hecho tengo un shortcut (”Control Mod1 P :ExecCommand aterm -tint green -e python” en el .fluxbox/keys) para iniciar una terminal de Python ni bien tengo una pequeña duda o quiero “experimentar”. Pero para mi asombro, detrás de un titulo prometedor encontré un par de malos consejos.
Primero los dos puntos que rescato del articulo como ciertos (al menos en mi experiencia):
Es poco probable, casi imposible, que un poco de código recién escrito funcione como esperamos: Esto es especialmente cierto con los ejemplos que da de consultas a la base de datos y expresiones regulares. Siempre una tarea, por mas insignificante o banal que parezca puede contener errores.
Probar una funcionalidad o un poco de código dentro de una aplicación es ineficiente: Existen tiempos muertos entre que arranca el programa y el flujo del mismo llega hasta donde esta nuestro nuevo segmento de código. Hay que agregar que esta tarea es iterativa: tenemos que repetir el proceso hasta tener el resultado que queremos (o todos los resultados que queramos si son varias opciones). Y a esto tenemos que sumarle el tiempo de compilación (Si el lenguaje que utilizamos lo requiere).
Habiendo leído esto mi conclusión es ese código debe estar en un test case del proyecto. Pero esta es la respuesta del autor a esta idea:
Some of you may now be thinking that the obvious solution is to write a proper unit test and run that unit test after every modification, until the code passes the test. I agree that goes a long way, but usually the test is part of a larger number of classes and running all those tests takes times, especially if it bootstraps an entire Spring-Hibernate application or something of the like.
Y ahí mi horror, respondo por partes:
but usually the test is part of a larger number of classes
Una funcionalidad básica de la mayoría de las librerías para correr test cases es elegir correr un solo test de la test suite. Para mi eso es muy importante justamente por este caso que esta nombrando, y siempre me fijo (cuando elijo una librería al menos) que cuenta con esta funcionalidad, se me vienen a la mente la librería de unittest de Python y CppUnit.
especially if it bootstraps an entire Spring-Hibernate application or something of the like
Voy a evitar el chiste fácil de decir que mi segundo horror es que usan Java y referirme a lo que importa: ¿Por que debería hacer falta iniciar toda una aplicación para probar un pequeño pedazo de esta? Eso me suena a mucho coupling:
Si tenes un código lo suficientemente no trivial como para que lo hallas tenido que probar antes, merece al menos su propia función con su propio test case. Es una simple premisa de manejar la complejidad del código que estas desarrollando. Un nombre de la función va a describir mejor lo que pretendes hacer que tener que parsear con la mente la expresión regular que estas escribiendo. Y si tiene su propia función: ¿Para que vas a levantar todo el programa para probar solamente esa función? El test case debería limitarse a probar esa, y solamente esa, función, a lo sumo mockear (del ingles mock, “imitar”) sus dependencias.
En conclusión: Experimentar es bueno, sirve para sacarse dudas de como funciona una librería, que hace con cada parámetro, etc. Pero una ves que empezamos a escribir un código que es probable que llegue a producción, tiene que ser probado por su correspondiente test case y ser versionado en el SCM que utilicemos.
Herramientas: Una buena obsesión
May 6, 2009 Articulos, Libros 5 Comments
Como ya mencioné en otros posts la elección de las herramientas con las que trabajo es una obsesión, una sana pero exigente obsesión. Considero a esa particular mirada a como trabajo y si lo hago lo suficientemente efectivo como sana porque me gusta trabajar menos. ¿A quien no? Si hay algo que estoy haciendo de una forma no-óptima en mi trabajo quiero darme cuenta, corregirlo, y disfrutar de ese tiempo haciendo otras cosas.
En su libro The 7 Habits of Highly Effective People Stephen Covey crea una de las analogías mas claras sobre esto:
Un hombre se encontró con un leñador en las montañas. El hombre paro a observar al leñador, mirándolo atentamente mientras talaba un gran árbol. El noto que el leñador sudaba mientras trabajaba talando y talando, pero que no avanzaba mucho en su tarea. El espectador entonces noto que la a sierra que el leñador estaba usando estaba tan afilada como un cuchillo de manteca. Entonces le dijo: “Disculpe señor leñador, no pude dejar de notar que duro que esta trabajando en ese árbol, pero sin avanzar mucho”. El leñador respondió mientras se secaba el sudor de la frente, “Si… lo se. Este árbol me esta dando algunos problemas.”. El espectador entonces le dijo, “Pero señor leñador, su sierra tiene tan poco filo que es imposible que corte algo.” “Lo se”, dijo el leñador, “pero estoy muy ocupado talando este árbol como para ponerme a afilar la sierra.”
“Sharpen the Saw”, The 7 Habits of Highly Effective People, Stephen R. Covey, 1989
Si bien el libro no es exclusivo de programadores recomiendo leerlo porque sirve bastante bien para nuestra disciplina.
Personalmente considero que de las herramientas que utilizo día a día le saco el jugo a unas pocas, vim, firefox, zsh y la shell en general, y quizás a Python como lenguaje de scripting para automatizar las tareas repetitivas. Pero sin mucho esfuerzo veo muchos mas lugares donde podría mejorar los programas que uso o elegir mejores programas para usar:
El rol que cumplo en mi trabajo se puede llamar “Project Manager Pulpo”, porque son varios los proyectos que “llevo adelante” y una de las formas de comunicación mas comunes es el email, para el cual utilizo Thunderbird. Hay decenas de metodologías para organizar/seguir varios temas por email, yo personalmente sigo una versión bastante liberal de GTD (Getting Things Done: The Art of Stress-Free Productivity, David Allen, 2002) pero mucho del trabajo que hago es manual (Como marcar emails con etiquetas “Por Hacer” y “Esperando Respuesta”), debería automatizar eso, y quizás pasarme a mutt, getmail, maildrop y scriptearlo un poco mas así hago uso de vim en mutt.
El libro que estoy leyendo ahora es The Productive Programmer, si bien aun voy por los primeros capítulos ya me dio bastantes temas en los que pensar, y me motivo a hacer algunas pruebas: utilizar macros (una función de vim que siempre supe que existía pero ignore deliberadamente), utilizar un program launcher (tenia keybinds a los programas mas utilizados, pero con Gnome-Do ahora puedo hacer prácticamente todo sin mover mis manos del teclado hacia el mouse), aprovechar mejor algunas funcionalidades de los SCM que utilizo (Mercurial y Subversion), y hasta aprovechar de forma eficiente los virtual desktops.
Hoy en Hacker News, un muy buen sitio si buscan estar informados del ambiente IT internacional, salio la siguiente pregunta: “Ask HN: Why no love for PHP? ” y me dio mucha risa la primer respuesta:
Las personas que son realmente buenas en sus trabajos se obsesionan sobre sus herramientas. Los artistas se obsesionan sobre la pintura, los carpinteros sobre sus herramientas a medida y los cocineros sobre sus cuchillos.
PHP es como comprar un cuchillo de chef en Wal-Mart. Vos podes hacer un plato 5 estrellas con el, corta perfectamente, pero no inspira la misma pasión que un cuchillo Shun.
Esto se extiende a todo. Si elegís el mejor editor de texto, uno completo como el que describí en mi primer post en este blog, vas a darle un uso y una importancia mucho mas alta que la que va a tener notepad que también puede editar código. Si elegís cualquier SCM, seguramente sea para tirar código ahí, si evalúas los pro y contras de cada uno seguramente cuando lo uses vas a aprovechar esos pro y no ignorarlos o dejarlos en desuso.
Dejo para otro día elaborar una lista de lo que podría considerarse las herramientas básicas de cada programador, ya enumere editor y SCM pero creo que hay muchas mas y cada una se merece su artículo aparte.
¿Que hace a un buen commit?
May 5, 2009 Articulos 3 Comments
Estaba leyendo este artículo de Pablo Santos sobre como los changelogs que puede generar un SCM como Mercurial o Subversion pueden ser utilizados como “documentación” del código y del trabajo que se hizo sobre el y me puse a pensar: ¿Que hace un buen mensaje de commit?
Después de un par de ideas, la mayoría de las cuales las tengo por haberlas leídos en otros blogs, concluí que un buen mensaje cumple con los siguientes puntos.
- Es corto.
- Describe lo que se cambio, si es posible también porque.
- Referencia el ticket/email que hizo necesario el cambio en el código.
- Utilizar prefijos como FIX y ADD para identificar que es lo que se hizo.
Un buen ejemplo es el que puedo encontrar en esta discusión de StackOverflow:
Changed paragraph separation from indentation to vertical space.
…
Fix: Extra image removed.
Fix: CSS patched to give better results when embedded in javadoc.
Add: A javadoc {@link} tag in the lyx, just to show it’s possible.
…
- Moved third party projects to ext folder.
- Added lib folder for binary library files.
…
Fix: Fixed bug #1938.
Add: Implemented change request #39381.
Yo soy de los puristas que creen que el código se debe escribir en ingles, y, por extensión, los commit messages.
Pero hubo un punto de esa misma discusión que me llamo mas la atención:
If you find yourself writing a very long list of changes, consider splitting your commit into smaller parts
Que me llevo a pensar en algo mas importante del mensaje: ¿Que hace a un buen commit?
Un commit es, en la mayoría de los SCM, la acción por la cual los cambios que uno hizo al código en una copia que tenga en su PC son introducidos al repositorio general donde todo el resto puede ver y utilizar el código. El que sea bueno o malo depende de su utilidad, y en el caso de algo tan simple y delineado como “cambios al código” solamente tengo dos opciones: utilizar o descartar esos cambios.
Un buen commit es aquel que me permite ignorarlo o revertirlo,y seguir aprovechando el resto de las funcionalidades de otros commits previos y posteriores. Para que esto sea así un commit debe seguir algunos lineamientos:
- No arreglar o cambiar mas de una caso por commit.
- Los cambios tienen que ser chicos.
Mas de una ves vi joyas en los bugzilla de varios proyectos open source: discusiones, información, incluso documentación. Pero algo que siempre me asombro es que hay grandes patchs (en ambos sentidos, lo que aportan y el tamaño de los mismos), hechos por gente que no colabora habitualmente con el proyecto y que quedan ahí indefinidamente porque al ser tan grandes nadie los aplica como un commit.
Haciendo uso de Trac, una herramienta que incluye un wiki para documentar, un navegador del SCM en uso (Mercurial, SVN y GIT estan soportados, no se otros) y un sistema de tickets, puedo ver los cambios que se van comiteando a los distintos proyectos open source que uso, y es raro ver alguno que supere las 100 líneas con documentación y tests cases incluidos! (Ej: Django)
Dejo para otro post una buena descripción de los distintos SCM.
Microsoft no sabe Unicode
Abr 5, 2009 Articulos, Historias 5 Comments
El otro día estaba hablando con el DBA de SQL Server de donde trabajo, revisando una base que habíamos diseñado con los chicos del equipo de arquitectura y se dio una conversación mas o menos como la siguiente:
DBA: ¿Porque nvarchar en lugar de varchar? *
Yo: Es porque guardamos caracteres no-ascii en esos campos, así que necesitamos que fueran unicode.
DBA: Pero eso va a ocupar el doble de espacio.
Yo: ¿Por que? Si creamos la base de datos en latin-1 debería guardarlos en un solo carácter. **
DBA: No, unicode siempre guarda todo usando 2 bytes.
Yo: No, unicode no dice como guardar cosas, unicode le da un numero a cada letra y nada mas, mira, lee esto.
* El prefijo “n” en los tipos de datos de SQL Server denota unicode.
** Lo que había especificado, descubrí después, es el collation, es decir como compara las cadenas de texto cuando se hacen joins u order by.
El texto que le pase es The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) de Joel Spolsky, pero lo que me asombro fue esa ultima frase “unicode siempre guarda todo usando 2 bytes”, después de un poco de investigación por parte de ambos encontramos esto en MSDN:
The Unicode specification addresses this problem by using 2 bytes to encode each character.
En ese mismo momento hice Plop!
La documentación de Microsoft se equivoca: Unicode no dice como representar los caracteres.
El texto, como todo dato que se guarda en una computadora moderna, se representa con ceros y unos. Estos ceros y unos, llamados bits, se unen de a ocho para formar un byte, el byte representa la unidad mínima de datos que se puede leer (esto es una limitación creada por los distintos canales de entrada y salida de datos, como la red o el disco rígido). Ahora un byte, con sus ocho bits, solamente puede representar 256 combinaciones, desde 00000000 hasta 11111111. 256 combinaciones no son suficientes para representar todos los caracteres; nosotros en el alfabeto tenemos 27 letras incluyendo la ñ, pero hay otros caracteres, como el punto, la coma, etc. Si a esto le sumamos otras letras no propias del castellano (como las de los idiomas orientales), tenemos miles de caracteres.
Un poco de historia: En la primer época de la informática, con la única influencia cultural del ingles, se utilizaba ASCII para representar el texto: Una forma de identificar un numero cuya representación entraba en un byte con una letra o carácter, hoy en día es bastante común ver esta tabla pegada en cualquier pared de una habitación donde halla programadores:
Pero en cuanto la computadora se empezó a usar en otros entornos, y el guardar textos de otras culturas se hizo necesario, como por ejemplo textos en castellano con caracteres como la eñe, este modelo hizo agua. Se solvento la situación usando codepages, así un documento creado en Argentina se guardaba en el Code Page 850 (también conocido como “Multilingual (Latin-1) Western European languages”), y otro creado en Grecia usaba el Code Page 737.
Estos Code Pages utilizaban esas 256 combinaciones para representar distintas letras, así el numero que en el codepage 737 significaba β en el codepage 850 significaba Ö. Los primeros 128 números siempre eran los mismos que en la tabla ASCII, mientras que los siguientes 128 se utilizaban para letras que variaban de codepage en codepage.
Aunque precaria, esta solución funciono durante bastante tiempo, el problema que no pudo afrontar es el intercambiar archivos entre distintas culturas (Algo muy común en Internet): Si yo enviaba mi archivo a Rusia quien tratara de abrirlo iba a ver todo mi texto como algo incomprensible, dado que lo iba a estar tratando de interpretar en caracteres con un codepage distinto en el que yo lo cree.
Ahí es donde entra unicode: Definir como representar todas las letras del mundo, y de otros mundos también, de forma univoca y con una forma de identificar cada letra. Ese es el objetivo de unicode:
Fundamentally, computers just deal with numbers. They store letters and other characters by assigning a number for each one. Before Unicode was invented, there were hundreds of different encoding systems for assigning these numbers. No single encoding could contain enough characters: for example, the European Union alone requires several different encodings to cover all its languages. Even for a single language like English no single encoding was adequate for all the letters, punctuation, and technical symbols in common use.
These encoding systems also conflict with one another. That is, two encodings can use the same number for two different characters, or use different numbers for the same character. Any given computer (especially servers) needs to support many different encodings; yet whenever data is passed between different encodings or platforms, that data always runs the risk of corruption.
Unicode no define como guardar o representar esas letras, para eso existe un proyecto paralelo llamado Universal Character Set que si propone distintas formas de guardarlas.
Con eso en mente, repasemos la frase de MSDN:
The Unicode specification addresses this problem by using 2 bytes to encode each character.
2 bytes no son suficientes para la ambición del proyecto unicode, existen miles y miles de letras mas que las 65.536 que 2 bytes permiten representar.
Y en luz de todo esto surge el concepto de encodings: Formas de representar los distintos caracteres. Ejemplos de encoding son utf-8, latin-1 y ucs2.
Los encodings como UTF-8 o UCS2 nacieron con grandes ambiciones: Representar todos y cada uno de los caracteres que definiera el proyecto unicode. UCS2 encontró su techo pronto, al ser de un largo fijo, 2 bytes, una ves que supero los 65.536 caracteres se quedo corto. En cambio UTF-8 propone un esquema variable, donde un carácter puede ocupar 1 byte (Como todos los caracteres que componen ASCII) y (Como todo el resto de las letras) ocupan mas.
Otros encodings, como latin-1 ocupan siempre 1 byte, solamente se limitan a algunos caracteres que pueden representar con 256 opciones.
Cada uno de los encodings tienen sus ventajas y desventajas: Los encodings variables como UTF-8 permiten representar cadenas de texto en muchos lenguajes siendo eficientes en el espacio que ocupan (tanto sea en disco como en una comunicación por la red), pero son mas lentos de interpretar que un encodings como UCS2 en el cual sabemos de antemano que cada 2 bytes tenemos un carácter. Revisando un poco mas encontré este otro articulo de MSDN donde correctamente dicen que lo que usan es UCS2 y no “unicode”. Entiendo la elección de un encoding fijo para interpretar las cadenas de texto internamente, es igual a la que hace Python (en CPython al menos) para manejar todos los objetos del tipo de datos unicode como UCS2 en memoria.
Hoy en día vivimos en un escenario bastante complejo. El hecho de tener varias opciones para representar el texto nos hace no solo tener que elegir una, si no saber la que otros eligieron, me explico:
Si dos sistemas tienen que intercambiar texto entre si, deben también tener que intercambiar en que encoding esta ese texto.
Y es ahi donde empiezan los problemas que solemos encontrar: ¿Que pasa si un sistema no me dice en que encoding esta el texto que me envía?, ¿O si me lo dice en varios lugares y difieren entre si? ¿Y si lo que me dice esta mal?
Un ejemplo claro son los sitios web. Una pagina cualquiera tiene tres lugares donde puede definir en que encoding esta el texto que presenta:
En primer lugar esta el header de Content-Type, que al pedir la pagina puede decirnos el encoding, como por ejemplo “Content-Type: text/html; charset=ISO-8859-1”.
En segundo lugar esta el header XML, en caso de ser un XHTML es muy común que la primer linea del documento sea algo como “<?xml version=”1.0″ encoding=”iso-8859-1″?>”.
En tercer y ultimo lugar esta el header META, dentro del head del HTML: “content = “text/html; charset=iso-8859-1″>”
En ese caso todos dicen el mismo encoding “iso-8859-1″ (también conocido como latin-1), pero si nos imaginamos un caso donde digan algo distinto: ¿a cual debemos creerle? Es un dilema difícil, este problema en particular los web browsers lo solucionan con un algoritmo que intenta adivinar el encoding, el ejemplo de Mozilla Labs (Firefox, Camino, etc) se puede ver online aprovechando que es open source, y ese mismo algoritmo fue portado a Python por Mark Pilgrim, de quien hable en mi post pasado.
En otros usos es mas complicado aun, hay protocolos o documentos que no nos informan del encoding, y no queda claro como abrirlos. Algunos programas caen en preguntarle al usuario, claro que para alguien no muy técnico es poco claro el tener que elegir algo así, mientras que otros programas hacen fallbacks, es decir que tratan de abrir los archivos con un encoding, si ese no funciona intentan con otro, y así sucesivamente.
Otro dia seguramente haga un post con aplicando estos conceptos a programar, por ahora recomiendo la charla Unicode (pa’ empezar nomás) de Facundo Batista, y los otros textos que linkie en este articulo, al menos para Python.
Esenciales 2009
Mar 30, 2009 Articulos 11 Comments
Mark Pilgrim, autor de Dive Into Python (y preparando Dive Into Python 3) hace cada tanto una lista del software que esta usando llamada “Essentials” (la ultima es “Essentials 2008”) en la que enumera las versiones que usa, que tan contento esta y que opciones esta viendo. Me parece interesante de hacerlo porque las herramientas que cada uno utiliza son muy importantes y siempre es bueno hacer una elección pro-activa de las mismas.
Así que acá van los Esenciales 2009 de Angel Freire:
Gentoo Linux, menos contento que otros años, cada ves le encuentro mas problemas de QA, con ebuilds mal hechos y problemas entre las dependencias. Pero aun así y todo sigue siendo la distribución donde me siento mas cómodo, Exherbo es una opción que me esta interesando mucho, aunque como bien dice la página todavía le falta mucho para que sea estable en el día a día.
Vim + snippetsEmu + tabs mapeadas a los mismos keybinds que Firefox + ctags. Trato de ejercitar un poco todos los días y tengo colgado al lado de mi escritorio “The Semi-Official IBM DeveloperWorks ™ Vim Cheatsheet”.
Firefox + Mouse Gestures Redox + Web Developer + Firebug (c/YSlow) + User Agent Switcher + Modify Headers + Xmarks (ex Foxmarks, que reemplazo a Google Browser Sync bastante bien, Weave no funciono nunca). Estoy acumulando ganas para darle una buena oportunidad a vimperator.
Pidgin para casi todo lo que es mensajería, menos para IRC donde irssi dentro de un screen sigue siendo la mejor opción.
Thunderbird para el email + Tag Toolbar + XNote + Buttons! + External Editor, algún día haré un post en este blog explicando como combino todo eso. Pero últimamente me esta llamando mucho la atención usar mutt, ya uso getmail + maildrop así le puedo sacar mas provecho a vim.
gqview para ver imágenes, epdfview para pdfs y OpenOffice para la mayoría del trabajo.
Para música, sigo utilizando mpd, pero estoy empezando a encontrarle el gusto a Exaile. Y en cuanto a películas sigo con (¿el ya obsoleto?) mplayer que cumple su trabajo muy bien.
En cuanto al entorno gráfico, Fluxbox sigue siendo mi elección de WM, tuve un intento con Gnome este año pero no perduro, y aterm como terminal sigue siendo rápida y cómoda, aunque estoy pensando en empezar a usar urxvt ya que en aterm estoy encontrándome cada ves mas con caracteres en unicode que no muestra bien.
Para p2p estoy usando Transmission, el único problema que le encontré es la falta de soporte para RSS, pero con un pequeño script en Python que lea los RSS que me interesan, les aplique regex, y utilice la api de Transmission para que los baje. Soy mas que feliz con esa solución.
Deje de usar gkrellm y empecé a usar conky, no ocupa espacio en la pantalla y me resulta gráficamente mas atractivo.
Como shell zsh me sigue brindando un buen equilibrio entre interactiva/scripteable, probé escribir algunos scripts en ksh pero todavía estoy muy verde, y en la mayoría de los servidores donde tengo que trabajar me encuentro bash así que también tengo que mantener un .bashrc ajustado a mis gustos.
Voy a tratar de hacer este post todos los años para mi cumpleaños, es una fecha fácil para recordar de repasar todo esto
Ortogonalidad (o “Cada cosa en su lugar”)
Mar 25, 2009 Articulos 5 Comments
Orthogonality means that features can be used in any combination, that the combinations all make sense, and that the meaning of a given feature is consistent, regardless of the other features with which it is combined. The name is meant to draw an explicit analogy to orthogonal vectors in linear algebra: none of the vectors in an orthogonal set depends on (or can be expressed in terms of) the others, and all are needed in order to describe the vector space as a whole.
Programming Language Pragmatics, Michael Scott, Morgan Kaufmann 2000
Ortogonalidad (en ingles Orthogonality) es una filosofía del diseño de sistemas que propone dividir de forma clara las distintas funcionalidades de estos, haciendo que estas funcionalidades no se pisen entre si y que compartan la mínima cantidad de código. El objetivo subyacente es el de evitar que cambios en alguna de las secciones de un programa repercuta en otra sección.
El nombre del concepto viene de la geometría, y en el desarrollo de software se adapta su significado para formar una metáfora que resalta la independencia, tanto en código como en utilidad, de dos componentes distintos de un mismo sistema.
Eric Lippert, diseñador de lenguajes en Microsoft (de los buenos, no de los otros) hizo un post en el 2005 sobre ortogonalidad titulado “Five-Dollar Words for Programmers, Part Two: Orthogonal”, en el definió el concepto de la siguiente manera:
Imagine for instance that you were trying to describe how to get from one point in an empty room to another. A perfectly valid way to do so would be to say how many steps to go north or south, and then how many steps to go northeast or southwest. This hockey-stick navigation system is totally workable, but it feels weird because north and northeast are not orthogonal — you can’t change your position by moving northeast without also at the same time changing how far north you are. With an orthogonal system — say, the traditional north-south/east-west system — you can specify how far north to go without worrying about taking the east-west movement into account at all.
Nonorthogonal systems are hard to manipulate because it’s hard to tweak isolated parts. Consider my fish tank for example. The pH, hardness, oxidation potential, dissolved oxygen content, salinity and conductivity of the water are very nonorthogonal; changing one tends to have an effect on the others, making it sometimes tricky to get the right balance. Even things like changing the light levels can change the bacteria and algae growth cycles causing chemical changes in the water.
Con este ejemplo Lippert deja en claro lo difícil que son de mantener los sistemas no-ortogonales donde la modificacion de un punto de un programa afecta a otras partes de este sin saberlo.
Otro ejemplo claro es el que da Dave Thomas con su analogía del helicóptero:
A helicopter has four main controls: foot pedals, collective pitch lever, cyclic, and throttle. The foot pedals control the tail rotor. With the foot pedals you can counteract the torque of the main blade and, basically, point the nose where you want the helicopter to go. The collective pitch lever, which you hold in your left hand, controls the pitch on the rotor blades. This lets you control the amount of lift the blades generate. The cyclic, which you hold in your right hand, can tip one section of the blade. Move the cyclic, and the helicopter moves in the corresponding direction. The throttle sits at the end of the pitch lever.
It sounds fairly simple. You can use the pedals to point the helicopter where you want it to go. You can use the collective to move up and down. Unfortunately, though, because of the aerodynamics and gyroscopic effects of the blades, all these controls are related. So one small change, such as lowering the collective, causes the helicopter to dip and turn to one side. You have to counteract every change you make with corresponding opposing forces on the other controls. However, by doing that, you introduce more changes to the original control. So you’re constantly dancing on all the controls to keep the helicopter stable.
That’s kind of similar to code. We’ve all worked on systems where you make one small change over here, and another problem pops out over there. So you go over there and fix it, but two more problems pop out somewhere else. You constantly push them back—like that Whack-a-Mole game—and you just never finish. If the system is not orthogonal, if the pieces interact with each other more than necessary, then you’ll always get that kind of distributed bug fixing.
The funny thing about the helicopter story is that I’m not a helicopter pilot. When I wrote the helicopter story, I wanted to make sure it was accurate. I knew of a USENET group on helicopters, so I posted the helicopter story saying, “This is what I’m intending to write about how helicopter controls work. Is it correct? A helicopter pilot emailed me and said, “I read what you wrote about controlling helicopters. I didn’t sleep all night.”
El ejemplo del helicóptero es un clásico al explicar ortogonalidad, de hecho Thomas vuelve a usar esta analogía en el libro The Pragmatic Programmer (Andrew Hunt y David Thomas, Addison-Wesley 1999), creo que la encuentra bastante efectiva para explicar la idea.
¿Alguna ves les paso tener un sistema donde un cambio en una función o clase tuvo efecto en otro extremo del programa, aun cuando no parecían estar relacionados en nada? Ese es un ejemplo de sistema-no ortogonal.
El logro de los sistemas ortogonales es que eliminan efectos entre elementos de nuestros programas que no están relacionados. La separación y buena encapsulacion facilitan mucho el poder programar sobre seguro, sabiendo que los cambios hechos solamente van a afectar las partes del programa que estamos modificando.
Otro beneficio de los sistemas ortogonales es que facilitan reutilizar el código. Si el código es realmente independiente del resto del sistema y no depende de otros elementos es muy simple la tarea de aislarlo en su propio modulo y reutilizarlo en otros programas.
También los sistemas ortogonales son fáciles de tededear (Lease diseñar/programar con Test Driven Development mas conocido como TDD y pronunciado tedede): Unit test y test funcionales pueden ser aplicados a secciones mucho mas limitadas (menos variables y condiciones extraordinarias), permitiendo que estos tests sean claros y mas confiables.
Yo tuve una experiencia muy grata participando del equipo que diseño y programo el reemplazo del sistema para edición y envío de noticias por SMS donde trabajo. Primero una pequeña descripción del sistema viejo:
Era monolítico. Se basaba en dos bases de datos, una que tenia los usuarios subscriptos al servicio, y otra que tenia los horarios de envío, las noticias a enviar, las noticias enviadas, y los distintos canales en los que se organizaban esas noticias. También los programas que cargaban datos en esas bases estaban viciados de no-ortogonalidad: Compartían funciones de formas no-directas (marcaban un campo en la base de datos, o un archivo en disco, o un registro en el registro de Windows). De mas esta decir que el sistema era inmantenible, estuvo funcionando mal durante varios años antes de que se planteara reemplazarlo. Y aun así cuando se lo hizo fue difícil hacer un relevamiento de que hacia exactamente para poder empezar a hacer un nuevo sistema.
Para el sistema nuevo nos pusimos como objetivo que sea ortogonal. En ese momento no conocíamos el concepto por su nombre, llamábamos al diseño “modular”, pero la definición de ese objetivo coincidía con la de ortogonal. Separamos las distintas funcionalidades del sistema en partes bien definidas, que de hecho eran programas separados y tenían su propia base de datos, código, y en algunos casos hasta lenguajes de programación distintos. El resultado final fueron varios sistemas: Uno mantiene los subscriptos a los servicios. Otro tiene un editor de contenidos web. Un tercero mantiene los horarios de envío. Y finalmente un “enviador” que consulta esas tres fuentes de datos y envía las noticias en el momento correcto a los usuarios que así lo desean.
No existe punto de comparación entre la complejidad de los dos sistemas. El viejo, no ortogonal, tenia muchas mas lineas de código y llevaba mas tiempo mantener a los programadores a cargo. Su diseño no-ortogonal hacia confuso cuando algo fallaba: No se sabia por donde empezar a buscar. El nuevo funciona en horario, es mucho mas claro que falla cuando hay algún error y requiere de muchas menos horas-hombre para mantenerlo ¡y extenderlo!. Aparte, como beneficio del diseño ortogonal, los nuevos sistemas se utilizan para otras tareas que la de envío de SMS; como la base de datos de subscriptores que ahora tiene usuarios de otros sistemas.
La ortogonalidad también tiene sus críticos, Ian Bicking en su articulo “Orthogonality is Pretentious” propone que el diseño de lenguajes de programación ortogonales puede resultar en varios problemas, como Ravioli Code donde terminan existiendo miles de pequeñas funciones no relacionadas entre si (¿Alguien dijo PHP?).
Finalmente esta ha sido llamada una de las “Five Dollar Programming words”, es decir uno de esos conceptos que al tener un nombre se vuelve mas fácil el ponerlos como un objetivo.
Sobre editar…
Mar 22, 2009 Articulos 9 Comments
Developers still spend a lot of time with plain text. No matter how many wizards and other sorcerers we develop most coding is still in plain text. Most of the information you keep should also reside in plain text because you never know if the tool you are using will be around in five years. It’s a good bet that you’ll be able to read plain ASCII (and probably Unicode) for the next century or so.
The Productive Programmer, Neal Ford y David (FRW) Bock, O’Reilly 2008
El editor de texto es quizás la mas preciada de las herramientas para un programador. El código de cada uno de los programas y scripts que escribimos esta en texto plano, y como bien dice la cita anterior incluso los datos que manipulan esos programas están de alguna forma en texto plano también.
¿Pero le damos la importancia que merece? Como programador, en un día normal, si excluyo las reuniones y conferencias telefónicas, el resto del tiempo, estoy frente a un editor de texto o un navegador web, rara ves me enfrento con herramientas que no reciban datos a través del teclado. Esto da la pauta de lo mucho mejor que se puede programar si se utiliza bien el editor de texto. Hasta llegue a leer en algunos artículos de distintos blogs sobre que al entrevistar gente para puestos de IT una de las preguntas que no puede faltar es “¿Que editor de texto usa?” (Por cierto, las respuestas “validas” que daban los autores eran Emacs, Vim y Textpad).
Bram Moolenaar, autor de vim en su charla de Google Edu sobre como editar texto de forma efectiva distingue tres pasos para ser mas efectivo:
- detect inefficiency
- find quicker way
- make it a habit
Son tres pasos muy simples, que imponen una curva de aprendizaje bastante alta, dado que al principio vamos a encontrar muchas insuficiencias en la forma que editamos texto, y de hecho hasta tengamos que cambiar el programa que usamos para encontrar mejores formas de hacer las tareas diarias.
El mismo Moolenar tiene un muy buen texto “Seven habits of effective text editing” en el que distingue varios puntos en los que uno tiene que poder contar con su editor de texto para ser efectivo:
- Move around quickly: Navegar el texto de forma cómoda, sin depender del mouse o teclas que se ubican lejos de la posición normal de las manos en el teclado (como pageup/down y las “flechitas”).
- Don’t type it twice: Poder tener varios textos copiados en varios clipboards y elegir cual pegar, facilitar elegir donde va a ser pegado el texto, permitirme hacer tareas como reemplazar X palabra en el texto que pegue, etc.
- Fix it when it’s wrong: “typos” es uno de los tipos de bugs mas faciles de cometer y donde el editor de texto te puede dar mas ayuda.
- A file seldom comes alone: ¿Que programa mas o menos complejo ocupa un solo archivo de codigo fuente? La habilidad de editar mas de un archivo a la ves es obligatoria.
- Let’s work together: El editor en si es solo una parte de todo el arsenal de herramientas para modificar texto, ¿Para que hacer que el editor ordene alfabéticamente algo cuando ya tengo sort? ¿Para que hacer una compleja función de buscar en todos los archivos del directorio cuando ya tengo grep?
- Text is structured: Que el editor nos ayude a mantener la estructura del texto/código, como la identacion en Python (si usas espacios que te autoidente con espacios, si usas tabs con tabs), que te avise cuando no cerraste una llave en C, o si tenes un end sin begin en un bloque de Ruby).
- Make it a habit: Encontrás la mejor forma de hacer una tarea, sabes que te ahorraste 10 o mas pasos que hubieras tenido que hacer para obtener el mismo resultado de otra manera: ¿Vas a tirar ese conocimiento a la basura? Editar texto es algo que aprendes y mejoras todos los dias y no tenes por que perder ese conocimiento cuando pases a trabajar en otro lenguaje o en otro sistema operativo, utiliza un editor que te permita abstraerte de esa particularidad y lo tengas disponible en cualquier lado.
En su libro “The Pragmatic Programmer” (Addison-Wesley 2000) Andrew Hunt y David Thomas distinguen tres grandes puntos al momento de elegir el editor: Configurable, Programable y Extensible.
Configurable: hace referencia a la capacidad de editar cosas como los colores, tipografía, y apariencia en general. Suena trivial pero como aclare antes la mayor parte del tiempo que uno pasa frente a la computadora programando lo hace en frente del editor de textos, es muy importante que luzca amigable, cómodo, y nos permita resaltar las cosas que nos importan.
Hay un viejo tip entre programadores que dice que cosas como los “magics numbers” (números dentro del código que aparezcan directamente en las funciones y no declarados en una variable o constante cuyo nombre nos ayude a identificar la razón de la misma) deben resaltarse con un color chocante, que salga del esquema de colores al que estamos acostumbrados hasta si se quiere decir así “se vea feo”, para que tratemos de tener la menor cantidad (o si es posible ninguno) de ellos.
Programable: Muchas tareas que hacemos cuando escribimos texto responden a un patrón, y la mayoría de esos patrones podemos programarlos para que el editor de texto lo haga por nosotros. Extender el editor con un lenguaje de scripting como Python o Perl puede resultar muy útil cuando trabajamos, a veces invertir 10′ en una pequeña extensión nos ahorra horas. Hay editores que tienen su propio lenguaje de scripting, otros que utilizan lenguajes conocidos (Emacs con Lisp), y otros que brindan ambas opciones (Vim tiene bindings para Python, Perl y Ruby, y aparte tiene su propio “lenguaje”).
Extensible: Aparte de la configuración y las opciones, esta el hecho de poder extenderlo mas allá del uso que le damos hoy, en este punto es difícil distinguir una buena herramienta que este preparada “para lo desconocido”, pero nos ayuda mirar al pasado y ver que editores como vim, emacs, y otros han sido usados para APL, C, Pascal, y después se adaptaron a lenguajes como Ruby y Perl sin mayores cambios.
¿Como elegir un editor? Joel Spolsky tiene el “The Joel Test” donde habla de 12 pasos a seguir para tener mejor codigo y en el punto 9 dice “Las mejores herramientas que el dinero pueda comprar”, y si bien coincido con la idea que el gasto en herramientas y programas para que los equipos de programadores trabajen mejor y mas cómodos se traduce en mejor código, en el caso del editor de texto encontré, en mi experiencia, que los mejores son gratuitos.
Las funcionalidades de editores como Vim y Emacs no estan en Ultraedit, Textpad o BBEdit, existen varios comparaciones de editores, y como la mayoría de las comparaciones suelen estar viciadas por quien hizo la comparación, así que un buen criterio el que puede dar una fuente neutral de información como Wikipedia.
Les dejo a ustedes la tarea de elegir uno, pero el desafió es hacerlo conscientemente, no dejar que el entorno en el que trabajan o el lenguaje de programación que usan elija las herramientas con las que tienen que lidiar a diario. Me gustaría leer sobre su elección en los comentarios.


