<?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>Tordek &#187; Programación</title>
	<atom:link href="http://blog.tordek.com.ar/category/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tordek.com.ar</link>
	<description>Linux, Programación, Diseño Web, y todo lo bueno de la Internet.</description>
	<lastBuildDate>Mon, 19 Oct 2009 00:53:13 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Eso no es POO. Es CACA.</title>
		<link>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/</link>
		<comments>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 22:51:40 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[orientación a objetos]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[Programación orientada a objetos]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/</guid>
		<description><![CDATA[Aparentemente, programar usando un diseño orientado a objetos significa hacer un dibujito UML, decirle a nuestro IDE que cree un montón de atributos (obviamente todos privados; no querríamos romper el encapsulamiento), y luego generar todos los accesores y mutadores, no vaya a ser que después no podamos cambiar algo. Al final, terminamos con una clase [...]]]></description>
			<content:encoded><![CDATA[<p>Aparentemente, programar usando un diseño orientado a objetos significa hacer un dibujito UML, decirle a nuestro IDE que cree un montón de atributos (obviamente todos privados; no querríamos romper el encapsulamiento), y luego generar todos los accesores y mutadores, no vaya a ser que después no podamos cambiar algo.</p>
<p>Al final, terminamos con una clase Persona, a la que cualquiera le puede decir que se cambie el nombre, el DNI, y cualquier cosa que le corresponda.</p>
<p>Eh, no.</p>
<p>Preguntémosle a Alan Kay, a Barbara Liskov, a Bjarne Stroustrup&#8230; y tantos otros, y creo que lo primero que nos van a decir es &#8220;Eso no es una clase; es una estructura&#8221;, y &#8220;¿No se suponía que ibas a encapsular los atributos?&#8221;&#8230;</p>
<p>A una interfaz siempre se puede agregar más métodos, sin romper nada, pero si borramos el más inútil de nuestros métodos, siempre va a haber alguien que estaba usándolo. Por eso el primer paso a un buen diseño es «<strong>No agregar accesores hasta que se demuestre útil. No agregar mutadores hasta que sea totalmente necesario.</strong>».</p>
<p>Ah, y, de paso: Las <em>Properties</em><sup class='footnote'><a href='#fn-304-1' id='fnref-304-1'>1</a></sup> no son más que accesores y mutadores disfrazados.</p>
<h3><i>Tell, Don&#8217;t Ask</i></h3>
<p>Traduciendo libremente de <a href="http://www.ccs.neu.edu/research/demeter/related-work/pragmatic-programmer/jan_03_enbug.pdf">The Art of Enbugging</a>, &#8220;Supongamos que el diariero viene a la puerta a cobrar lo que le debés de la semana. Te das vuelta, y él saca tu billetera de tu bolsillo, toma dos dólares, y te la devuelve. En vez de eso, el diariero debería pedirle al cliente que le pague los $2,00.&#8221;.</p>
<p>Para ponerlo en código (porque sí):</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">Diariero<span style="color: #008080;">::</span><span style="color: #007788;">Cobrar</span><span style="color: #008000;">&#40;</span>Cliente<span style="color: #000040;">*</span> cliente, <span style="color: #0000ff;">int</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">throw</span> <span style="color: #008000;">&#40;</span>EsUnRataException<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Billetera<span style="color: #000040;">*</span> billetera <span style="color: #000080;">=</span> Cliente<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getBilletera<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>billetera<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>contenido<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        cliente<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setBilletera<span style="color: #008000;">&#40;</span>billetera<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">throw</span> EsUnRataException<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    billetera.<span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span>cantidad<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    Cliente.<span style="color: #007788;">setBilletera</span><span style="color: #008000;">&#40;</span>billetera<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>vs.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">Diariero<span style="color: #008080;">::</span><span style="color: #007788;">Cobrar</span><span style="color: #008000;">&#40;</span>Cliente<span style="color: #000040;">&amp;</span> cliente, <span style="color: #0000ff;">int</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">throw</span> <span style="color: #008000;">&#40;</span>DineroInsuficienteException<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Cliente.<span style="color: #007788;">cobrar</span><span style="color: #008000;">&#40;</span>cantidad<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Y el primero probablemente necesite revisar si el cliente tiene una billetera, ver si usa monedero o nada, cosa que nos obliga a agregar varios if donde podríamos haber usado polimorfismo.</p>
<h3>¿Y mis porotos?</h3>
<p>Los <em>Beans</em> (Objetos con accesores y mutadores para cada atributo, más un constructor sin parámetros) parecen ser la necesidad básica del programador de Java moderno (?). Todo tiene que ser un bean, si vamos a usar <a href="www.hibernate.org">Hibernate</a>, JPA o &lt;inserte sigla de moda&gt;.</p>
<p>Para muchos, eso es todo lo que se necesita para decidir que todos los mutadores deben ser públicos: ¡Si no no puedo usar Hibernate!&#8230; pero no. Hibernate pide que existan, pero no necesariamente que sean públicos: si son protegidos, es más que suficiente.</p>
<h3>Of course&#8230;</h3>
<p>Por supuesto, hay lugares donde los accesores son útiles, y mucho mejores que un constructor repleto de parámetros. Para los que no me crean, revisen la API de Windows:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">m_hWindow <span style="color: #000080;">=</span>
    <span style="color: #008080;">::</span><span style="color: #007788;">CreateWindow</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span>,          <span style="color: #ff0000; font-style: italic;">/* class name */</span>
                   m_pszTitle,           <span style="color: #ff0000; font-style: italic;">/* title to window */</span>
                   WS_OVERLAPPEDWINDOW,  <span style="color: #ff0000; font-style: italic;">/* style */</span>
                   CW_USEDEFAULT,        <span style="color: #ff0000; font-style: italic;">/* start pos x */</span>
                   CW_USEDEFAULT,        <span style="color: #ff0000; font-style: italic;">/* start pos y */</span>
                   m_nWidth,             <span style="color: #ff0000; font-style: italic;">/* width */</span>
                   m_nHeight,            <span style="color: #ff0000; font-style: italic;">/* height */</span>
                   <span style="color: #0000ff;">NULL</span>,                 <span style="color: #ff0000; font-style: italic;">/* parent HWND */</span>
                   <span style="color: #0000ff;">NULL</span>,                 <span style="color: #ff0000; font-style: italic;">/* menu HANDLE */</span>
                   hInstance,            <span style="color: #ff0000; font-style: italic;">/* */</span>
                   <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>                <span style="color: #ff0000; font-style: italic;">/* creatstruct param */</span></pre></div></div>

<p>Todos los <code>NULL</code> y <code>CW_USEDEFAULT</code> podrían haber sido valores por defecto. <cite>The Little Manual of API Design</cite>, de los creadores de QT, ofrece una alternativa, más similar a la que se usa en QT4:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">window <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Window<span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setClassName<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setWindowTitle<span style="color: #008000;">&#40;</span>winTitle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setStyle<span style="color: #008000;">&#40;</span>Window<span style="color: #008080;">::</span><span style="color: #007788;">Overlapped</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setSize<span style="color: #008000;">&#40;</span>width, height<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setModuleHandle<span style="color: #008000;">&#40;</span>moduleHandle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Una opción indiscutiblemente mejor: Ocupa menos líneas, y no involucra memorizar el orden arbitrario de los 11 parámetros del constructor anterior. Podría parecer más larga de escribir, por todos los &#8220;window&#8221; que se repiten, pero podría reducirse aún más si la API<sup class='footnote'><a href='#fn-304-2' id='fnref-304-2'>2</a></sup> soporta un estilo más <a href="http://en.wikipedia.org/wiki/Fluent_interface">fluido</a> (cada método retorna <code>this</code>), permitiendo algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">window <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Window<span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setClassName<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setWindowTitle<span style="color: #008000;">&#40;</span>winTitle<span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setStyle<span style="color: #008000;">&#40;</span>Window<span style="color: #008080;">::</span><span style="color: #007788;">Overlapped</span><span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setSize<span style="color: #008000;">&#40;</span>width, height<span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setModuleHandle<span style="color: #008000;">&#40;</span>moduleHandle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>&#8230;de lo cual más de un smalltalker se reirá.</p>
<h3>Colecciones</h3>
<p>Un lugar donde se nota obviamente la bestialidad de los accesores y mutadores es cuando hay colecciones de por medio. Primero, porque exponer una colección elimina cualquier posibilidad de concurrencia: Si dos métodos quieren modificarla, el único resultado va a ser un bug.</p>
<p>Además, se expone el tipo interno de la colección, removiendo otra de las características de la orientación a objetos: la implementación tiene libertad sobre la interfaz.</p>
<p>Acá hay que aplicar uno de los refactoreos de Fowler (y esto ya debería llegar a volverse regla natural): <a href="http://www.refactoring.com/catalog/encapsulateCollection.html">Encapsulate collection</a>. Es simple: Primero, matamos el setter. No cumple ninguna función útil. Nos aseguramos, además, de que en el constructor se cree la colección. Después procedemos a liberar la responsabilidad de la colección: El getter retorna una copia inmutable. Y, finalmente, agregamos métodos que se encarguen de agregar o remover objetos de la colección.</p>
<p><em lang="fr_FR">Voilá</em>: Nuestro objeto está un paso más cerca de ser, bueno, orientado a objetos.</p>
<h3>Ley Anti-mutantes</h3>
<p>Le debo una a William Stryker.</p>
<p>Una vez, discutiendo sobre OO con un amigo, le dije que todo debería ser inmutable, excepto en raros casos. Me dijo «¡Pero el chiste de la Orientación a Objetos es la mutabilidad del estado!».</p>
<p>Bueno, sí y no.</p>
<p>Más vale no.</p>
<p>Siguiendo con las colecciones, algunas son más críticas que otras. Si sólo tenemos un array de objetos, no importa que cualquiera de sus valores cambie. Ahora, si tenemos una <em>hashtable</em>, más vale que el hash nunca cambie, o van a pasar cosas muy malas.</p>
<p>Cualquier valor del que dependa <code>hashCode</code> (en Java) <strong>tiene</strong> que ser inmutable. Si no, estaríamos violando el contrato, y sufriremos mil y un bugs sutiles.</p>
<h3>¡Bueno, basta, prometo no hacerlo más, pero dejá de escribir!</h3>
<p>No todos los atributos de un objeto merecen un getter: Por cada getter exponemos implementación.</p>
<p>Muy pocos atributos merecen un setter: Si tiene que cambiar, que lo haga el objeto sólo.</p>
<p>Las interfaces deben revelar lo menos posible: No digas <code>HashSet</code> donde podés decir <code>Collection</code>.</p>
<p>Encapsulá tus colecciones.</p>
<p>El primer paso a una buena orientación a objetos es la paranoia.</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-304-1'>que admito amar <span class='footnotereverse'><a href='#fnref-304-1'>&#8617;</a></span></li>
<li id='fn-304-2'>O el lenguaje, con un constructo <code>with</code> o similar <span class='footnotereverse'><a href='#fnref-304-2'>&#8617;</a></span></li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Listas vs. Tuplas</title>
		<link>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/</link>
		<comments>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 04:15:02 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Rol]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/</guid>
		<description><![CDATA[En la lista de PyAr hace no mucho alguien preguntó, «¿Cuál es la diferencia entre una tupla y una lista?». Acá hago una síntesis de las respuestas, y agrego mis notas. Esta duda surge en Python porque, a primera vista, la única diferencia es que una usa corchetes, y la otra paréntesis: No importa si [...]]]></description>
			<content:encoded><![CDATA[<p>En la lista de PyAr hace no mucho alguien preguntó, «¿Cuál es la diferencia entre una tupla y una lista?». Acá hago una síntesis de las respuestas, y agrego mis notas.</p>
<p>Esta duda surge en Python porque, a primera vista, la única diferencia es que una usa corchetes, y la otra paréntesis: No importa si tengo una lista o una tupla, puedo acceder a sus elementos con <code>[<var>indice</var>]</code>, y con cualquiera puedo hacer asignación múltiple (<code>a, b = [1, 2]</code>)&#8230;</p>
<p>Lentamente las diferencias empiezan a aparecer:</p>
<ul>
<li><strong>Las tuplas, como los strings, son inmutables</strong>: Una vez que una tupla tiene un valor, no se puede cambiar, sólo crear una nueva.</li>
<li>Debido a lo anterior, <strong>las tuplas son <em>hasheables</em></strong>: Se puede crear un diccionario que use como índice tuplas&#8212;pero nunca listas.</li>
</ul>
<p>Estas diferencias técnicas son las más importantes, y las que justamente las definen.</p>
<p>Ahora, ¿Cuándo es mejor cada una?&#8230; En muchos casos realmente no hay diferencia: Si a cualquiera de las dos puedo acceder por índice, o con for&#8230; Pero podemos tomar una pista de un lenguaje más estricto: Haskell.</p>
<p>En Haskell, una tupla de 2 elementos es de un tipo diferente al de una de 3 (y no se las puede acceder por índice). Además, las tuplas pueden ser heterogéneas, mientras que las listas son homogéneas. Eso es, puedo tener una tupla (int, String, String), pero una lista puede contener sólo un tipo de datos (Claro, ese tipo puede ser una tupla&#8230; pero divago).</p>
<p>Entonces, lo «correcto» (con comillas) es que, si a todos los elementos se los va a tratar de una misma forma (sea con un for, o con map), usamos una lista, pero si cada elemento tiene un significado diferente, lo mejor es una tupla.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Chiste pésimo</title>
		<link>http://blog.tordek.com.ar/2009/03/chiste-pesimo/</link>
		<comments>http://blog.tordek.com.ar/2009/03/chiste-pesimo/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 13:14:22 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Tordek]]></category>
		<category><![CDATA[baltha]]></category>
		<category><![CDATA[chiste]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[malo]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=296</guid>
		<description><![CDATA[Tordek: Y a ver cuando aprendes Lisp vos, ¿eh? Baltha: ¡Ya se la mitad de Lisp, ¿sabés? ¡¿Sabés?! Tordek: ¿Qué, sabés &#8216;(&#8216;?]]></description>
			<content:encoded><![CDATA[<ul>
<li><strong>Tordek</strong>: Y a ver cuando aprendes Lisp vos, ¿eh?</li>
<li><strong>Baltha</strong>: ¡Ya se la mitad de Lisp, ¿sabés? ¡¿Sabés?!</li>
<li><strong>Tordek</strong>: ¿Qué, sabés &#8216;(&#8216;?</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/03/chiste-pesimo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Do what you mean. Do what I mean.</title>
		<link>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/</link>
		<comments>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 21:27:42 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[confirmacion]]></category>
		<category><![CDATA[deshacer]]></category>
		<category><![CDATA[undo]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/</guid>
		<description><![CDATA[El diálogo de &#8220;¿Estás seguro?&#8221; es total y absolutamente inutil. Estuve discutiendo con un amigo, que dice que no es así, pero la única conclusión que tengo es: Si necesitás ese diálogo, tu sistema está mal diseñado. &#8212;Pero, &#8212;algunos se quejarán&#8212; ¿y si me equivoqué? ¿Y si después de que lo hice me dí cuenta [...]]]></description>
			<content:encoded><![CDATA[<p>El diálogo de &#8220;¿Estás seguro?&#8221; es total y absolutamente inutil. Estuve discutiendo con un amigo, que dice que no es así, pero la única conclusión que tengo es: Si necesitás ese diálogo, tu sistema está mal diseñado.</p>
<p>&#8212;Pero, &#8212;algunos se quejarán&#8212; ¿y si me equivoqué? ¿Y si después de que lo hice me dí cuenta que no lo quería?</p>
<p>Bien, primero: Si te diste cuenta después, el botón de &#8220;estás seguro&#8221; no te salva. Obviamente, la opción no es &#8220;Ja, lástima, para qué hacés click ahí&#8221;. Existe una que sirve de verdad, y que hace mucho nos dimos cuenta que se puede: Deshacer.</p>
<p>Si en Windows se me ocurre borrar un archivo, va a la papelera. Si me equivoqué, lo recupero. Si en Thunderbird borro un mensaje, está en la basura.</p>
<p>Aparte, ¿para qué cambiar el significado de las cosas? Tengo un botón borrar. ¿Qué hace ese botón? ¿Borra? No. Me muestra una ventana que me pregunta &#8220;¿Estás seguro?&#8221;, y al hacer click en &#8220;Sí&#8221;, recién borra. ¿Desde cuando &#8220;Borrar&#8221; significa &#8220;Preguntame si quiero borrar&#8221;, y &#8220;Sí&#8221; significa borrar?</p>
<p>Y es imposible quejarse acerca de implementarlo. Si nuestra aplicación usa alguna forma de base de datos, tenemos una marca de &#8220;Borrado&#8221;. Si usa el sistema de archivos, una carpeta donde almacenamos los archivos &#8216;Borrados&#8217;.</p>
<p><a href="http://msdn.microsoft.com/en-us/magazine/cc163835.aspx">Confirmar es inutil, Deshacer es divino</a>, o como quieras ponerlo, basta de preguntas, y hacé lo que dije.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Vimpress; un buen editor en WordPress</title>
		<link>http://blog.tordek.com.ar/2008/11/vimpress-un-buen-editor-en-wordpress/</link>
		<comments>http://blog.tordek.com.ar/2008/11/vimpress-un-buen-editor-en-wordpress/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 17:49:06 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Meta]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2008/11/vimpress-un-buen-editor-en-wordpress/</guid>
		<description><![CDATA[Interesante plugin para vim1. Con sólo un par de comandos, :BlogNew y :BlogSend, puedo editar un nuevo post en vim, y publicarlo directamente en mi blog. Se lo pueden bajar de la página de su autor, y, como todo plugin de vim, lo único que tienen que hacer es descomprimirlo en su .vim/plugins. No tiene [...]]]></description>
			<content:encoded><![CDATA[<p>Interesante plugin para vim<sup class='footnote'><a href='#fn-238-1' id='fnref-238-1'>1</a></sup>. Con sólo un par de comandos, <code>:BlogNew</code> y <code>:BlogSend</code>, puedo editar un nuevo post en vim, y publicarlo directamente en mi blog.</p>
<p>Se lo pueden bajar de <a href="http://friggeri.net/blog/2007/07/13/vimpress">la página de su autor</a>, y, como todo plugin de vim, lo único que tienen que hacer es descomprimirlo en su <tt>.vim/plugins</tt>.</p>
<p>No tiene muchos comandos, pero tampoco los necesita:</p>
<ul>
<li><code>:BlogList</code> para ver la lista de todos los posts;</li>
<li><code>:BlogNew</code> para crear uno nuevo;</li>
<li><code>:BlogOpen <var>id</var></code> para editar uno; y</li>
<li><code>:BlogSend</code> para, finalmente, publicar&#8230;</li>
</ul>
<p>Veamos qué tal&#8230;.</p>
<p><strong>Edit:</strong></p>
<p>Hasta ahora, me gusta; en particular porque me molestan los <acronym class="uttAcronym" title="What You See Is What You Get">WYSIWYG</acronym> porque lo que ves no se parece en nada a lo que sale (Y no te dan la mitad de los tags&#8230; a menos que uses el editor <a href="http://www.w3.org/MarkUp/" class="ubernym uttInitialism"><abbr class="uttInitialism" title="HyperText Markup Language">HTML</abbr></a>, sacándole todo el chiste.)</p>
<p>Ah, y se banca categorías, tags, y varias otras cosas (aunque no me deja editar el texto del permalink).</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-238-1'>El único editor que vale la pena&#8230; Morite, emacs. <span class='footnotereverse'><a href='#fnref-238-1'>&#8617;</a></span></li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/11/vimpress-un-buen-editor-en-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Oops&#8230;</title>
		<link>http://blog.tordek.com.ar/2008/11/oops/</link>
		<comments>http://blog.tordek.com.ar/2008/11/oops/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 22:42:59 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Cualquiera]]></category>
		<category><![CDATA[Meta]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Tordek]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[noob]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=234</guid>
		<description><![CDATA[Eh, no, el blog no estuvo caido; sólo que cuando lo actualicé me olvidé de copiar mi .htaccess&#8230; Ceceo ya es un poquito más lindo; sólo estás a una bajada y un make de distancia de poder hacer, simplemente '(a b c) =&#62; (a b c). No es la gran cosa, pero es un Lisp&#8230; [...]]]></description>
			<content:encoded><![CDATA[<p>Eh, no, el blog no estuvo caido; sólo que cuando lo actualicé me olvidé de copiar mi .htaccess&#8230;</p>
<p><a href="http://blog.tordek.com.ar/2008/10/ceceo-01%CE%B1-released/">Ceceo</a> ya es un poquito más lindo; sólo estás a una bajada y un make de distancia de poder hacer, simplemente <code>'(a b c) =&gt; (a b c)</code>.</p>
<p>No es la gran cosa, pero es un Lisp&#8230;</p>
<p>Y mi problema con <strong>bison</strong> eran los malditos strings de C; estaba guardadando el puntero al string, en vez de una copia. Ahora sí.</p>
<p>Bueno, sigue sin tener un recolector de basura, pero qué se le va a hacer.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/11/oops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ceceo 0.1α released</title>
		<link>http://blog.tordek.com.ar/2008/10/ceceo-01%ce%b1-released/</link>
		<comments>http://blog.tordek.com.ar/2008/10/ceceo-01%ce%b1-released/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 21:44:28 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[lisp]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=231</guid>
		<description><![CDATA[Así como lo molesté a Juanjo Conti por un par de cosas que no andaban de su Lisp, me puse a hacer uno yo. Implementa sólo las raíces de lisp; las 7 primitivas básicas y las 6 funciones derivadas de estas &#8212;aunque, la verdad, no las uso&#8230;&#8212;, según detalla The Roots of Lisp. En el [...]]]></description>
			<content:encoded><![CDATA[<p>Así como lo molesté a Juanjo Conti por un par de cosas que no andaban de su Lisp, me puse a hacer uno yo.</p>
<p>Implementa sólo las raíces de lisp; las 7 primitivas básicas y las 6 funciones derivadas de estas &#8212;aunque, la verdad, no las uso&#8230;&#8212;, según detalla <a href="http://lib.store.yahoo.net/lib/paulgraham/jmc.ps">The Roots of Lisp</a>.</p>
<p>En el proceso aprendí varias cosas:</p>
<ol>
<li>Bison me odia<sup class='footnote'><a href='#fn-231-1' id='fnref-231-1'>1</a></sup>.</li>
<li>Las <code>union</code>s sirven para algo.</li>
<li>LISP es todavía más groso que lo que imaginaba.</li>
<li>([a-z]|micro|pico|femto|atto)lisp ya existe.</li>
</ol>
<p>Bien, le falta mucho para estar completo; en particular, le falta la parte interactiva; por ahora es sólo un lisp-en-c; si se quiere hacer, digamos, <code>(quote a)</code> (y evaluarlo, claro), hay que hacer <code>eval(cons(symbol("quote"),cons(symbol("a"),symbol("nil"))))</code>&#8230;</p>
<p>Por esto, tampoco probé si lambda hace lo que debe y demás.</p>
<p>No tiene ningún tipo de números, porque tenía planeados ponerlos cuando haga funcionar el <em>REPL</em>.</p>
<p>Y finalmente, no hay recolector de basura&#8230;</p>
<p>Si alguien, por algún bizarro motivo, tiene ganas de usar el código, está en <a href="http://tordek.com.ar/labs/ceceo/">una de mis páginas secretas</a>, liberado bajo la licencia BSD.</p>
<p>¿Será este el comienzo de una nueva era? ¿Una donde empiece a liberar código?&#8230; sólo el tiempo lo dirá.</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-231-1'>¿Alguien se anima a tirarme una mano? <span class='footnotereverse'><a href='#fnref-231-1'>&#8617;</a></span></li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/10/ceceo-01%ce%b1-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lo siento&#8230;</title>
		<link>http://blog.tordek.com.ar/2008/10/lo-siento/</link>
		<comments>http://blog.tordek.com.ar/2008/10/lo-siento/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 18:43:03 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Cualquiera]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Tordek]]></category>
		<category><![CDATA[oh no]]></category>
		<category><![CDATA[suicido]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=229</guid>
		<description><![CDATA[Amigos&#8230; Programadores&#8230; Desarrolladores&#8230; Lo lamento&#8230; en serio&#8230; no merezco ningún tipo de respeto. Deberían revocarme la membresía del club&#8230; Estoy en un estado de pecado: Me aburro y no tengo ningún proyecto personal para trabajar. Me siento sucio.]]></description>
			<content:encoded><![CDATA[<p>Amigos&#8230; Programadores&#8230; Desarrolladores&#8230;</p>
<p>Lo lamento&#8230; en serio&#8230; no merezco ningún tipo de respeto. Deberían revocarme la membresía del club&#8230;</p>
<p>Estoy en un estado de pecado: Me aburro y no tengo ningún proyecto personal para trabajar.</p>
<p>Me siento sucio.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/10/lo-siento/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Socializando</title>
		<link>http://blog.tordek.com.ar/2008/10/socializando/</link>
		<comments>http://blog.tordek.com.ar/2008/10/socializando/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 15:07:11 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[comunicacion]]></category>
		<category><![CDATA[foro]]></category>
		<category><![CDATA[social]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=227</guid>
		<description><![CDATA[Una pregunta para todo el que lea mi blog o el feed de codear: ¿Qué listas de correo, foros, canales de chat y demás suelen visitar para discutir de programación? Tanto general como de lenguajes y tecnologías particulares.]]></description>
			<content:encoded><![CDATA[<p>Una pregunta para todo el que lea mi blog o el feed de codear:</p>
<p>¿Qué listas de correo, foros, canales de chat y demás suelen visitar para discutir de programación?</p>
<p>Tanto general como de lenguajes y tecnologías particulares.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/10/socializando/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>No molestes al usuario</title>
		<link>http://blog.tordek.com.ar/2008/09/no-molestes-al-usuario/</link>
		<comments>http://blog.tordek.com.ar/2008/09/no-molestes-al-usuario/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 22:40:47 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[interfaz]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=213</guid>
		<description><![CDATA[Tu programa puede hacer maravillas y ahorrar miles de horas y pesos cada vez que lo usas. Pero esa no es razón para molestar al usuario. Además, si tu propósito es ahorrar tiempo, ¿por qué gastarlo obligándolo a hacer cosas innecesarias? El tipo de interfaz no importa No importa si es una línea de comandos, [...]]]></description>
			<content:encoded><![CDATA[<p>Tu programa puede hacer maravillas y ahorrar miles de horas y pesos cada vez que lo usas.</p>
<p>Pero esa no es razón para molestar al usuario. Además, si tu propósito es ahorrar tiempo, ¿por qué gastarlo obligándolo a hacer cosas innecesarias?</p>
<h3>El tipo de interfaz no importa</h3>
<p>No importa si es una línea de comandos, ventanas múltiples, juegos, si usa el teclado, el mouse, un joystick, o cualquier otra cosa; el usuario es el que importa, no tu programa.</p>
<p>A lo mejor a vos te tome media hora más agregar el código para auto-configurar el programa al instalarse, pero ahorrar un minuto a cien usuarios es todavía más tiempo.</p>
<h3>Una regla importante<a href="http://www.catb.org/~esr/writings/taoup/"><br />
</a></h3>
<p><a href="http://www.catb.org/~esr/writings/taoup/">The Art of Unix Programming</a>, de Eric Raymond, nos cuenta la historia de Unix, y las características de sus programas, interfaces, y qué es lo que lo hace bueno &#8212;y malo&#8212; para programar. De ésto robo una regla relacionada a la interfaz:</p>
<p>La Regla de Silencio: Si un programa no tiene nada sorprendente que decir, no debe decir nada.</p>
<p>No me avises que abriste el archivo; no me digas que todo fué bien &#8212;o, al menos, no me molestes si lo hacés. Una caja de mensajes modal<sup class='footnote'><a href='#fn-213-1' id='fnref-213-1'>1</a></sup> diciendo &#8220;Archivo abierto correctamente [OK]&#8221; es una pérdida de tiempo y nada más. Si tenés que avisarme, al menos no interfieras. Por ejemplo, el diálogo de &#8220;Guardar Contraseña&#8221; de Firefox 3, que no interfiere con el flujo.</p>
<h3>Cuando dudes, copia</h3>
<p>A todos nos gusta ser únicos y originales, pero si diseñamos nuestro programa de manera que el usuario sienta que ya lo usó antes, no va a sentirse intimidado diciendo que es difícil de usar.</p>
<p>Si ya hay un programa que hace lo que vos querés, considerá robar su apariencia (Firefox, con ciertas excepciones, es igual a Internet Explorer). Claro, hay excepciones; DarkRoom, por ejemplo prácticamente elimina la interfaz, sacando del medio cualquier tipo de botón y menú, y sólo las opciones de abrir, guardar, y crear un nuevo archivo&#8230; pero DarkRoom tiene una razón para hacerlo.</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-213-1'>O sea, una que no deja hacer nada hasta que se le hace click <span class='footnotereverse'><a href='#fnref-213-1'>&#8617;</a></span></li>
</ol>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/09/no-molestes-al-usuario/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.449 seconds -->
