<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programación &#8211; Blog de Javier Smaldone</title>
	<atom:link href="https://blog.smaldone.com.ar/category/software/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.smaldone.com.ar</link>
	<description>Todos los días se aprende algo viejo</description>
	<lastBuildDate>Wed, 11 Jan 2017 13:27:45 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<site xmlns="com-wordpress:feed-additions:1">4035488</site>	<item>
		<title>Los garantes del voto electrónico en la Provincia de Córdoba</title>
		<link>https://blog.smaldone.com.ar/2017/01/10/los-garantes-del-voto-electronico-en-la-provincia-de-cordoba/</link>
					<comments>https://blog.smaldone.com.ar/2017/01/10/los-garantes-del-voto-electronico-en-la-provincia-de-cordoba/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Wed, 11 Jan 2017 01:25:59 +0000</pubDate>
				<category><![CDATA[Boleta única electrónica]]></category>
		<category><![CDATA[Computación]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Voto electrónico]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=3100</guid>

					<description><![CDATA[En la Provincia de Córdoba tenemos el triste privilegio, desde hace casi 30 años, de contar con un Consejo Profesional de Ciencias Informáticas de matriculación obligatoria (el CPCIPC). En virtud de una ley que supieron lograr en el año 1987, regulan el ejercicio de «la profesión informática» (como si tal cosa pudiera siquiera definirse). Sí, &#8230; <a href="https://blog.smaldone.com.ar/2017/01/10/los-garantes-del-voto-electronico-en-la-provincia-de-cordoba/" class="more-link">Sigue leyendo <span class="screen-reader-text">Los garantes del voto electrónico en la Provincia de Córdoba</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>En la Provincia de Córdoba tenemos el triste privilegio, desde hace casi 30 años, de contar con un <a href="http://www.cpcipc.org.ar/"><strong>Consejo Profesional de Ciencias Informáticas</strong></a> de matriculación obligatoria (el <strong>CPCIPC</strong>). En virtud de una ley que supieron lograr en el año 1987, regulan el ejercicio de <em>«la profesión informática</em>» (como si tal cosa pudiera siquiera definirse). Sí, en Córdoba para desarrollar profesionalmente cualquier actividad relacionada con la computación hay que tener un <em>«título habilitante»</em> y pagar la matrícula del Consejo Profesional.</p>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/votarcpcipc.jpg" alt="CPCIPC y Vot.Ar" /></div>
<p>Hace unos días, y <a href="https://blog.smaldone.com.ar/2016/12/22/no-al-voto-electronico-en-la-provincia-de-cordoba/">desoyendo la voz de especialistas</a>, la Legislatura de Córdoba <a href="https://blog.smaldone.com.ar/2016/12/15/el-retroceso-electoral-de-cordoba/">aprobó una ley</a> que ordena el uso de <strong>voto electrónico</strong> en las elecciones provinciales. Amén de implementar un sistema más que cuestionado, la norma pone en manos del <strong>CPCIPC</strong> la fiscalización (limitando la posibilidad de ser fiscal informático partidario a quienes estén matriculados) y seguramente sea también el <strong>CPCIPC</strong> quien asuma el rol principal en la realización de las auditorías del sistema informático a utilizar.</p>
<p>Lo que sigue es un ejemplo más del lamentable nivel de los informáticos nucleados en el <strong>CPCIPC</strong>.</p>
<p><span id="more-3100"></span></p>
<h3>El sitio web del CPCIPC</h3>
<p>El programador <strong>Federico Heinz</strong> (que hace unos días publicó una <a href="http://www.lavoz.com.ar/numero-cero/debate-cordoba-lejos-de-la-libertad-informatica">excelente nota sobre el tema</a>) hizo notar en Twitter que el sitio del <strong>CPCIPC</strong> tenía un ridículo sistema de autenticación para el acceso de los matriculados:</p>
<blockquote class="twitter-tweet" data-lang="es">
<p lang="es" dir="ltr">En <a href="https://t.co/i4jSOkpZqH">https://t.co/i4jSOkpZqH</a> el login requiere dos datos: # matrícula y DNI. Adiviná que hay en <a href="https://t.co/eeyuWAuVp6">https://t.co/eeyuWAuVp6</a>? <a href="https://twitter.com/hashtag/NoDanMasDeIn%C3%BAtiles?src=hash">#NoDanMasDeInútiles</a></p>
<p>&mdash; Fede Heinz (@fheinz) <a href="https://twitter.com/fheinz/status/818592510654038016">9 de enero de 2017</a></p></blockquote>
<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>No pasó mucho tiempo hasta que algunos tuiteros comenzaron a ingresar al sistema usando los números de matrícula de las autoridades del <strong>CPCIPC</strong> (publicados en el mismo sitio) y su DNI (dato fácilmente obtenible si se tiene el nombre completo de la persona).</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/fheinz">@fheinz</a> <a href="https://twitter.com/mis2centavos">@mis2centavos</a> Ya estoy logueado como el presidente. Me estoy tentando de hacer alguna maldad, muejejeje <a href="https://t.co/WdqhBvVqdt">pic.twitter.com/WdqhBvVqdt</a></p>
<p>&mdash; Elvira de Musicardi (@pitersoap) <a href="https://twitter.com/pitersoap/status/818617074570371073">10 de enero de 2017</a></p></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/pitersoap">@pitersoap</a> <a href="https://twitter.com/mis2centavos">@mis2centavos</a> POR FAVOR NO ENTREN. La seguridad es patética, pero no es razón para violarla.</p>
<p>&mdash; Fede Heinz (@fheinz) <a href="https://twitter.com/fheinz/status/818675335948603392">10 de enero 2017</a></p></blockquote>
<p>De nada sirvió el pedido de <strong>Federico Heinz</strong>, para algunos la tentación fue muy grande:</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/mis2centavos">@mis2centavos</a> jajajaja quien fue!? :P <a href="https://t.co/HaZDAe4vVv">pic.twitter.com/HaZDAe4vVv</a></p>
<p>&mdash; Maxi Biscardi (@MaxiBiscardi) <a href="https://twitter.com/MaxiBiscardi/status/818648103763013633">10 de enero de 2017</a></p></blockquote>
<p>Alguien más encontró un error todavía más grosero: en el sitio del <strong>CPCIPC</strong> había un script que permitía descargar cualquier archivo del sistema que fuese accesible por el servidor web:</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/fheinz">@fheinz</a> <a href="https://t.co/TlTh0J7ben">https://t.co/TlTh0J7ben</a> y acá te dejan descargarte lo que quieras.</p>
<p>&mdash; Gonza Cabrera (@_gonzacabrera) <a href="https://twitter.com/_gonzacabrera/status/818665665909374978">10 de enero de 2017</a></p></blockquote>
<p>Este es el código del script «<em>downloader.php</em>» que se encontraba en el servidor:</p>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/downloader-mini.jpg" alt="downloader.php" /><br /><a href="/files/cpcipc/downloader.jpg" target="_blank"><em>(Clic para ampliar)</em></a></div>
<p>¿Cómo es que los sesudos profesionales del <strong>CPCIPC</strong> cometieron este error digno de un principiante? Fácil: <a href="http://php.net/manual/en/function.readfile.php">copiando y pegando código</a> de la documentación de <strong>PHP</strong>:</p>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/php.png" alt="Ejemplo de PHP" /></div>
<p>Pero evidentemente, los errores en el sitio del <strong>CPCIPC</strong> no se agotaban. Unos minutos después, ya alguien había <a href="http://web.archive.org/web/20170110051841/http://www.cpcipc.org.ar/content/comisi%C3%B3n-directiva">modificado el contenido</a> (reemplazando las fotos de las autoridades por la del dueño de la empresa MSA <strong>Sergio Angelini</strong>, vendedora de <strong>voto electrónico</strong>):</p>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/mis2centavos">@mis2centavos</a> Bue, se fueron al carajo.</p>
<p>Este es el actual estado de <a href="https://t.co/hHjsear4L9">https://t.co/hHjsear4L9</a> <a href="https://t.co/G7OCSFN4FZ">pic.twitter.com/G7OCSFN4FZ</a></p>
<p>&mdash; Luciano Bello (@microluciano) <a href="https://twitter.com/microluciano/status/818685105803788290">10 de enero de 2017</a></p></blockquote>
<p>Más tarde, el sitio del <strong>CPCIPC</strong> ya estaba <a href="http://web.archive.org/web/20170110053942/http://www.cpcipc.org.ar/">completamente «<em>defaceado</em>«</a>:</p>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/deface.png" alt="Disclaimer en el sitio" /></div>
<p>Hoy por la mañana, parece que ya estaban solucionando los problemas (o al menos algunos de ellos):</p>
<blockquote class="twitter-tweet" data-lang="es">
<p lang="es" dir="ltr">Lo instalamos entre todos? <a href="https://t.co/CZXHyB9UUy">pic.twitter.com/CZXHyB9UUy</a></p>
<p>&mdash; mdl (@MadlySeason) <a href="https://twitter.com/MadlySeason/status/818793630638993409">10 de enero de 2017</a></p></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr">Solución de los guardianes monopólicos de la seguridad informática: eliminar la posibilidad de que los usuarios/colegiados se logueen <a href="https://t.co/5bjVKSH850">pic.twitter.com/5bjVKSH850</a></p>
<p>&mdash; Delia Ferreira (@DeliaFerreira) <a href="https://twitter.com/DeliaFerreira/status/818892432192471041">10 de enero de 2017</a></p></blockquote>
<p>¿Algo más? Sí. Como era de esperar, y para completar la vergüenza, el servidor del <strong>CPCIPC</strong> ya había sido crackeado con anterioridad, por alguien que lo infectó con software que lo convierte en parte de un red de máquinas esclavas (<a href="https://es.wikipedia.org/wiki/Botnet">botnet</a>):</p>
<blockquote class="twitter-tweet" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/cpcipc">@cpcipc</a> buenas muchachos, se les metió una porquería en el webserver vaya uno a saber hace cuanto <a href="https://t.co/JSPG4br5LY">https://t.co/JSPG4br5LY</a></p>
<p>/lib/libudev.so</p>
<p>&mdash; mega (@iglosiggio) <a href="https://twitter.com/iglosiggio/status/818873762858889224">10 de enero de 2017</a></p></blockquote>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/botnet.png" alt="Infección en el servidor del CPCIPC" /></div>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="es">
<p lang="es" dir="ltr"><a href="https://twitter.com/cpcipc">@cpcipc</a> de paso miren el crontab</p>
<p>&mdash; mega (@iglosiggio) <a href="https://twitter.com/iglosiggio/status/818873799118618624">10 de enero de 2017</a></p></blockquote>
<p>(Si, el servidor del <strong>CPCIPC</strong> podría ser usado por terceros para realizar <a href="https://es.wikipedia.org/wiki/Ataque_de_denegaci%C3%B3n_de_servicio">ataques distribuidos de denegación de servicio</a>. En definitiva, quienes lo descubrieron les hicieron un favor).</p>
<h3>Conclusión</h3>
<p>Esta es la gente que <a href="https://www.facebook.com/javier.smaldone/posts/873266052810774?comment_id=873871659416880">amenaza con denunciarme por <strong>«ejercicio ilegal de la informática»</strong></a> por <a href="https://blog.smaldone.com.ar/2016/08/06/criticas-a-la-boleta-unica-electronica-en-la-camara-de-diputados/">presentarme en el Congreso de la Nación</a> como programador y especialista en informática:</p>
<div class="centerpic"><img decoding="async" src="/files/cpcipc/denuncia.png" alt="Amenaza de denuncia" /></div>
<p>Es la gente que <em>«tutela el ejercicio de la profesión»</em> y realiza inspecciones en la <strong>Provincia de Córdoba</strong> para determinar quién puede trabajar en informática y quién no:</p>
<div class="centerpic"><iframe width="600" height="338" src="https://www.youtube.com/embed/1T_VwAT1ztY?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe></div>
<p>También es la gente que se dedica a promocionar el sistema de <strong>voto electrónico</strong> de la empresa <strong>MSA</strong> y se ofrece a auditarlo en las elecciones:</p>
<div class="centerpic"><iframe width="600" height="338" src="https://www.youtube.com/embed/UwUFjhEj1VU?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe></div>
<p>Y es la gente que, gracias a la nueva ley provincial, tendrá el <strong>monopolio de la fiscalización electrónica</strong> en las votaciones por venir.</p>
<p>Gente que no puede implementar razonablemente un sistema de usuario y contraseña para autenticar a sus matriculados. Gente que no puede escribir una aplicación siguiendo los lineamientos básicos de seguridad. Gente que no puede ni siquiera mantener un servidor web sin transformarse en el <strong>hazmerreír de los programadores del resto del país</strong>. Ese es el <strong>Consejo Profesional de Ciencias</strong> (o «<strong>Carencias</strong>«) <strong>Informáticas de la Provincia de Córdoba</strong>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2017/01/10/los-garantes-del-voto-electronico-en-la-provincia-de-cordoba/feed/</wfw:commentRss>
			<slash:comments>24</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3100</post-id>	</item>
		<item>
		<title>Los Riesgos de las Universidades-Java</title>
		<link>https://blog.smaldone.com.ar/2010/06/01/los-riesgos-de-las-universidades-java/</link>
					<comments>https://blog.smaldone.com.ar/2010/06/01/los-riesgos-de-las-universidades-java/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Tue, 01 Jun 2010 20:53:13 +0000</pubDate>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Educación]]></category>
		<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=432</guid>

					<description><![CDATA[Este artículo de Joel Spolsky es, desde hace tiempo, uno de mis favoritos. Publicado originalmente en el año 2005, el paso del tiempo sólo lo ha hecho ganar rigor y actualidad. Spolsky alerta sobre la creciente tendencia de muchas universidades a sobre-simplificar la currícula de las carreras de Ciencias de la Computación (con Java como &#8230; <a href="https://blog.smaldone.com.ar/2010/06/01/los-riesgos-de-las-universidades-java/" class="more-link">Sigue leyendo <span class="screen-reader-text">Los Riesgos de las Universidades-Java</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Este artículo de <a href="http://en.wikipedia.org/wiki/Joel_Spolsky">Joel Spolsky</a> es, desde hace tiempo, uno de mis favoritos. <a href="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html">Publicado originalmente</a> en el año 2005, el paso del tiempo sólo lo ha hecho ganar rigor y actualidad.</p>
<p><strong>Spolsky</strong> alerta sobre la creciente tendencia de muchas universidades a sobre-simplificar la currícula de las carreras de Ciencias de la Computación (con <strong>Java</strong> como «lenguaje insignia»), con el único objetivo de producir mayor cantidad de egresados y en menos tiempo. La consecuencia es directa: cada vez más abundan programadores que poco entienden de conceptos de programación (corrección, recursión, complejidad, paralelismo, entre tantos otros) y para los cuales los mecanismos «internos» de los sistemas informáticos (gestión de memoria, interacción con el sistema operativo, comunicación entre procesos, etc.) son completamente esotéricos.</p>
<p><span id="more-432"></span></p>
<p>El principal impulsor de este embrutecimiento es cierto sector de la llamada «Industria del Software» que requiere de mano de obra barata y de pobre formación, y empuja a las instituciones educativas a proveerles «recursos» tan rápido y en tanta cantidad como sea posible (ni qué decir de las instituciones educativas que ceden a esta presión).</p>
<p>Nadie está en contra de hacer la tarea del programador más simple, ni mucho menos de la evolución de los lenguajes y las metodologías de desarrollo de software. Lo que se reprocha aquí es la negación de la realidad como forma de evasión. Esto es: la necesidad de dotar a los programadores de ciertos conceptos, aún cuando esto provoque la deserción de quienes no puedan llegar a dominarlos (y mal que le pese al referido sector de la «Industria»).</p>
<h3>Los Riesgos de las Universidades-Java</h3>
<p><strong>por Joel Spolsky</strong><br />
Jueves 29 de diciembre de 2005</p>
<p>Chicos perezosos.</p>
<p>¿Qué pasó con el trabajo duro?</p>
<p>Un seguro indicio de mi decadencia hacia la senilidad son mis continuas quejas y lamentos sobre «los chicos de hoy», y cómo ya no quieren o no pueden hacer cosas difíciles.</p>
<p>Cuando yo era un muchacho, aprendí a programar con tarjetas perforadas. En esos tiempos si cometías un error, no tenías ninguna de esas modernas funciones como la tecla «<em>backspace</em>» para corregirlo. Tenias que tirar la tarjeta y empezar todo de nuevo.</p>
<p>Cuando empecé a entrevistar programadores en 1991, les dejaba usar generalmente cualquier lenguaje que quisieran para resolver los problemas de programación que les planteaba. El 99% de las veces, ellos elegían C.</p>
<p>Ahora ellos tienden a elegir Java.</p>
<p>No me malinterpreten: no hay nada malo con Java como lenguaje de implementación.</p>
<p>Un momento, quiero rectificar eso último. No digo, <em>en este artículo en particular</em>, que haya algo de malo con Java como lenguaje de implementación. Hay un montón de cosas mal con Java, pero tendrán que esperar hasta otro artículo.</p>
<p>En cambio, lo que quiero decir es que Java no es, generalmente, un lenguaje de programación lo suficientemente difícil para que pueda ser usado para distinguir entre excelentes programadores y programadores mediocres. Puede ser un buen lenguaje para trabajar, pero ese no es el tema de hoy. Puedo ir incluso mas allá y decir que el hecho de que Java no sea lo suficientemente difícil es una característica, no un bug, pero que tiene ese problema.</p>
<p>Si puedo ser atrevido, diría que en mi humilde experiencia han sido dos las cosas tradicionalmente enseñadas en las universidades como parte de la carrera de Ciencias de la Computación (CS) las que mucha gente nunca llega realmente a comprender: punteros y recursión.</p>
<p>En aquellos tiempos lo normal era empezar la universidad con un curso de estructuras de datos, con listas enlazadas, tablas hash y, por qué no, con un uso intensivo de punteros. Esos cursos eran frecuentemente usados como filtros: eran tan difíciles que cualquiera que no pudiera soportar el desafío mental de un grado en CS se daría por vencido, lo que era bueno, porque si piensas que los punteros son difíciles, espera hasta intentar probar cosas en teoría de punto fijo.</p>
<p>Todos esos chicos que lo habían hecho muy bien en la secundaria escribiendo juegos de «pong» en BASIC para su Apple II, iban a la universidad, tomaban el curso CompSci 101, sobre estructuras de datos, y cuando llegaban al asunto de los punteros, sus cerebros estallaban completamente; y lo próximo de lo que tenías noticias es que estaban especializándose en Ciencias Políticas, porque la escuela de leyes parecía ser una mejor idea. He visto todo tipo de de índices de deserción en CS y usualmente están entre el 40% y  el 70%. Las universidades tienden a ver esto como un derroche; yo creo que es sólo la poda necesaria de gente que no va a ser feliz o exitosa en una carrera de programación.</p>
<p>El otro curso difícil para muchos jóvenes estudiantes de CS era el curso donde aprendías programación funcional, incluyendo programación recursiva. MIT puso una barrera muy alta en esos cursos, creando un <a href="http://sicp.csail.mit.edu/Fall-2005/">curso</a> obligatorio (6.001) y un libro de texto (<a href="http://mitpress.mit.edu/sicp/full-text/book/book.html">Estructura e Interpretación de Programas de Computadora</a> de Abelson y Sussman, el cual era usado en docenas o quizás cientos de carreras de CS prestigiosas como el estándar de facto para la introducción a las Ciencias de la Computación. (Puedes, y deberías echarle una ojeada a la antigua versión de las clases <a href="http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/">en línea</a>).</p>
<p>La dificultad de esos cursos es asombrosa. En la primera clase has aprendido casi todo Scheme, y ya has sido introducido a la función de punto fijo que toma otra función como parámetro. Cuando me esforzaba en pasar un curso similar, CSE121 en Penn, observaba cómo muchos sino la mayoría de los estudiantes simplemente no lo lograba. La materia era muy difícil. Inclusive escribí un largo email de lloriqueando a mi profesor diciendo que “simplemente no era justo”. Alguien en Penn debe haberme escuchado (o a alguno de los otros llorones), porque ese curso se dicta ahora con Java.</p>
<p>Desearía que no hubiesen escuchado.</p>
<p>Aquí radica el quid del debate. Años de lloriqueo de estudiantes perezosos como yo, combinados con quejas de la industria acerca de cuan pocos graduados en CS salen de las universidades americanas, han pagado su precio, y en la ultima década un gran numero de otrora perfectamente buenas universidades se han vuelto 100% Java. Esta de moda, a los reclutadores que usan “grep» parece gustarles, y, lo mejor de todo, no hay nada lo suficientemente difícil en Java como para filtrar aquellos programadores sin la parte del cerebro que entiende punteros y recursión. Así es que la deserción es menor, y los departamentos de ciencias de la computación tienen mas alumnos y mayores presupuestos y todo está bien.</p>
<p>Los afortunados chicos de esas Universidades-Java nunca van a toparse con raros fallos de segmentación tratando de implementar tablas hash basadas en punteros. Nunca se van a volver locos tratando de empaquetar cosas en bits. Nunca tendrán que ocupar sus cabezas en cómo en un lenguaje puramente funcional, el valor de una variable nunca cambia, y aun así, ¡cambia todo el tiempo! ¡Una paradoja!</p>
<p>Ellos no necesitan esa parte del cerebro para obtener un 4 en la materia.</p>
<p>¿Soy sólo uno de esos viejos cascarrabias anticuados, vanagloriándose acerca de cuán duro era sobrevivir a todas esas dificultades?</p>
<p>Rayos, en 1900, el Latín y el Griego eran asignaturas requeridas en la universidad, no porque sirvieran de algún propósito, sino porque de alguna manera eran considerados un requisito obvio de la gente educada. De cierta manera mi argumento no es diferente del argumento expuesto por la gente pro-Latín: “[El Latín] entrena tu mente. Entrena tu memoria. Desembrollar una sentencia en Latín es un excelente ejercicio del pensamiento, un verdadero acertijo intelectual y una buena introducción al pensamiento lógico”, <a href-"http://www.promotelatin.org/whylatin.htm">escribe</a> Scout Barrer. Pero ya no puedo encontrar una sola universidad que requiera Latín. ¿Son los punteros y la recursión el Latín y el Griego de las ciencias de la computación?</p>
<p>Ahora, admito que programar con punteros no es necesario en el 90% del código escrito en la actualidad, y de hecho es totalmente peligroso en el código de producción. OK. Está bien. Y que la programación funcional no es muy empleada en la práctica. De acuerdo.</p>
<p>Pero todavía sigue siendo importante para algunos de las tareas más excitantes en programación. Sin punteros, por ejemplo, nunca serías capaz de trabajar en el Kernel de Linux. No puedes entender una sola línea del código de Linux, o de hecho, de cualquier sistema operativo, sin realmente entender punteros.</p>
<p>Sin entender programación funcional, no podrás inventar <a href="http://labs.google.com/papers/mapreduce.html">MapReduce</a>, el algoritmo que hace Google tan masivamente escalable. Los términos Map y Reduce vienen de Lisp y la programación funcional. MapReduce es, en retrospectiva, obvio para cualquiera que recuerde de su clase equivalente a 6.001 que los programas puramente funcionales no tienen efectos colaterales y por ende son trivialmente paralelizables. El simple hecho que Google inventara MapReduce, y no Microsoft, dice algo del por qué Microsoft está aun jugando a lograr que funcionen algunas características básicas de búsqueda, mientras Google se ha movido ya al siguiente problema: construir <a href="http://en.wikipedia.org/wiki/Skynet">Skynet</a>^H^H^H^H^H^H, la mayor <a href="http://www.pbs.org/cringely/pulpit/pulpit20051117.html">supercomputadora</a> masivamente paralela del mundo. Simplemente no creo que Microsoft entienda completamente cuan retrasados están en ese campo.</p>
<p>Pero mas allá de la importancia a simple vista de los punteros y la recursión, su valor real radica en que construir grandes sistemas requiere del tipo de flexibilidad mental que adquieres aprendiéndolos, y de la actitud mental que necesitas para no huir de los cursos en donde son enseñados. Punteros y recursión requieren cierta habilidad para razonar, para pensar en abstracciones, y más importante, para ver un problema en diversos niveles de abstracción simultáneamente. Por lo tanto, la habilidad para entender punteros y recursión esta directamente correlacionada con la habilidad de ser un gran programador.</p>
<p>No hay nada en grado académico 100% Java que realmente descarte a los estudiantes que carecen de la agilidad mental para tratar con esos conceptos. Como empleador, he visto que las Universidades 100% Java han empezado a producir en serie una buena cantidad de graduados quienes simplemente no son lo suficientemente listos para trabajar como programadores en nada mas sofisticado que «Sólo Otra Aplicación Contable en Java», aunque se las han arreglado para colarse a través de la (ahora simplificada) carrera. Esos estudiantes nunca sobrevivirían al 6.001 del MIT o al CS 323 en Yale y, francamente, esa es una razón por la cual, como empleador, un título en CS del MIT o Yale tiene más peso que uno de Duke, que recientemente se hizo 100%-Java, o de Penn, donde remplazaron Scheme y ML por Java tratando de enseñar la materia que casi nos mata a mis compañeros y a mi, CSE121. No es que no quiera contratar chicos listos de Duke o Penn, lo hago, es sólo que es mucho más difícil para mí darme cuenta de cuáles son. Yo estaba acostumbrado a decir que los chicos listos eran aquellos que podían desmenuzar un algoritmo recursivo en segundos, o implementar funciones de manipulación de listas enlazadas usando punteros tan rápido como podían escribir en la pizarra. Pero con graduado sde Universidades-Java, no puedo saber si padecen esos problemas a causa de haber sido mal educados o si los padecen porque realmente carecen de esa parte del cerebro que van a necesitar para ser buenos programadores en el trabajo. Paul Graham los llama «<a href="http://www.paulgraham.com/avg.html"><em>Blub Programmers</em></a>«.</p>
<p>Ya es bastante malo que las Universidades-Java fallen en filtrar los chicos que nunca van a ser buenos programadores, algo que las universidades podrían justificablemente decir que no es su problema. Después de todo es la industria, o al menos los reclutadores-que-usan-grep, quien está pidiendo a gritos que se enseñe Java.</p>
<p>Pero las Universidades-Java fallan también en entrenar las mente de los chicos para ser hábiles, ágiles y lo suficientemente flexibles para lograr buen diseño de software (y no me refiero al “diseño” OO, donde gastas incontables horas acomodando tu jerarquía de objetos, o preocupándote de «problemas» superfluos como “tiene-un” vs. “es-un”). Necesitas entrenamiento para pensar en las cosas a varios niveles de abstracción simultáneamente, y ese tipo de pensamiento es exactamente lo que necesitas para diseñar excelentes arquitecturas de software.</p>
<p>Puedes estar preguntándote si la enseñanza de programación orientada a objetos (OOP) es un buen sustituto de los punteros y la recursión para el filtrado. La respuesta rápida: no. Sin debatir acerca de los meritos de la OOP, simplemente no es lo suficientemente difícil para filtrar a los programadores mediocres. OOP en las universidades consiste básicamente en memorizar un puñado de términos de vocabulario como “encapsulacion” y “herencia” y tomar exámenes del tipo «multiple-choice» acerca de las diferencias entre polimorfismo y sobrecarga. No más difícil que memorizar fechas destacadas y nombres en una clase de historia, la OOP tiene desafíos mentales inadecuados para espantar a los estudiantes de primer año. Cuando te enfrentas con un problema de OOP, <em>tu programa aun funciona</em>, sólo que es algo difícil de mantener. Supuestamente. Pero cuando te enfrentas a un problema con punteros, tu programa produce línea <strong>Fallo de segmentación</strong> y no tienes ni la menor idea de lo que está pasando, hasta que te paras, tomas una fuerte bocanada de aire y tratas de forzar tu mente a trabajar en dos diferentes niveles de abstracción simultáneamente.</p>
<p>Los reclutadores-que-usan-grep, de hecho, son ridiculizados aquí, y por un buen motivo. Nunca he conocido alguien que pueda usar Scheme, Haskell y punteros en C, que no pueda entender Java en dos días, y crear mejor código en Java que gente con cinco años de experiencia en Java. Pero trata de explicar eso al zombie de Recursos Humanos.</p>
<p>¿Pero que hay de la misión del compromiso con las CS de las facultades de CS? ¡Ellas no son escuelas vocacionales! No debería ser su trabajo entrenar gente para trabajar en la industria. Eso queda para los terciarios y los programas de capacitación del gobierno para trabajadores desplazados, dirán. Ellas se suponen que están para dar a los estudiantes las herramientas fundamentales para vivir sus vidas, no para prepararlos para sus primeras semanas de trabajo. ¿No es cierto?</p>
<p>Aun así, las CS son demostraciones (recursión), algoritmos (recursión), lenguajes (cálculo lambda), sistemas operativos (punteros), compiladores (cálculo lambda), y entonces la conclusión es que la Universidad-Java que no enseña C y no enseña Scheme, tampoco está enseñando realmente ciencias de la computación. Tan inútil como el concepto de <a href="http://en.wikipedia.org/wiki/Currying"> currificación de funciones</a> puede serle al mundo real, es un obvio prerrequisito para un graduado en CS. No puedo entender por qué los profesores en las comisiones curriculares de las facultades de CS han permitido que sus programas sean embrutecidos a tal punto que  no sólo no pueden producir <em>programadores operativos</em>, sino que ya ni siquiera pueden producir graduados en CS que puedan obtener PhDs y puedan competir por sus puestos de trabajo. Oh, esperen. No importa. Quizás entienda.</p>
<p>Si volvemos en el tiempo y analizamos las discusiones que tomaron lugar en el mundo académico durante el “Gran Levantamiento Java”, encontraremos que la mayor preocupación fue que Java no era lo suficientemente <em>simple</em> para ser usado como un lenguaje de enseñanza.</p>
<p><em>Mi Dios</em>, pensé, <em>¡están tratando de embrutecer la curricula aun mas!</em> ¿Por que mejor no le llevamos la comida a la boca a los estudiantes? Dejemos que los ayudantes de cátedra den los exámenes por ellos también, entonces nadie se cambiara a Estudios Americanos. ¿Cómo se supone que alguien aprenderá algo si la curricula ha sido cuidadosamente diseñada para hacer todo más fácil de lo que ya es? Parece haber una comisión de trabajo (<a href="http://www.sigcse.org/topics/javataskforce/java-task-force.pdf">PDF</a>) intentando idear un subconjunto simple de Java que pueda ser enseñado a estudiantes, produciendo documentación simplificada que esconde cuidadosamente toda esa basura EJB/J2EE de sus tiernas mentes, de manera tal que no tengan que preocupar sus cabecitas con otras clases que no necesiten para resolver sus aun más fáciles problemas de CS.</p>
<p>La interpretación mas compasiva de por qué las facultades CS son tan entusiastas en embrutecer sus clases es porque ello les dará más tiempo para enseñar verdaderos conceptos de CS, así no necesitaran dos clases enteras para esclarecer a los alumnos las diferencias entre, digamos, un <strong>int</strong> y un <strong>Integer</strong> en Java. Bueno pero si ese fuera el caso, 6.001 tiene la respuesta perfecta: Scheme, un lenguaje de enseñanza tan simple que el lenguaje entero puede enseñarse a estudiantes brillantes en unos 10 minutos; entonces puedes gastar el resto del semestre enseñando puntos fijos.</p>
<p>Fiu&#8230;</p>
<p>Voy a regresar a los unos y ceros.</p>
<p>(¿Te tocaron unos? ¡Bastardo suertudo! A nosotros nos tocaron todos ceros.)</p>
<p>&nbsp;</p>
<p><em>Esta traducción está basada en la versión disponible en <a href="http://local.joelonsoftware.com/wiki/Riesgos_de_las_escuelas_Java">el Wiki de Joel Spolsky</a>, corregida y adaptada por mí.</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2010/06/01/los-riesgos-de-las-universidades-java/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">432</post-id>	</item>
		<item>
		<title>¿Cómo decimos verdades que pueden lastimar?</title>
		<link>https://blog.smaldone.com.ar/2010/06/01/verdades-que-pueden-lastimar/</link>
					<comments>https://blog.smaldone.com.ar/2010/06/01/verdades-que-pueden-lastimar/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Tue, 01 Jun 2010 07:59:14 +0000</pubDate>
				<category><![CDATA[Computación]]></category>
		<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=417</guid>

					<description><![CDATA[Lo que sigue es una traducción de un excelente artículo de Edsger W. Dijkstra titulado originalmente «How do we tell truths that might hurt?«. Dijkstra es reconocido como uno de los pioneros de las Ciencias de la Computación por sus abundantes aportes, tanto en el área teórica como en la práctica. Resulta ser que, además &#8230; <a href="https://blog.smaldone.com.ar/2010/06/01/verdades-que-pueden-lastimar/" class="more-link">Sigue leyendo <span class="screen-reader-text">¿Cómo decimos verdades que pueden lastimar?</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Lo que sigue es una traducción de un excelente artículo de <a href="http://es.wikipedia.org/wiki/Edsger_Dijkstra">Edsger W. Dijkstra</a> titulado originalmente «<a href="http://userweb.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD498.html">How do we tell truths that might hurt?</a>«.</p>
<p><strong>Dijkstra</strong> es reconocido como uno de los pioneros de las Ciencias de la Computación por sus abundantes aportes, tanto en el área teórica como en la práctica. Resulta ser que, además de un notable científico, también fue un gran visionario. Una muestra de ello es el artículo aquí reproducido, publicado originalmente en el año <strong>1975</strong>.</p>
<p>Realmente es penoso ver que, aún <strong>35 años después</strong>, muchos siguen sin caer en la cuenta de cuestiones que ya en aquella época resultaban evidentes.</p>
<p><span id="more-417"></span></p>
<h3>¿Cómo decimos verdades que pueden lastimar?</h3>
<p>A veces descubrimos verdades desagradables. Cada vez que lo hacemos, estamos en dificultades: suprimirlas es científicamente deshonesto, por lo que tenemos que decirlas; pero diciéndolas, sin embargo, se volverán en nuestra contra. Si las verdades son lo suficientemente desagradables, nuestro público será psíquicamente incapaz de aceptarlas y seremos tachados de irrealistas, idealistas sin remedio, peligrosamente revolucionarios, tontamente crédulos o lo que sea. (Además de eso, decir tales verdades es una forma segura de volverse impopular en muchos círculos, y como tal, es un hecho que en general no está exento de riesgos personales. Recordemos a Galileo Galilei&#8230;)</p>
<p>Las Ciencias de la Computación parecen sufrir gravemente este conflicto. En general, se mantienen silenciosas y tratan de escapar del mismo desviando la atención. (Por ejemplo: con respecto a COBOL se puede hacer sólo una de dos cosas: luchar contra la enfermedad o pretender que no existe. La mayoría de los departamentos de Ciencias de la Computación han optado por la última como una salida más fácil). Pero, hermanos, os pregunto: ¿es honesto? ¿No está nuestro prolongado silencio corrompiendo la integridad intelectual de las Ciencias de la Computación? ¿Es decente premanecer en silencio? Si no, ¿cómo podemos hablar?</p>
<p>Para que se haga una idea de la magnitud del problema, he enumerado una serie de tales verdades. (Casi todos los científicos de computación que conozco bien estarán de acuerdo sin dudarlo con casi todas ellas. Sin embargo, permitimos que el mundo se comporte como si no las conociéramos&#8230;)</p>
<ul>
<li>La programación es una de las ramas más difíciles de las matemáticas aplicadas, los pobres matemáticos mejor hubieran seguido siendo matemáticos puros.</li>
<li>Las aplicaciones de computadora más fáciles son los cálculos técnicos/científicos.</li>
<li>Las herramientas que usamos tienen una profunda (¡y retorcida!) influencia en nuestros hábitos de pensamiento y, por lo tanto, en nuestra habilidad de pensar.</li>
<li>FORTRAN -«la enfermedad infantil»-, actualmente con casi 20 años de edad, es completamente inadecuado para cualquier aplicación informática que tenga en mente hoy: es demasiado torpe, demasiado arriesgado y demasiado costoso.</li>
<li>PL / I -«la enfermedad fatal»- pertenece más al conjunto de los problemas que al de las soluciones.</li>
<li>Es prácticamente imposible enseñar buena programación a estudiantes que han tenido exposición previa al BASIC: como programadores potenciales están mentalmente mutilados sin esperanza de regeneración.</li>
<li>El uso de COBOL incapacita la mente, y su enseñanza debe, por tanto, ser considerada como un delito penal.</li>
<li>APL es un error, llevado a cabo a la perfección. Es el lenguaje del futuro para técnicas de programación del pasado: crea una nueva generación de inútiles de la programación.</li>
<li>Los problemas de administración de empresas en general y de gestión de bases de datos, en particular, resultan mucho más complicados para las personas que piensan en IBMés, compuesto con un Inglés desalineado.</li>
<li>Sobre el uso del lenguaje: es imposible para afilar un lápiz con una cuchilla desafilada. Es igualmente inútil tratar de hacerlo con diez cuchillas desafiladas.</li>
<li>Además de una inclinación matemática, un dominio excepcional de la lengua nativa es el activo más vital de un programador competente.</li>
<li>Muchas compañías que se han vuelto dependientes de equipamiento IBM (y al hacerlo, han vendido su alma al diablo) se derrumbará bajo el peso de la complejidad incontrolada de sus sistemas de procesamiento de datos.</li>
<li>No podemos encontrar ninguna disciplina científica, ni una profesión robusta, basada en los errores técnicos del Departamento de Defensa y, principalmente, un fabricante de computadoras.</li>
<li>El uso de la terminología antropomórfica cuando se trabaja con sistemas de computación es un síntoma de inmadurez profesional.</li>
<li>Afirmando que pueden contribuir a la ingeniería de software, los científicos blandos se vuelven aún más ridículos. (No menos peligrosos, ¡ay!). A pesar de su nombre, la ingeniería de software requiere (cruelmente) el soporte de la ciencia dura.</li>
<li>En los buenos viejos tiempos los físicos repetían los experimentos de los demás, simplemente para estar seguros. Hoy se apegan a FORTRAN, de modo que puedan compartir los programas de cada uno, errores incluidos.</li>
<li>Los proyectos que promueven la progamación en «lenguaje natural» están intrínsecamente condenados al fracaso.</li>
</ul>
<p>¿No es esta lista suficiente para hacernos sentir incómodos? ¿Qué vamos a hacer? Volver a la orden del día, presumiblemente&#8230;</p>
<p><em>18 de junio 1975<br />
Plataanstraat 5<br />
Nuenen &#8211; 4565<br />
Holanda</em></p>
<p><em><strong>Prof. Dr. Edsger W. Dijkstra<br />
Burroughs Research Fellow</strong></em></p>
<p>PD: Si la conjetura «Usted hubiera preferido que no lo molestara enviándole esto» es correcta, puede añadirla a la lista de verdades incómodas.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2010/06/01/verdades-que-pueden-lastimar/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">417</post-id>	</item>
		<item>
		<title>Programadores, ¿productores o consumidores?</title>
		<link>https://blog.smaldone.com.ar/2010/03/27/programadores-productores-o-consumidores/</link>
					<comments>https://blog.smaldone.com.ar/2010/03/27/programadores-productores-o-consumidores/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Sat, 27 Mar 2010 23:46:36 +0000</pubDate>
				<category><![CDATA[Opinión]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Software libre]]></category>
		<category><![CDATA[Software privativo]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=385</guid>

					<description><![CDATA[Los programadores somos, casi por definición, productores de software. Esto es, producimos programas (que muchas veces hasta son llamados «productos», según la definición que dicta el marketing). El gran sueño de muchos programadores es desarrollar un «producto» implementando una idea innovadora (o cubriendo un nicho insatisfecho) y vender una gran cantidad de copias, multiplicando las &#8230; <a href="https://blog.smaldone.com.ar/2010/03/27/programadores-productores-o-consumidores/" class="more-link">Sigue leyendo <span class="screen-reader-text">Programadores, ¿productores o consumidores?</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Los programadores somos, casi por definición, <em>productores de software</em>. Esto es, producimos programas (que muchas veces hasta son llamados «productos», según la definición que dicta el marketing). El gran sueño de muchos programadores es desarrollar un «producto» implementando una idea innovadora (o cubriendo un nicho insatisfecho) y vender una gran cantidad de copias, multiplicando las ganancias.</p>
<p>Esta visión, lentamente, está cambiando. Por un lado, las historias de aquellos que hicieron una fortuna (o establecieron una posición económica) mediante la venta de licencias de un programa son, a la vez, cada vez más lejanas y menos frecuentes. Pero, si empezamos a vernos a nosotros mismos también como consumidores de software, el razonamiento cambia radicalmente.</p>
<p><span id="more-385"></span></p>
<h3>Comparemos</h3>
<p>Tomemos como ejemplo el desarrollo de un programa que le demande 5 años de trabajo a un programador altamente calificado y que requiera de las siguientes herramientas:</p>
<ul>
<li><strong>Sistema Operativo</strong>.</li>
<li><strong>Compilador</strong>.</li>
<li><strong>Entorno de desarrollo</strong>: Depurador, editor de textos, etc.</li>
<li><strong>Herramientas de modelado</strong>: Herramientas para hacer diagramas de diseño, documentación, etc.</li>
<li><strong>Motor de base de datos</strong>.</li>
</ul>
<p>El lapso de 5 años no es arbitrario: es una buena cota superior del tiempo pasado el cual un desarrollador debe renovar las herramientas que utiliza, si es que desea mantenerse actualizado. (Si lo prefiere, puede suponer la suma de varios desarrollos de menor envergadura, hasta llegar a cubrir dicho tiempo).</p>
<p>Comparemos entonces la cantidad de líneas de código «producidas» respecto de las «consumidas». El cociente será seguramente bastante cercano a cero. Desde este punto de vista, aún cuando un programador sigue produciendo software, su rol de consumidor es, por mucho, más relevante.</p>
<p>Alguien dirá que al vender muchas licencias del programa producido, su valor se multiplicará. Esto no es así, teniendo en cuenta que, para poder ejecutarse el programa requerirá, nuevamente, de un sistema operativo y del motor de base de datos. No es poco común ver a un programador cobrar determinada suma de dinero por un desarrollo y a su cliente desembolsar bastante más por licencias del software requerido para que funcione.</p>
<h3>Un mal negocio</h3>
<p>Entre los programadores independientes (o pequeñas empresas de desarrollo) es práctica común usar software sin pagar por sus licencias, con lo cual parte del análisis anterior no los afecta demasiado. Pero sus clientes (y cada vez más) no tienen opción.</p>
<p>Por ejemplo, un sistema que requiera de un servidor con el sistema operativo <strong>Windows 2008</strong> y el motor de bases de datos <strong>Microsoft SQL Server 2008</strong> para su utilización en 25 puestos de trabajo, requerirá el pago de  más de <strong>u$s 10.000</strong> en concepto de licencia de uso de dichos productos (en la Argentina, marzo de 2010). ¿Cuánto deberá trabajar el programador para cobrar una suma de dinero similar?</p>
<p>Claramente, esta forma de ver el negocio no tiene mucho sentido (a no ser para aquellas empresas de desarrollo que además son agente de ventas de quienes proveen el software de base y se llevan una jugosa comisión).</p>
<p>Quizá sea por este motivo que las empresas proveedoras de herramientas de desarrollo y software de base invierten tanto dinero para que los programadores se pongan «su camiseta», recurriendo para esto a <a href="https://www.youtube.com/watch?v=8To-6VIJZRE">discursos motivadores</a>, aportes a instituciones educativas, descuentos, tazas de café, etc.</p>
<p>Asumir que esta es una situación natural es resignarse a ser, ya no un productor, sino un mero promotor de la venta de productos de otro (con un esfuerzo y un riesgo bastante altos).</p>
<h3>Una buena alternativa</h3>
<p>Debemos reconocernos a nosotros mismos, antes que como productores, como consumidores de software. De esta manera, la salida es clara: debemos reducir los costos de la «materia prima». Debemos, en la medida de lo posible, utilizar software que no requiera el pago de licencias de uso. De esta manera disminuyen sensiblemente los costos para el desarrollador, como así también los costos extra del cliente. (Y cliente que gasta menos en licencias, tiene más dinero para pagarle al programador).</p>
<p>Si el sistema del ejemplo anterior pudiera correr en un servidor con <a href="http://es.wikipedia.org/wiki/GNU/Linux"><strong>GNU/Linux</strong></a> y el motor de bases de datos <a href="http://es.wikipedia.org/wiki/PostgreSQL"><strong>PostgreSQL</strong></a> tendría más de <strong>u$s 10.000</strong> de «ventaja» en condiciones similares.</p>
<p>Otro punto importante es el ahorro en hardware, al utilizar productos que reduzcan los requerimientos en este aspecto (característica que distingue a muchos programas libres, respecto de sus contrapartes privativas), aunque dicho análisis escapa al objetivo del presente artículo.</p>
<h3>¿Por qué no?</h3>
<p>Existe una marcada reticencia en ciertos programadores a analizar seriamente esta alternativa. Dejaremos de lado, por supuesto, el caso de aquellos que actúan, además, como agentes de venta de los proveedores de software de base (su caso es más que claro: ellos se benefician por ambos lados). Analizaremos algunas de las objeciones más comunes:</p>
<h4>El sistema operativo libre «X» es difícil de usar. No lo entiendo</h4>
<p>En casi todos los casos, «X» se refiere al sistema operativo <a href="http://es.wikipedia.org/wiki/GNU/Linux"><strong>GNU/Linux</strong></a> (el sistema operativo libre más difundido). Quizás el programador en cuestión haya tenido una mala experiencia tratando de usar alguna versión mal configurada u obsoleta. Seguramente tampoco haya dedicado demasiado tiempo ni esfuerzo a aprender los conceptos básicos (que no son, precisamente, como usar los botones del mouse), y se alejó cual <a href="http://es.wikisource.org/wiki/La_zorra_y_las_uvas_(Esopo)">la zorra de Esopo</a> murmurando «están verdes».</p>
<p>De esto no se desprende que <a href="http://es.wikipedia.org/wiki/GNU/Linux"><strong>GNU/Linux</strong></a> sea tán fácil, cómodo o agradable de usar que <strong>Windows 7</strong> (o más), pero tratándose de un profesional y habiendo tanto dinero de por medio, bien merece algún pequeño sacrificio.</p>
<h4>En la empresa en donde se implanta mi sistema usan Windows</h4>
<p>Aquí hay una amplia variedad de casos. ¿Usan <strong>Windows</strong> en los equipos de escritorio? Asumiendo que ya han pagado las licencias (por el tiempo que reste hasta la actualización de los equipos), de todas maneras podría significar un ahorro importante a nivel de los servidores. ¿Usan <strong>Windows</strong> en los servidores? Proveer una aplicación que no lo requiera, puede significar un valor agregado interesante.</p>
<p>En la mayoría de los casos en que la empresa «usa <strong>Windows</strong>» es porque las aplicaciones existentes lo requieren. No es, por lo tanto, una excusa para no proveer una alternativa que posibilite un ahorro importante (si no en lo inmediato, en el mediano plazo).</p>
<h4>Estoy acostumbrado a desarrollar en (y para) Windows</h4>
<p>Todos sabemos que los programadores disponemos de poco tiempo para mantenernos actualizados y lo costoso que resulta abordar el aprendizaje de una nueva tecnología. Cada quién sabrá si realmente se justifica el esfuerzo, poniendo en la balanza costos y beneficios (o, según el planteo de este artículo, costos y ahorros).</p>
<h4>No hay un equivalente libre de la herramienta «Y»</h4>
<p>Es cierto que en algunos casos (no tantos como se alegan) no hay equivalentes libres a ciertas herramientas privativas. ¿Y aquí termina el análisis? ¿No merece la pena indagar sobre alguna alternativa? ¿Tan útil es la herramienta «Y» que se hace imprescindible e indiscutible?</p>
<p>Si alguien depende exclusivamente de una determinada herramienta para desarrollar software, entonces se encuentra ante un problema bastante más grave que el gastar dinero en licencias de uso. (Preguntar a desarrolladores en <strong>Delphi</strong>,  <strong>Visual Fox</strong>, <strong>Clarion</strong>, entre otros. Pero este tema también excede el alcance del presente artículo.).</p>
<h4>No hay un equivalente libre del motor de bases de datos «Z»</h4>
<p>Aquí «Z» suele tomar la forma de <strong>MS SQL Server</strong>, <strong>Oracle</strong> o <strong>DB/2</strong>. La afirmación suele hacerse seguida de alguna frase que parece extraída de una publicidad del proveedor correspondiente. La realidad es que existen numerosos motores de bases de datos libres, como por ejemplo <a href="http://es.wikipedia.org/wiki/MySQL"><strong>MySQL</strong></a> para pequeños volúmenes de información, o <a href="http://es.wikipedia.org/wiki/PostgreSQL"><strong>PostgreSQL</strong></a> que no tiene ninguna característica importante que envidiarle a ningún otro producto.</p>
<h4>En el caso de programas libres, nadie me ofrece el soporte que me da la empresa «W»</h4>
<p>¿Enserio? Prácticamente todos los programas libres importantes, cuentan con ofertas de soporte incluso mejores que las que puedan conseguirse respecto de programas privativos. Por un lado, el soporte ofrecido es de mejor nivel, ya que se ofrece a nivel de reparación de errores en el código fuente y, por otro, muchas veces existen múltiples proveedores de soporte, que compiten entre si (en el mundo del software privativo el soporte es un monopolio del fabricante).</p>
<h3>Porque no</h3>
<p>Es cierto que hay algunos casos en donde no hay alternativa (la utilización de determinada tecnología puede ser impuesta como un requerimiento), pero en la mayoría de los casos la situación es que el programador se encuentra «atado» a sus herramientas.</p>
<p>En algunos casos, porque las han utilizado durante mucho tiempo (y tienen una gran cantidad de código desarrollado ligado a ellas) y en otros porque han «comprado» el discurso de su productor, muchos programadores se resisten a realizar cualquier análisis que tenga que ver con cambiar sus herramientas. El caso más grave (y lamentablemente no poco común) es cuando el programador simplemente no puede usar otra tecnología más que la que domina: es la única que conoce.</p>
<p>De más está decir, las inversiones en marketing dan resultado. Hoy nos encontramos a muchos programadores que han sido formados en un ambiente académico muy similar a un «monocultivo» (que, a pesar de ellos, ni siquiera ofrece los amplios márgenes de ganancia de la soja) o que se han entregado más tarde a determinada combinación de herramientas/tecnología y la han abrazado como dispuestos a envejecer (y quedar obsoletos) junto con ella.</p>
<p>Y así es que el negocio seguirá funcionando muy bien para los «grandes productores de software», en tanto que los pequeños no reconozcan su rol de consumidores. Afortunadamente, la situación ya está cambiando: abundan los ejemplos de quienes, siendo conscientes de esto, están haciendo una diferencia económica significativa.</p>
<h3>Adenda</h3>
<p>Nótese que en este artículo no se hace alusión a la licencia bajo la cual el programador entrega su programa al cliente final. El término «<em>libre</em>» sólo se aplica a las herramientas utilizadas para el desarrollo y a las requeridas para su posterior ejecución.</p>
<p>El <em>uso</em> de herramientas de desarrollo libre no impone ninguna condición sobre la licencia que acompañará al programa resultante. (Distinta situación puede darse si se incorpora <em>código</em> de un programa libre en uno de producción propia).</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2010/03/27/programadores-productores-o-consumidores/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">385</post-id>	</item>
		<item>
		<title>Is MySQL a toy RDBMS?</title>
		<link>https://blog.smaldone.com.ar/2008/12/29/is-mysql-a-toy-rdbms/</link>
					<comments>https://blog.smaldone.com.ar/2008/12/29/is-mysql-a-toy-rdbms/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Mon, 29 Dec 2008 22:38:18 +0000</pubDate>
				<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=135</guid>

					<description><![CDATA[Since two days ago I&#8217;m trying to believe what I&#8217;ve found: MySQL («the world&#8217;s most popular open source database«, as they say) is unable to resolve a simple SQL query in an efficient way, leading me (and the program I&#8217;m developing) to a dead end. The situation I have a table «mytable» (1,000,000 rows) with &#8230; <a href="https://blog.smaldone.com.ar/2008/12/29/is-mysql-a-toy-rdbms/" class="more-link">Sigue leyendo <span class="screen-reader-text">Is MySQL a toy RDBMS?</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Since two days ago I&#8217;m trying to believe what I&#8217;ve found: <a href="http://www.mysql.com/">MySQL</a> («<em>the world&#8217;s most popular open source database</em>«, as they say) is unable to resolve a simple SQL query in an efficient way, leading me (and the program I&#8217;m developing) to a dead end.</p>
<p><span id="more-135"></span> </p>
<h3>The situation</h3>
<p>I have a table «<em>mytable</em>» (1,000,000 rows) with a column named «<em>mycolumn</em>» of type «<strong>datetime</strong>» and an index created on it named «<em>idx_mycolumn</em>«. When I issue the following query:</p>
<blockquote><p><code>SELECT * FROM mytable ORDER BY mycolumn</code></p></blockquote>
<p>it tooks more than 1 minute to give the results (the 1,000,000 rows ordered by <em>mycolumn</em>.)</p>
<p>Using the command «<strong>EXPLAIN</strong>» I can see that the <a href="http://www.mysql.com/">MySQL</a> optimizer don&#8217;t use the index at all: it generates a filesort (on disk) in order to sort the resultset. The only way to solve this issue (as far as I know) is providing a «hint» to the optimizer, telling what indexes to use:</p>
<blockquote><p><code>SELECT * FROM mytable USE INDEX(idx_mycolumn) ORDER BY mycolumn</code></p></blockquote>
<p>But the optimizer still chooses to do a full table scan instead of using the «<em>idx_mycolumn</em>» index (and still generates a filesort, taking more than 1 minute.)</p>
<p>There is a way to force the optimizer to use the index:</p>
<blockquote><p><code>SELECT * FROM mytable FORCE INDEX(idx_mycolumn) ORDER BY mycolumn</code></p></blockquote>
<p>This time, the optimizer uses the index, and the query takes about 3 seconds. (Is the <a href="http://www.mysql.com/">MySQL</a> query optimizer that bad?)</p>
<h3>A bigger problem</h3>
<p>Then, I came into the real problem for me: Obviously I&#8217;ll never need to get all the rows from that table, but is a common task to «paginate» the rows (previously ordered by some column) taking, let&#8217;s say, 25 rows at a time and using an offset. The query looks as follows:</p>
<blockquote><p><code>SELECT * FROM mytable ORDER BY mycolumn LIMIT 100000,25</code></p></blockquote>
<p>It sorts the resultset using the values of «<em>mycolumn</em>» and then returns 25 rows skipping the first 100,000. Surprisingly, this time the query tooks less than 1 second to execute (and «<strong>EXPLAIN</strong>» says that is using the «<em>idx_mycolumn</em>» index. What a joy!).</p>
<p>But the problem is still there: If the limit reaches (or surpases) the last row, then the optimizer  throws away the index and generates a filesort (taking more than 1 minute, making the query totally useless&#8230;)</p>
<p>The solution (again) is to force the optimizer to use the index «<em>idx_mycolumn</em>«, getting a response in about 3 seconds.</p>
<h3>My conclusion</h3>
<p>Far from being a MySQL expert, the only conclusion I can reach is that the optimizer is really screwed up. How can it be possible that changing only the limit of the results, confuses the optimizer in such a way that leads to a simple query (that can&#8217;t take more than a few seconds) to take an unacceptable amount of time (not to mention the disk space)?</p>
<p>As I can&#8217;t (and don&#8217;t want) force indexes in every query involving large tables in my system, the only real solution for me is replacing <a href="http://www.mysql.com/">MySQL</a> with a more robust (and decent) DBMS (I&#8217;ve tried <a href="http://www.postgresql.org/">PostgreSQL</a> with the same database and the results are far more reasonable.)</p>
<h3>Some things to consider</h3>
<ul>
<li>The problem is the same being the engine used <strong>MyISAM</strong> or <strong>InnoDB</strong>.</li>
<li>The problem doesn&#8217;t get solved after doing a «<strong>ANALYZE TABLE</strong>«.</li>
<li>I&#8217;ve trying with other datatypes for the sorting column, with the same results.</li>
<li>I&#8217;ve tested this issue with versions 5.0.35 and 5.0.51a, with identical results.</li>
</ul>
<h3>Update (2008/12/30)</h3>
<p>The observed behavior must be related with the <a href="http://bugs.mysql.com/bug.php?id=28404">bug 28404</a> (<a href="http://lists.mysql.com/commits/31882">patched</a> in version 5.1). From the patch description:</p>
<blockquote>
<p>When there are many indexes in table, optimizer wrongly does not even consider the one on column used in ORDER BY, when LIMIT N clause is also present.</p>
</blockquote>
<p>I&#8217;ve oversimplified the example, but in my real scenario I had multiple single-column indexes on the table. I still can&#8217;t believe that the optimizer get confused by having multiple indexes to choose from (but only in presence of the LIMIT clause). Can you guess how is the optimizer coded? (That&#8217;s why I use the word «<em>toy</em>» in the title.)</p>
<p>A posible solution seems to be moving to the new version, but anyway, <strong>MySQL</strong> 5.1 also has <a href="http://www.planetmysql.org/entry.php?id=16232">several issues</a> (and the distribution installation script for <strong>GNU/Linux</strong> is totally broken), so I&#8217;m moving to <strong>PostgreSQL</strong>.</p>
<p><em>(Thanks to Abel Chiola for the links.)</em></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2008/12/29/is-mysql-a-toy-rdbms/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">135</post-id>	</item>
		<item>
		<title>Charla sobre Ruby en Córdoba (7JRSL)</title>
		<link>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-en-cordoba-7jrsl/</link>
					<comments>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-en-cordoba-7jrsl/#respond</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Thu, 02 Oct 2008 21:54:55 +0000</pubDate>
				<category><![CDATA[Charlas]]></category>
		<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=123</guid>

					<description><![CDATA[Siguiendo con la tendencia a desempolvar cosas viejas, aquí va la presentación que utilicé en mi charla «Ruby: &#8216;Orientación a Objetos&#8217; y algo más&#8230;», en el marco de las 7mas. Jornadas Regionales de Software Libre, realizadas en la ciudad de Córdoba, en agosto de 2007. Ruby: «Orientación a Objetos» y algo más&#8230; Presentación en formato &#8230; <a href="https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-en-cordoba-7jrsl/" class="more-link">Sigue leyendo <span class="screen-reader-text">Charla sobre Ruby en Córdoba (7JRSL)</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Siguiendo con la tendencia a desempolvar cosas viejas, aquí va la presentación que utilicé en mi charla <a href="http://jornadas.grulic.org.ar/7/contenido/programa/charlas/charla43">«Ruby: &#8216;Orientación a Objetos&#8217; y algo más&#8230;»</a>, en el marco de las <a href="http://jornadas.grulic.org.ar/7/">7mas. Jornadas Regionales de Software Libre</a>, realizadas en la ciudad de Córdoba, en agosto de 2007.</p>
<h3>Ruby: «Orientación a Objetos» y algo más&#8230;</h3>
<ul>
<li><a href="/files/7jrsl/ruby_smaldone.pdf">Presentación en formato PDF</a></li>
<li><a href="/files/7jrsl/ruby_smaldone.odp">Presentación en formato ODP</a> (<a href="http://www.openoffice.org/">OpenOffice.org</a>)</li>
</ul>
<p><span id="more-123"></span></p>
<p>Bueno, ¡no podía faltar una foto! <strong>;)</strong></p>
<div class="centerpic"><img decoding="async" src="/files/7jrsl/cordoba.jpg" alt="7JRSL"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-en-cordoba-7jrsl/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">123</post-id>	</item>
		<item>
		<title>Charla sobre Ruby on Rails en Rosario (5JRSL)</title>
		<link>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-on-rails-en-rosario-5jrsl/</link>
					<comments>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-on-rails-en-rosario-5jrsl/#respond</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Thu, 02 Oct 2008 21:10:20 +0000</pubDate>
				<category><![CDATA[Charlas]]></category>
		<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=122</guid>

					<description><![CDATA[Esta es la presentación que utilicé en la charla «Primeros pasos en Rails» en ocasión de las 5tas. Jornadas Regionales de Software Libre, en noviembre del 2005, en Rosario, Santa Fé. Aunque se trata de material un tanto obsoleto, ya que está basado en las primeras versiones de Rails (en las cuales ni siquiera existían, &#8230; <a href="https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-on-rails-en-rosario-5jrsl/" class="more-link">Sigue leyendo <span class="screen-reader-text">Charla sobre Ruby on Rails en Rosario (5JRSL)</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Esta es la presentación que utilicé en la charla <a href="http://www.ant.org.ar/jornadas/html/programDescription.php?id=20">«Primeros pasos en Rails»</a> en ocasión de las <a href="http://www.ant.org.ar/jornadas/">5tas. Jornadas Regionales de Software Libre</a>, en noviembre del 2005, en Rosario, Santa Fé.</p>
<p>Aunque se trata de material un tanto obsoleto, ya que está basado en las primeras versiones de Rails (en las cuales ni siquiera existían, por ejemplo, las «migrations»), decidí publicarlo de todas formas.</p>
<h3>Primeros pasos en Rails</h3>
<ul>
<li><a href="/files/5jrsl/primeros_pasos_rails.pdf">Presentación en formato PDF</a></li>
<li><a href="/files/5jrsl/primeros_pasos_rails.odp">Presentación en formato ODP</a> (<a href="http://www.openoffice.org/">OpenOffice.org</a>)</li>
</ul>
<p><span id="more-122"></span></p>
<p>Un pequeño comentario: Todavía recuerdo el gran esfuerzo de la gente del <strong>Grupo de usuarios de GNU/Linux de Rosario</strong> (<a href="http://www.lugro.org.ar/">LUGRO</a>) y de los integrantes de la <strong>Asociación Argentina de Nuevas Tecnologías</strong> (<a href="http://ant.org.ar/">ANT</a>) que lograron una organización impecable y, como siempre ocurre en estos eventos, un excelente clima de camaradería.</p>
<div class="centerpic"><img decoding="async" src="/files/5jrsl/rosario.jpg" alt="5JRSL"></div>
<p>En la foto aparecemos (de izquierda a derecha) <a href="http://blog.dgomez.com.ar/">Diego Gomez</a> (gran amigo y colega) , yo, <a href="http://www.bea.org.ar/">Beatriz Busaniche</a> (excelente periodista, integrante de la <a href="http://www.vialibre.org.ar">Fundación Vía Libre</a> y gran activista en favor del Software Libre), <a href="http://federratas.codigolibre.net/">Federico Heinz</a> (amigazo, también integrante de <a href="http://www.vialibre.org.ar">Vía Libre</a> y hacker de aquellos&#8230;) y <a href="http://criadoindomable.wordpress.com/">Sebastián Criado</a> (incansable, movedizo y persistente luchador por el software libre, entre otras causas).</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2008/10/02/charla-sobre-ruby-on-rails-en-rosario-5jrsl/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">122</post-id>	</item>
		<item>
		<title>Mi charla en las 8vas. JRSL</title>
		<link>https://blog.smaldone.com.ar/2008/09/02/mi-charla-en-las-8vas-jrsl/</link>
					<comments>https://blog.smaldone.com.ar/2008/09/02/mi-charla-en-las-8vas-jrsl/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Wed, 03 Sep 2008 01:07:34 +0000</pubDate>
				<category><![CDATA[Charlas]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Redes]]></category>
		<category><![CDATA[Software libre]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=120</guid>

					<description><![CDATA[Tal como comenté en el artículo anterior, tuve la gran satisfacción de dar una charla en las 8vas. Jornadas Regionales de Software Libre, realizadas del 20 al 22 de agosto pasado en la Universidad de Belgrano. Aunque en algún momento estará disponible en el sitio del evento (junto con el video de la charla), no &#8230; <a href="https://blog.smaldone.com.ar/2008/09/02/mi-charla-en-las-8vas-jrsl/" class="more-link">Sigue leyendo <span class="screen-reader-text">Mi charla en las 8vas. JRSL</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Tal como comenté en el <a href="https://blog.smaldone.com.ar/2008/08/02/8vas-jornadas-regionales-de-software-libre/">artículo anterior</a>, tuve la gran satisfacción de dar una charla en las <a href="http://jornadas.cafelug.org.ar/">8vas. Jornadas Regionales de Software Libre</a>, realizadas del 20 al 22 de agosto pasado en la Universidad de Belgrano.</p>
<p>Aunque en algún momento estará disponible en el sitio del evento (junto con el video de la charla), no resití la tentación de publicar la presentación que utilicé.</p>
<h3>Experiencias en la implementación de un ISP con software libre</h3>
<ul>
<li><a href="/files/8jrsl/isp_software_libre.pdf">Presentación en formato PDF</a></li>
<li><a href="/files/8jrsl/isp_software_libre.odp">Presentación en formato ODP</a> (<a href="http://www.openoffice.org/">OpenOffice.org</a>)</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2008/09/02/mi-charla-en-las-8vas-jrsl/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">120</post-id>	</item>
		<item>
		<title>La base de datos del sistema de escrutinio de MSA</title>
		<link>https://blog.smaldone.com.ar/2008/06/25/la-base-de-datos-del-sistema-de-escrutinio-de-msa/</link>
					<comments>https://blog.smaldone.com.ar/2008/06/25/la-base-de-datos-del-sistema-de-escrutinio-de-msa/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Wed, 25 Jun 2008 09:06:21 +0000</pubDate>
				<category><![CDATA[Política]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Voto electrónico]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/?p=115</guid>

					<description><![CDATA[Como comenté en el artículo anterior, tuve la oportunidad de tener cierto contacto con el sistema utilizado por la empresa Magic Software Argentina (MSA) en el escrutinio provisorio de las elecciones municipales de mi ciudad, Río Cuarto. Los fiscales informáticos tuvimos acceso a la interfaz de consulta del proceso de escrutinio y a un volcado &#8230; <a href="https://blog.smaldone.com.ar/2008/06/25/la-base-de-datos-del-sistema-de-escrutinio-de-msa/" class="more-link">Sigue leyendo <span class="screen-reader-text">La base de datos del sistema de escrutinio de MSA</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Como comenté en <a href="https://blog.smaldone.com.ar/2008/06/23/las-elecciones-en-rio-cuarto-y-msa/">el artículo anterior</a>, tuve la oportunidad de tener cierto contacto con el sistema utilizado por la empresa <a href="http://www.msa.com.ar/">Magic Software Argentina</a> (<strong>MSA</strong>) en el escrutinio provisorio de las elecciones municipales de mi ciudad, Río Cuarto.</p>
<p>Los fiscales informáticos tuvimos acceso a la interfaz de consulta del proceso de escrutinio y a un volcado de la base de datos, que se realizaba cada 5 minutos. Lamentablemente, no tuvimos acceso al código fuente de la aplicación (aunque espero poder acceder al informe de los peritos contratados por la Junta Electoral).</p>
<p>Una vez finalizado el escrutinio provisorio, surgieron diferencias en los totales de votantes de los dos cargos electivos. A raíz de esto, decidí inspeccionar la base de datos con el objetivo de generar el listado de las mesas en las cuales se originaba dicha diferencia. De dicho análisis resultó el siguiente artículo, en el que me permito realizar algunas críticas.</p>
<p><span id="more-115"></span></p>
<h3>El diagrama de Entidad-Relación (DER)</h3>
<p>El siguiente es el DER que nos envió la gente de <strong>MSA</strong>:</p>
<div class="centerpic"><img decoding="async" src="/files/msa/database.png" alt="Diagrama de Entidad-Relación de la Base de Datos" /></div>
<p>Como puede verse se trata de una base de datos realmente simple (apenas 11 tablas). Lo que me llamó la atención a primera vista fue la utilización de palabras en castellano (muchos programadores opinamos que los programas deberían estar documentados en inglés). Siguiendo con los nombres, por más que me esforcé no pude imaginar la diferencia entre «<em>ubicaciones</em>» y «<em>lugares</em>«. No encontré palabras como «<em>mesa</em>«, «<em>escuela</em>«, «<em>circuito</em>«. A mi entender, la elección de la nomenclatura no ha sido la mejor.</p>
<h3>Las claves primarias</h3>
<p>En 9 tablas de la base de datos, las claves primarias son del tipo «<code>varchar</code>«. Si bien esto no es del todo incorrecto, no es muy recomendable. Las claves primarias deberían ser del tipo «<code>integer</code>«, y además auto-incrementadas (<a href="http://www.postgresql.org/">PostgreSQL</a>, el RDBMS utilizado, lo soporta). Esto no solamente simplifica la asignación de valores a las claves (no hay que verificar la unicidad), sino que tiene un gran impacto en el desempeño de la base de datos.</p>
<p>Al utilizar el tipo «<code>varchar</code>«, cuya longitud es variable, el tamaño de los índices es mayor que usando «<code>integer</code>«. Esto, al aumentar la cantidad de filas de las tablas, se torna cada vez más importante (es deseable que los índices quepan en la caché del RDBMS). (En Río Cuarto había solamente 352 mesas y menos de 110.000 votantes, por lo cual no debe haberse notado la diferencia, pero en una elección más amplia seguramente lo haría.)</p>
<p>Un factor que agrava la situación es que la comparación de claves, al tratarse de cadenas, debe hacerse caracter a caracter (a diferencia de la comparación de valores enteros, que se realiza mediante una simple resta). Como veremos más adelante, en algunas tablas los valores del atributo clave en varias filas tienen un prefijo en común. Esto ralentiza aún más la comparación, y la situación es empeorada por la utlización de la codificación de caracteres <strong>UTF-8</strong>, debido a la implementación interna de <strong>PostgreSQL</strong>. </p>
<p>En mi opinión pudiendo usar valores enteros como clave, debieron haberlo hecho.</p>
<h3>¿Relación inexistente?</h3>
<p>Primero, una breve explicación del problema: La ciudad se divide en 3 circuitos electorales, en los cuales se encuentran las distintas escuelas, en donde a su vez están las mesas de votación. Como el sistema permite analizar circuitos, escuelas y mesas por separado, el primer diseño que cualquier programador pensaría es disponer de tres tablas: «circuitos», «escuelas» y «mesas» (en el caso de una elección provincial o nacional se agregarían algunas más). Entre esas tablas habría relaciones 1:N, es decir «1 circuito tiene N escuelas, 1 escuela pertenece a un circuito», «1 escuela tiene N mesas, 1 mesa pertenece a 1 escuela».</p>
<p>Aprovechando el hecho de que tanto las escuelas como las mesas tienen los mismos atributos, decidieron usar una única tabla, denominada «ubicaciones», según muestra el DER:</p>
<div class="centerpic"><img decoding="async" src="/files/msa/database_ubicaciones.png" alt="Entidad Ubicaciones" /></div>
<p>Es común utilizar este tipo de representación para estructuras de «árbol». Esto se logra agregando como atributo una clave foránea que referencia a la clave primaria de la misma tabla. En las filas «padre»  dicho atributo tiene el valor «<code>NULL</code>«, en tanto que en las filas «hijas», dicho atributo contiene el valor de la clave primaria del padre.</p>
<p>Sin embargo, el código SQL de la estructura de la tabla «<code>ubicaciones</code>» es el siguiente:</p>
<blockquote>
<p><code></p>
<pre>CREATE TABLE ubicaciones (
    id_ubicacion character varying(12) NOT NULL,
    clase character varying(30) NOT NULL,
    descripcion character varying(100),
    sexo character(1),
    CONSTRAINT ubicaciones_sexo_check CHECK 
          (((sexo = 'F'::bpchar) OR (sexo = 'M'::bpchar)))
);</pre>
<p></code></p>
</blockquote>
<p>No existe ningún atributo que oficie de clave foránea para representar la relación en cuestión. ¿Cómo es esto posible?</p>
<p>Para comprender cómo está representada esta relación, fue necesario analizar los datos de la tabla (algo que, después de discutirlo con varios amigos, no pudimos llegar a la conclusión de qué principios de la teoría de bases de datos violenta, quizás algún lector pueda echar algo de luz al respecto). Encontre lo siguiente:</p>
<div class="centerpic"><img decoding="async" src="/files/msa/ubicaciones_data.png" alt="Tabla ubicaciones" /></div>
<p>El «truco» consiste en utilizar parte de la clave primaria de una fila, para referenciar a la fila «padre». Por ejemplo, las claves de todas las mesas pertenecientes a la escuela «Adolfo Alsina» (cuya clave es «<code>RC0101</code>«) comienzan con el prefijo «<code>RC0101</code>«. De la misma manera, las claves de todas las escuelas del circuito «165» (cuya clave es «<code>RC01</code>«) comienzan con el prefijo «<code>RC01</code>«.</p>
<p>Ingenioso, pero totalmente innecesario y contrario a la teoría de bases de datos relacionales. De hecho, la relación está presente en el DER, pero no se ve reflejada en la base de datos. (Este tipo de representación de relaciones basadas en códigos era una práctica común de los programadores <strong>Cobol</strong> de otras épocas.)</p>
<h3>Tipos de datos</h3>
<p>Siguiendo con la tabla «<code>ubicaciones</code>«, podemos apreciar la siguiente restricción de integridad:</p>
<blockquote>
<p><code></p>
<pre>CONSTRAINT ubicaciones_sexo_check CHECK 
         (((sexo = 'F'::bpchar) OR (sexo = 'M'::bpchar)))</pre>
<p></code></p>
</blockquote>
<p>El objetivo de esta restricción es verificar que el valor del atributo «<code>sexo</code>» (de tipo «<code>character(1)</code>» sea «<code>F</code>» o «<code>M</code>«. Una forma más simple y eficiente, es definir un tipo de datos enumerado:</p>
<blockquote>
<p><code></p>
<pre>CREATE TYPE sexos AS ENUM ('F', 'M')</pre>
<p></code></p>
</blockquote>
<p>Esta misma situación se produce en otras tablas, incluyendo la reiteración de casos como el que sigue:</p>
<blockquote>
<p><code></p>
<pre>CONSTRAINT usuarios_carga_check CHECK 
          (carga = 'SI'::bpchar OR carga = 'NO'::bpchar)</pre>
<p></code></p>
</blockquote>
<p>Aquí, evidentemente, hubiera bastado definir al atributo «<code>carga</code>» de tipo «<code>boolean</code>«. (Esta restricción se encuentra en la tabla «<code>usuarios</code>«, en donde es reiterada tres veces.)</p>
<p>La tabla «<code>estados</code>» contiene los distintos estados en que puede encontrarse una planilla a lo largo del proceso:</p>
<blockquote>
<p><code></p>
<pre>CREATE TABLE estados (
    id_estado character varying(16) NOT NULL,
    descripcion character varying(50),
    bg_color1 character varying(7),
    bg_color2 character varying(7),
    prioridad integer,
    orden integer,
    accion character varying(20),
    CONSTRAINT estados_id_estado_check CHECK
         ((((((id_estado)::text = 'Espera'::text) 
          OR ((id_estado)::text = 'En Proceso'::text)) 
          OR ((id_estado)::text = 'Intranet'::text))
          OR ((id_estado)::text = 'Internet'::text)))
);</pre>
<p></code></p>
</blockquote>
<p>Aquí la restricción de integridad tiene como objetivo que restringir los valores de la clave «<code>id_estado</code>«, pero esto deja sólo cuatro posibilidades (de hecho, ¡los cuatro estados posibles de una planilla!). Codificar en el esquema de la base de datos los valores (fijos) de las claves de las cuatro entradas que luego tendrá la tabla no parece una buena idea. (Nuevamente, de juzgarse necesario, debería haberse utilizado un tipo enumerado.)</p>
<p>Otro punto cuestionable es la elección de los valores para codificar cada estado: varias palabras, uso de mayúsculas y minúsculas.</p>
<h3>Otros errores</h3>
<p>En el DER puede verse lo siguiente:</p>
<div class="centerpic"><img decoding="async" src="/files/msa/database_error_1.png" alt="Error en el Diagrama de Entidad-Relación de la Base de Datos 1" /></div>
<p>Esto parece indicar que no puede haber más de 2 planillas en el mismo estado, algo que es falso (de hecho, inicialmente todas las planillas están en el estado «Espera» y al finalizar están en el estado «Internet».</p>
<p>El DER también muestra la siguiente entidad:</p>
<div class="centerpic"><img decoding="async" src="/files/msa/database_error_2.png" alt="Error en el Diagrama de Entidad-Relación de la Base de Datos 2" /></div>
<p>La tabla que se corresponde con dicha entidad se llama «<code>configuracion</code>» (en singular).</p>
<p>Estos errores pueden parecer simples detalles (de hecho, en un sistema con solamente 11 tablas posiblemente lo sean), pero en un sistema más complejo pueden dificultar sensiblemente la programación, propendiendo a la comisión de errores.</p>
<h3>Conclusión</h3>
<p>Sin ser un experto en bases de datos relacionales (las utilizo desde hace más de 10 años como parte de mi trabajo, pero no me considero un especialista en la materia), los errores detectados me dan la pauta de que no se ha puesto el suficiente cuidado en el diseño de la base de datos, fundamentalmente de cara a la escalabilidad del sistema para soportar volumenes de carga mayores a los generados por proceso electoral como el de Río Cuarto (2 cargos electivos, 6 listas y 352 mesas).</p>
<p>De más está decirlo, dejo abierto este espacio a críticas y sugerencias respecto de este tema.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2008/06/25/la-base-de-datos-del-sistema-de-escrutinio-de-msa/feed/</wfw:commentRss>
			<slash:comments>22</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">115</post-id>	</item>
		<item>
		<title>El secreto de Ruby: Las «clausuras»</title>
		<link>https://blog.smaldone.com.ar/2007/04/26/el-secreto-de-ruby-las-clausuras/</link>
					<comments>https://blog.smaldone.com.ar/2007/04/26/el-secreto-de-ruby-las-clausuras/#comments</comments>
		
		<dc:creator><![CDATA[Javier]]></dc:creator>
		<pubDate>Thu, 26 Apr 2007 19:37:04 +0000</pubDate>
				<category><![CDATA[Programación]]></category>
		<guid isPermaLink="false">http://blog.smaldone.com.ar/2007/04/26/el-secreto-de-ruby-las-clausuras/</guid>

					<description><![CDATA[Uno de los mecanismos más potentes provistos por el lenguaje Ruby es la posibilidad de manipular bloques de código que pueden ser pasados como argumentos en la invocación a funciones. Este mecanismo se denomina «clausura» («closure«, en inglés), y aunque no es exclusivo de Ruby (es un viejo conocido en Smalltalk y Lisp, encontrándose aún &#8230; <a href="https://blog.smaldone.com.ar/2007/04/26/el-secreto-de-ruby-las-clausuras/" class="more-link">Sigue leyendo <span class="screen-reader-text">El secreto de Ruby: Las «clausuras»</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>Uno de los mecanismos más potentes provistos por el lenguaje <strong>Ruby</strong> es la posibilidad de manipular bloques de código que pueden ser pasados como argumentos en la invocación a funciones.</p>
<p>Este mecanismo se denomina «<em>clausura</em>» («<a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"><em>closure</em></a>«, en inglés), y aunque no es exclusivo de <strong>Ruby</strong> (es un viejo conocido en <strong>Smalltalk</strong> y <strong>Lisp</strong>, encontrándose aún en <strong>Perl</strong> y <strong>Python</strong>), la simplicidad de su uso lo transforma en una herramienta muy poderosa y flexible.</p>
<p><span id="more-110"></span></p>
<p>Quienes hemos programado en lenguajes funcionales (como <strong>ML</strong> y <strong>Haskell</strong>), siempre hemos extrañado en los lenguajes imperativos la posibilidad de pasar funciones como parámetros de forma «natural» (no a la manera en que puede hacerse en <strong>Java</strong> o <strong>Pascal</strong>, sino incluyendo las ligaduras al <em>scope</em> actual).</p>
<h3>Un ejemplo simple</h3>
<p>Supongamos que deseamos escribir una función que tome como parámetro un arreglo de valores enteros y retorne otro arreglo, producto de multiplicar por 2 cada uno de los elementos del parámetro.</p>
<p>En <strong>Java</strong> podríamos escribir algo así:</p>
<blockquote>
<p><code><strong>public static</strong> ArrayList double(ArrayList x)<br />
<strong>{</strong><br />
&nbsp;&nbsp;ArrayList y = <strong>new</strong> ArrayList();<br />
&nbsp;&nbsp;<strong>for</strong> (Iterator i = x.iterator(); i.hasNext(); )<br />
&nbsp;&nbsp;&nbsp;&nbsp;y.add(i.next() * 2);<br />
&nbsp;&nbsp;<strong>return</strong> y;<br />
<strong>}</strong></code></p>
</blockquote>
<p><em>(Obviamente, olvidándonos de algunos casts para simplificar la lectura.)</em></p>
<p><!-- y.add(new Integer(((Integer)(i.next())).intValue() * 2 )); --></p>
<p>O, en <strong>PHP</strong>:</p>
<blockquote>
<p><code><strong>function</strong> double($x) <strong>{</strong><br />
&nbsp;&nbsp;$y = <strong>array</strong>();<br />
&nbsp;&nbsp;<strong>foreach</strong> ($x as $e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;array_push($y, $e*2);<br />
&nbsp;&nbsp;<strong>return</strong> $y;<br />
<strong>}</strong></code></p>
</blockquote>
<p>En tanto que en un lenguaje funcional, como <strong>Haskell</strong> podríamos escribir lo siguiente:</p>
<blockquote>
<p><code>double x = map (*2) x</code></p>
</blockquote>
<p>O, simplemente:</p>
<blockquote>
<p><code>double = map (*2)</code></p>
</blockquote>
<p>«<code>map</code>» toma como parámetro una función (en este caso, la función parcial «<code>*2</code>«) y un arreglo, devolviendo el resultado de aplicar dicha función a cada elemento del arreglo.</p>
<p>Veamos un ejemplo de la evaluación de <code>double</code>:</p>
<blockquote>
<p><code>double [1, 2, 3]<br />
[1*2, 2*2, 3*2]<br />
[2, 4, 6]</code></p>
</blockquote>
<p>Como podemos ver, la principal ventaja de los lenguajes funcionales es su expresividad, en el sentido de que el código del programa expresa de forma mucho más clara qué es lo que este hace (multiplicar por 2 cada elemento del arreglo).</p>
<p>En <strong>Ruby</strong>, aunque no es un lenguaje funcional, la posibilidad de pasar funciones (o, en general, bloques de código) como parámetro se presenta de forma igualmente sencilla:</p>
<blockquote>
<p><code><strong>def</strong> double(a)<br />
&nbsp;&nbsp;a.map {|e| e*2}<br />
<strong>end</strong></code></p>
</blockquote>
<p>«<code>map</code>» es un método de la clase «<code>Array</code>» que toma un bloque de código y lo ejecuta para cada elemento del arreglo, devolviendo la colección de los resultados producidos. El fragmento «<code>|e|</code>» establece la ligadura entre el identificador «<code>e</code>» y el elemento actual.</p>
<h3>Explotando la potencia de las clausuras</h3>
<p>Supongamos ahora que tenemos una clase «<code>Person</code>«, cuyo método «<code>age</code>» calcula la edad de la persona. Si tenemos una colección de personas en el arreglo «<code>people</code>» y deseamos obtener sólo aquellas que son mayores de 18 años, en <strong>Ruby</strong> podríamos escribir lo siguiente:</p>
<blockquote>
<p><code>people.select{|p| p.age &gt; 18}</code></p>
</blockquote>
<p><em>(El método «<code>select</code>» aplica una función lógica (booleana) a cada elemento y devuelve sólo aquellos para los cuales resultó verdadera.)</em></p>
<p>En tanto que si, además, quisiéramos mostrar el nombre de cada una de ellas, podríamos escribir:</p>
<blockquote>
<p><code>people.select{|p| p.age &gt; 18}.each{|p| puts p.name}</code></p>
</blockquote>
<p><em>(El método «<code>each</code>» aplica el bloque a cada elemento del arreglo.)</em></p>
<p>O bien, de forma más compacta (sin generar un segundo arreglo):</p>
<blockquote>
<p><code>people.each{|p| puts p.name if p.age &gt; 18}</code></p>
</blockquote>
<h3>Comparación con otros lenguajes</h3>
<h4>Problema 1</h4>
<p>Convertir las cadenas de un arreglo a mayúsculas.</p>
<p>En <strong>PHP</strong>:</p>
<blockquote>
<p><code><strong>for</strong> ($i = 0; $i &lt; count($a); $i++)<br />
&nbsp;&nbsp;$a[$i] = strtoupper($a[$i]);</code></p>
</blockquote>
<p>En <strong>Ruby</strong>:</p>
<blockquote>
<p><code>a.map!{|e| e.upcase}</code></p>
</blockquote>
<p><em>(El método «<code>map!</code>«, a diferencia de «<code>map</code>«, modifica el arreglo, en vez de retornar uno nuevo.)</em></p>
<h4>Problema 2</h4>
<p>Dado un arreglo de la forma <code>[["nombre", "apellido"]]</code>, obtener un arreglo de la forma <code>["apellido, nombre"]</code>. Por ejemplo, dado:</p>
<blockquote>
<p><code>[["Javier","Smaldone"],["Santiago","Lobos"],["Bon","Scott"]]</code></p>
</blockquote>
<p>obtener:</p>
<blockquote>
<p><code>["Smaldone, Javier", "Lobos, Santiago", "Scott, Bon"]</code></p>
</blockquote>
<p>En <strong>PHP</strong>:</p>
<blockquote>
<p><code>$b = array();<br />
<strong>foreach</strong> ($a as $e)<br />
&nbsp;&nbsp;array_push($b, $e[1] . ', ' . $e[0]);</code></p>
</blockquote>
<p>En <strong>Ruby</strong>:</p>
<blockquote>
<p><code>b = a.map{|e| e.reverse.join(', ')}</code></p>
</blockquote>
<h4>Problema 3</h4>
<p>Calcular la edad promedio de las personas mayores de edad (según el ejemplo planteado anteriormente).</p>
<p>En <strong>PHP</strong>:</p>
<blockquote>
<p><code>$sum = 0;<br />
$count = 0;<br />
<strong>foreach</strong> ($people as $p) <strong>{</strong><br />
&nbsp;&nbsp;<strong>if</strong> ($p-&gt;age &gt; 18) <strong>{</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;$sum += $p-&gt;age;<br />
&nbsp;&nbsp;&nbsp;&nbsp;$count++;<br />
&nbsp;&nbsp;<strong>}</strong><br />
<strong>}</strong><br />
<strong>if</strong> ($count) print $sum/$count;</code></p>
</blockquote>
<p>Una solución posible en <strong>Ruby</strong> sería:</p>
<blockquote>
<p><code>adults = people.select{|p| p.age &gt; 18}<br />
sum = 0<br />
adults.each {|p| sum += p.age }<br />
puts sum.to_f/adults.size if adults.size &gt; 0</code></p>
</blockquote>
<p>Pero usando todo el poder de las clausuras y las funciones «<code>map</code>» e «<code>inject</code>«, podríamos escribir:</p>
<blockquote>
<p><code>adults = people.select{|p| p.age > 18}<br />
sum = adults.map{|p| p.age}.inject{|ac,e| ac+e}<br />
puts sum.to_f/adults.size if sum</code></p>
</blockquote>
<p><em>( «<code>inject</code>» ejecuta el bloque, asignando la segunda variable a cada elemento del arreglo y asignando el resultado de la ejecución a la primera, manteniendo su valor a través de cada iteración.)</em></p>
<h4>Problema 4</h4>
<p>Dado un arreglo de cadenas, obtener la de mayor longitud.</p>
<p>En <strong>PHP</strong>:</p>
<blockquote>
<p><code>$max = '';<br />
<strong>foreach</strong> ($a as $e)<br />
&nbsp;&nbsp;<strong>if</strong> (strlen($e) &gt; strlen($max))<br />
&nbsp;&nbsp;&nbsp;&nbsp;$max = $e;</code></p>
</blockquote>
<p>En <strong>Ruby</strong>:</p>
<blockquote>
<p><code>max = a.inject {|m, e| e.length > m.length ? e : m }</code></p>
</blockquote>
<p><em>(Adicionalmente, hemos usado el operador de asignación condicional «<code>cond ? val1 : val2</code>«, que retorna «<em>val1</em>» si «<em>cond</em>» es verdadero y «<em>val2</em>» en caso contrario.)</em></p>
<h3>Conclusión</h3>
<p>La posibilidad de utilizar clausuras nos acerca a la simplicidad y la expresividad de la programación funcional. Este es uno de los puntos fuertes del lenguaje <strong>Ruby</strong> (y la envidia de otros lenguajes, como <strong>Java</strong>, cuya comunidad <a href="http://barrapunto.com/articles/07/04/25/2026232.shtml">está debatiendo</a> sobre la posibilidad de incorporarlo en la versión 7).</p>
<p><em>(Y sí, se lo que pensará mi amigo Ricardo cuando lea este artículo. Es cierto, <a href="http://kapcoweb.com/p/static/docs/la-venganza-de-los-nerds/la-venganza-de-los-nerds.html">los lenguajes tienden a <strong>Lisp</strong></a>.)</em></p>
<p>Algunas referencias:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">Clausuras en Wikipedia (en inglés).</a></li>
<li><a href="http://www.martinfowler.com/bliki/Closure.html">Más sobre clausuras en <strong>Ruby</strong>.</a></li>
<li><a href="http://ivan.truemesh.com/archives/000392.html">Clausuras en <strong>Python</strong>.</a></li>
<li><a href="http://www.unix.org.ua/orelly/perl/advprog/ch04_03.htm">Clausuras en <strong>Perl</strong>.</a></li>
<li><a href="http://gafter.blogspot.com/2007/01/definition-of-closures.html">Historia de las clausuras.</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.smaldone.com.ar/2007/04/26/el-secreto-de-ruby-las-clausuras/feed/</wfw:commentRss>
			<slash:comments>17</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">110</post-id>	</item>
	</channel>
</rss>
