<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>David Capello's Blog</title>
 <link href="https://davidcapello.com/atom.xml" rel="self"/>
 <link href="https://davidcapello.com"/>
 <updated>2024-12-21T15:27:18+00:00</updated>
 <id>https://davidcapello.com</id>
 <author>
   <name>David Capello</name>
   <email>david@igara.com</email>
 </author>

 
 <entry>
   <title>The Dumpster Diving Era of Tech</title>
   <link href="https://davidcapello.com/blog/ideas/the-dumpster-diving-era-of-tech/"/>
   <updated>2024-12-21T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/the-dumpster-diving-era-of-tech</id>
   <content type="html">&lt;p&gt;This year is ending and I was thinking of writing something
thoughtful, something about how the world is going down the drain,
with some kind of wishful conclusion. But I’m not in the mood.&lt;/p&gt;

&lt;p&gt;The only thing I can think of is how technology is entering in a kind
of dumpster diving era. Where everything is considered trash, your
creations, your own pictures, your face, your retina, or even your
medical record, and they can be taken without any cost, to bring the
most outrageous tampered reality.&lt;/p&gt;

&lt;p&gt;There is no shame in anonymity. But now big tech companies have no
anonymity, and no mortification either. It looks like being a public
shameless figure (or company) is the standard.  At least real dumpster
diving has the dignity of being done for survival. For these
companies: we are the trash.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Data-Driven Mistakes</title>
   <link href="https://davidcapello.com/blog/dev/data-driven-mistakes/"/>
   <updated>2023-06-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/data-driven-mistakes</id>
   <content type="html">&lt;p&gt;Several years ago, I remember reading about data-driven design. How big
companies (Google mainly?) were using data-driven approaches to
design and evolve their UI. In those years &lt;a href=&quot;/blog/dev/improving-your-applications-by-statistics/&quot;&gt;I thought about that like
a great idea&lt;/a&gt;
to know how the UI was being used. But later, in the last few years,
I completely dismissed that approach.&lt;/p&gt;

&lt;p&gt;It’s a little crazy to drive your design-decision from just some stats:&lt;/p&gt;

&lt;p&gt;— How many clicks did this menu item receive? &lt;br /&gt;
— Only a couple from hundreds of users. &lt;br /&gt;
— Hmm, we might remove the item, or send it to a deeper menu level.&lt;/p&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;p&gt;— This is the most used action from the whole program. &lt;br /&gt;
— Hmm, I think we should make its button bigger. &lt;br /&gt;
— It’s already half the screen… &lt;br /&gt;
— It should be as big as the screen, probably the only button in the
whole program.&lt;/p&gt;

&lt;p&gt;These are totally exaggerated characterizations, but they are a good
example about what you can achieve doing data-driven design: &lt;em&gt;You are
going to make the problems of your UI just worse.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The data/stats you can receive from the UI are already defined by the
initial design of the UI itself. You are going to receive just data
about the current design, it’ll tell you absolutely nothing about how
to evolve the UI, or what is failing, or not being used because it’s
not accessible enough.&lt;/p&gt;

&lt;p&gt;The only data you should be listening to are &lt;em&gt;your users.&lt;/em&gt; The direct
feedback you are getting from them: emails, messages, issues, error
reports, etc. That is the most important &lt;em&gt;data&lt;/em&gt; that matters in your
design decisions.&lt;/p&gt;

&lt;p&gt;Ask your users.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Floppy Disk</title>
   <link href="https://davidcapello.com/blog/ideas/floppy-disk/"/>
   <updated>2023-03-12T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/floppy-disk</id>
   <content type="html">&lt;p&gt;En la película The Matrix existen esos discos de entrenamiento que le
ofrecen a uno todo el &lt;em&gt;know-how&lt;/em&gt; sobre una determinada área del
conocimiento humano:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/w_8NsPQBdV0&quot; title=&quot;The Matrix movie - Training Disk scenes&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Un poco de eso ya ocurre hoy en día con YouTube: uno graba un video,
lo sube, para que luego una “inteligencia” artificial lo
utilice para aprender —por ejemplo— &lt;a href=&quot;https://www.youtube.com/watch?v=i1GVwbYURuQ&quot;&gt;a cocinar un bife&lt;/a&gt;,
y así nos reemplace.&lt;/p&gt;

&lt;p&gt;Siempre “el futuro” se vendió como una imagen donde tendríamos que
dedicarnos menos tiempo al trabajo y más tiempo al ocio, a leer, al
arte, a crear y hacer cosas que nos conmuevan. Pero parece ser que el
futuro llegó como un balde de agua fría —o
&lt;a href=&quot;https://elpais.com/argentina/2023-03-08/argentina-registra-el-verano-mas-caluroso-de-su-historia.html&quot;&gt;caliente&lt;/a&gt;—:
Ahora tampoco será necesario crear, porque los robots ya pueden
&lt;a href=&quot;https://nypost.com/2023/02/22/sci-fi-magazine-not-accepting-submissions-due-to-bots/&quot;&gt;escribir&lt;/a&gt;
y &lt;a href=&quot;https://www.youtube.com/watch?v=GOwxXj1EIXM&quot;&gt;dibujar&lt;/a&gt;.
Gracias a toda esa hermosa nube de datos
fácilmente &lt;a href=&quot;https://en.wiktionary.org/wiki/crawlable&quot;&gt;crawleable&lt;/a&gt;
—amigable al robo masivo de datos— que es Internet.&lt;/p&gt;

&lt;p&gt;¿Adónde va el ser humano si no tiene qué hacer? ¿Qué pasa si el “arte”
ahora lo “genera” un ordenador? ¿Cómo podremos distinguir lo original
de lo sintético? ¿Quién va a pagar todo lo afanado? ¿Cuáles serán los
incentivos para crear algo en el futuro? ¿Acaso no estamos trabajando
cada vez más y creando cada vez menos? ¿Dónde está ese futuro
liberador? Cuestiones sin responder.&lt;/p&gt;

&lt;p&gt;Silicon Valley, como sinónimo del progreso tecnológico desenfrenado
—más que cómo locación geográfica— es como una patada en los
huevos que primero golpea y luego pide permiso. Ya habrá tiempo de
preguntar, hacer
&lt;a href=&quot;https://hipertextual.com/2023/02/getty-demanda-ia-stable-diffusion-derechos-autor&quot;&gt;juicios&lt;/a&gt;,
y ver quién hizo el bien y quién hizo el mal. Pero el dolor ya lo
empezamos a sentir. ¿Creemos que el humano va a quedar cruzado de
brazos? ¿Sin hacer nada? ¿Que los corazones de millones de artistas
van a dejar de latir, &lt;a href=&quot;/blog/ideas/inteligencia-artificial-2/&quot;&gt;sin ningún deseo&lt;/a&gt;?  ¿Dónde se alojará toda esta
información? ¿Serán servidores infinitos? ¿O será en un simple &lt;em&gt;floppy
disk&lt;/em&gt;? El futuro, aunque &lt;a href=&quot;/blog/ideas/inteligencia-artificial/&quot;&gt;virtual&lt;/a&gt;, también se ve bastante frágil 💾&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Inteligencia Artificial II</title>
   <link href="https://davidcapello.com/blog/ideas/inteligencia-artificial-2/"/>
   <updated>2022-12-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/inteligencia-artificial-2</id>
   <content type="html">&lt;p&gt;Se sabe que Cleopatra (excusen este ejemplo traído de la historia
romana) clavaba agujas de oro en el pecho de sus esclavas y que
disfrutaba enormemente los gritos y contorsiones de las víctimas. Me
dirán que eso ocurría en una época bárbara; que nuestro siglo
también es bárbaro, ya que todavía se clavan alfileres; que el
hombre, aunque tenga ahora una comprensión más clara de las cosas,
no se acostumbra todavía a seguir las reglas de la razón y de la
ciencia. Pero ustedes están convencidos de que el hombre se
acostumbrará con el correr del tiempo, cuando el sentido común y la
ciencia terminen de reeducar completamente la naturaleza humana y la
orienten por un camino normal. Creen que con el tiempo el hombre
dejará de errar y se verá, entonces, en la imposibilidad de oponerse
a sus intereses normales.&lt;/p&gt;

&lt;p&gt;Pero hay más. Entonces (según ustedes) la ciencia hará saber al
hombre (aunque esto sea un lujo superfluo) que no tuvo nunca
voluntad ni caprichos y que es, en definitiva, como una tecla de
piano o un pedal de órgano. De modo que actúa, no de acuerdo a su
voluntad, sino según las leyes de la naturaleza. Bastará, entonces,
descubrir las leyes para que no se pueda considerar al hombre
responsable de sus actos, y entonces la vida será fácil. Con estas
leyes, todas las acciones de los hombres se podrán calcular tan
matemáticamente como los logaritmos, hasta la cienmilésima, y se
harán con ellas libros importantes, como nuestros diccionarios
enciclopédicos, en los que todo estará exactamente calculado y
previsto. Ya no habrá aventuras… y ni siquiera acciones.&lt;/p&gt;

&lt;p&gt;Entonces (creen ustedes) se establecerán novedosas relaciones
económicas, que se fijarán con precisión matemática, de modo que los
problemas desaparecerán enseguida, por la sencilla razón de que se
habrán descubierto las soluciones. Entonces se construirá un hermoso
palacio de cristal. Entonces veremos el Pájaro de Fuego.
Entonces… No se puede garantizar, digo yo, que eso no sea
terriblemente aburrido (¿qué se podrá hacer, si todo está ya
calculado y fijado?). Como contrapartida, todos serán
sabios. Evidentemente, el aburrimiento es un mal consejero: es el
aburrimiento lo que mueve a clavar agujas de oro en los pechos
ajenos… Pero aun esto no tiene demasiada importancia. Lo grave, lo
terrible es, digo, que el hombre se sienta feliz de tener al alcance
de la mano agujas de oro. El hombre es estúpido por naturaleza,
totalmente estúpido. Y es más ingrato que estúpido: es difícil
encontrar otro ser más ingrato que él. Por eso no sería extraño
verlo erguirse de pronto en medio de esa felicidad, un caballero sin
elegancia, de rostro “retrógrado” y burlón, y que dijera: “¡Bueno,
señores! ¿Cuándo vamos a destruir de un solo puntapié toda esta
insoportable felicidad, aunque solo sea para enviar todos los
logaritmos al demonio y poder vivir de nuevo según nuestra estúpida
fantasía?.” Y hay algo peor, y es que muy rápidamente ese personaje
encontraría discípulos. El hombre es así. Y la causa de todo es algo
ínfimo que, a primera vista, se podría pasar por alto. Esa causa es
que el hombre, sea el que sea, aspira siempre a obrar según su
voluntad y no según las prescripciones de la razón y del
interés. Ahora bien, yo creo que la voluntad de uno puede, y a veces
incluso debe, oponerse a sus intereses. Mi voluntad; mi libre
albedrío; mis caprichos, por insensatos que sean; mi imaginación
sobreexcitada hasta la demencia… Esto es lo que no se tiene en
cuenta, este es el precioso interés que ignoran todas esas
clasificaciones de ustedes y que hace estallar todos los sistemas,
todas las teorías.&lt;/p&gt;

&lt;p&gt;¿De dónde sacan nuestros sabios que el hombre necesita una voluntad
normal y virtuosa? ¿Por qué suponen que el hombre quiere ser
razonable? El hombre sólo quiere una voluntad independiente, sin
importar los precios y el resultado. Pero el diablo sabe lo que
cuesta ese deseo…&lt;/p&gt;

&lt;p&gt;— &lt;em&gt;Memorias del Subsuelo, de Fiódor Dostoyevski&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Papá</title>
   <link href="https://davidcapello.com/blog/meta/papa/"/>
   <updated>2022-04-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/papa</id>
   <content type="html">&lt;p&gt;El 14 de noviembre del 2020 falleció mi padre y hoy cumpliría
años. Teníamos una relación de amistad, aunque a la distancia por
vivir en ciudades distintas. Desde su partida que quiero escribir
algo, pero siento que cualquier cosa que diga queda chica para el
desborde de palabras que él representaba. Diré poco, y guardo el resto
para mí.&lt;/p&gt;

&lt;p&gt;Era un delirante, dentro de ciertos límites, pero sólo él conocía esos
límites. Uno nunca sabía qué esperar, ni en lo bueno ni en lo
malo. Verborrágico, y no por nada se dedicaba a las ventas. Una vez lo
ví dormirse mientras hablaba. Podría haber sido periodista deportivo
–le gustaban los autos y las carreras, los veleros y las regatas– o
conductor de radio –tenía un gusto especial por la buena música.
También le gustaba el arte, desde el Renacimiento a las tiras de
cómics.&lt;/p&gt;

&lt;p&gt;Un poco incomprendido. Con mucho para compartir y poco para escuchar.
Enviaba mensajes todos los días, o cada dos o tres días –o dos o tres
por día–. A cualquier horario. Nunca le apasionaron las computadoras,
ni a mí los autos, y aún así podíamos hablar de todo un poco –o de
todo un mucho–. Siempre abierto a nuevas ideas y con buen humor a
pesar de cualquier circunstancia.&lt;/p&gt;

&lt;p&gt;Lamentaré toda la vida no haber estado con él en sus últimos días, la
forma en que –no– nos despedimos, no poder saludarlo ni ayudarlo. No
poder compartir más tiempo juntos. Como él solía decir –con mejores
palabras de las que puedo recordar– el tiempo es lo más valioso para
regalarle a las personas, cada vez que esto ocurra disfrutalo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tierra Surreal</title>
   <link href="https://davidcapello.com/blog/scifi/tierra-surreal/"/>
   <updated>2020-10-15T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/scifi/tierra-surreal</id>
   <content type="html">&lt;p&gt;Allá a lo lejos va el berenjeno triste enterándose de que su
representante miente. Será la hierba transatlántica que hace sombra a
los chamanes de tu pueblo. O los biseles que no dejan erguirme. Me has
generado una lumbalgia cerebral, que deja mirar sólo cerca de la más
antigüa cicatriz.&lt;/p&gt;

&lt;p&gt;Ahora estoy en mi invernadero marciano, dejando sala al nuevo tratado.
La paz intergaláctica es un hecho sólo por tiempos. Las bombas de
relojería se aburren en el espacio. Solté mi paloma a tu planeta,
volvió mutante con un aceituno rancio. Sé que todavía no están listos
para tanta fertilidad. No den a luz a un Cronos matricida.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Consejos para Diseñar Clases (en realidad Software)</title>
   <link href="https://davidcapello.com/blog/programacion/consejos-para-diseniar-software/"/>
   <updated>2020-10-12T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/programacion/consejos-para-diseniar-software</id>
   <content type="html">&lt;p&gt;Gracias a una pregunta que me hicieron hoy sobre algunos consejos para
diseñar clases, escribo este pequeño artículo sobre mi enfoque
personal hacia el desarrollo de software, y sobre las clases en
particular:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Crear un programa no se trata de crear clases, sino sólo de
resolver un problema.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Un programa son instrucciones de código que manejan/transforman
datos, y esto es siempre así, sin excepción.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Los datos son memoria en el disco o la memoria RAM, y pueden
“estructurarse” con un simple un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;. Ejemplo:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Jugador {
  char nombre[256];   //&amp;lt; Los primeros 256 bytes representan el nombre del jugador
  uint32_t puntaje;   //&amp;lt; Luego un entero de 4 bytes representan el puntaje del jugador
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;El código que maneja los datos puede estar ubicado en cualquier
lugar, pero existe una relación directa entre ese código y los
datos que manipulan.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Por lo tanto siempre vamos a preferir tener el código cercanos
a esos datos que manipula (en el mismo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cpp&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.h&lt;/code&gt;, o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.java&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csharp&lt;/code&gt;, etc.).
Ejemplo:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Jugador { ... };

Jugador* crear_jugador(const char* nombre);
void destruir_jugador(Jugador* jugador);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Si comenzamos a manipular los datos en cualquier lugar de nuestro
programa comenzaremos a tener problemas a futuro para cualquier
modificación que queramos hacer. &lt;strong&gt;Mal ejemplo&lt;/strong&gt;:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int main() {
  Jugador* j = crear_jugador();
  memcpy(j-&amp;gt;nombre, &quot;David\0&quot;, 6);   //&amp;lt; Código que accede a la estructura interna del Jugador
  destruir_jugador(j);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Luego al querer cambiar la estructura de nuestros datos:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Jugador {
  string nombre;     //&amp;lt; Ahora el nombre es un std::string
  uint32_t puntaje;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Nuestro código que llamaba a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy()&lt;/code&gt; deja de funcionar.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Así es como podemos crear funciones para manipular esos datos:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void cambiar_nombre_del_jugador(Jugador* j, const char* nuevo_nombre);
void sumar_puntos_al_jugador(Jugador* j, uint32_t mas_puntos);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pero en vez de repetir la palabra &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_del_jugador&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;al_jugador&lt;/code&gt;,
etc. podríamos colocar las funciones que modifican los datos lo más
cerca de los datos posible, dentro del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; mismo:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Jugador {
  string nombre;
  uint32_t puntaje;

  void cambiar_nombre(const char* nuevo_nombre);
  void sumar_puntos(uint32_t mas_puntos);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Y finalmente podríamos “ocultar” el acceso directo a los campos
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nombre&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puntaje&lt;/code&gt; desde fuera del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Jugador {    //&amp;lt; Esto podría ser un &quot;struct&quot; y no habría diferencia
public:
  void cambiar_nombre(const char* nuevo_nombre);
  void sumar_puntos(uint32_t mas_puntos);

private:
  string nombre;
  uint32_t puntaje;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;En esta forma tenemos funciones que modifican datos estructurados y
que ocultan los detalles de esa estructura.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;objetivos-de-las-clases&quot;&gt;Objetivos de las clases&lt;/h2&gt;

&lt;p&gt;Los objetivos de las clases entonces parecen ser:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Ocultar detalles de la estructura de los datos en memoria&lt;/li&gt;
  &lt;li&gt;Permitir modificar esa estructura manteniendo la misma interfaz (¿modificar menos código a futuro?)&lt;/li&gt;
  &lt;li&gt;Escribir menos código al evitar usar el nombre del tipo de dato
en cada función (ej: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cambiar_algo_del_jugador&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;obtener_algo_del_jugador&lt;/code&gt;, etc.)
y al ofrecer acceso implícito a las variables miembros de la clase
(esto es: al escribir &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nombre&lt;/code&gt; sabemos que hacemos referencia a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this-&amp;gt;nombre&lt;/code&gt;,
igual que hacer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jugador-&amp;gt;nombre&lt;/code&gt; en cualquier otra función fuera de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Jugador&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;consejos-para-diseñar-clases&quot;&gt;Consejos para diseñar clases&lt;/h2&gt;

&lt;p&gt;Mi consejo es comenzar directamente con &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;s, todos los datos
públicos, y un conjunto de funciones: funciones dentro del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; si
modifican esos datos, y funciones globales si son lógica que usa el
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Empezaría usando la estructura con sus funciones y en algunos casos
accediendo a sus datos directamente. Luego si nos damos cuenta que
hacemos algo con los datos repetidamente, aparecerá la necesidad de
crear una función (dentro del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;) para evitar duplicar código.&lt;/p&gt;

&lt;p&gt;A futuro (cuando el sistema se hace más complejo) colocamos todas las
variables miembro en campos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; y también la mayor cantidad de
funciones en &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; que podamos. Toda la interfaz (y lo más pequeña
posible) en &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt;. Al compilar los errores nos dirán dónde
accedemos directamente a los campos que ahoran son &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tenemos que tener en cuenta que el desarrollo de software es algo
evolutivo. Comenzaremos con el diseño más sencillo que podamos
(estructuras y funciones que modifiquen esos datos) y luego a medida
que avanzamos empezamos a ocultar más información, agregando funciones
miembro (métodos), etc.&lt;/p&gt;

&lt;p&gt;En definitiva mi consejo sería:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;No hagas algo excesivamente “robusto” en un principio si no sabes
que lo que estás haciendo durará por mucho tiempo. Ej. un simple
programa para resolver un problema pequeño tal vez no requiere de
tanta ingeniería/arquitectura/etc.&lt;/li&gt;
  &lt;li&gt;Las clases aparecerán solas por necesidad de modificar datos, y las
relaciones entre clases por las relaciones entre esos datos.
Mientras menos relaciones/dependencias entre distintas clases, y
jerarquías de clases tengamos, mejor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yo diría que el único enfoque posible es &lt;em&gt;pensar en datos&lt;/em&gt; y no en
cosas/objetos del mundo real, sino más bien en &lt;em&gt;qué datos&lt;/em&gt; necesitamos
para resolver el problema que tenemos que resolver.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Comienzo, luego escribo</title>
   <link href="https://davidcapello.com/blog/ideas/comienzo-luego-escribo/"/>
   <updated>2020-08-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/comienzo-luego-escribo</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Esto fue escrito el 14 de mayo del 2019. Es un texto perdido de algo
que nunca comencé titulado &lt;em&gt;“Comienzo, luego escribo”&lt;/em&gt;. Subtitulado
&lt;em&gt;“Pensando como una colonia de hormigas.”&lt;/em&gt; Creo que vale más para
este año 2020.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sobrevivir, eso es lo único que importa. &lt;br /&gt;
Si no comienzo a escribir, moriré sin haber escrito. &lt;br /&gt;
¿De qué sirve escribir si todo lo que escribo no lo leerá nadie? &lt;br /&gt;
¿Qué es una idea en un mundo donde no existe nadie que la piense? &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;En caso de una catástrofe a nivel mundial nadie está seguro de nada, o
dicho de otro modo, sólo estamos seguros de una cosa, nadie
sobreviviría.&lt;/p&gt;

&lt;p&gt;¿Podría la inteligencia sobrevivir un cataclismo? ¿Podría luego los
seres vivos evolucionar a una forma más pequeña de ser vivo
inteligente?&lt;/p&gt;

&lt;p&gt;Lo que debemos entender es que nadie nos protege. Una vez superado el
miedo inicial de que estamos solos en el universo, debemos empezar la
“planificación.” La pregunta es, ¿qué debemos planificar?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Me Estoy Viniendo Viejo</title>
   <link href="https://davidcapello.com/blog/ideas/me-estoy-viniendo-viejo/"/>
   <updated>2020-07-31T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/me-estoy-viniendo-viejo</id>
   <content type="html">&lt;p&gt;Lo que buscan todos los servicios de Internet es destruir tu tiempo
personal, masacrarlo con la violencia más deshumanizada posible, hasta
que no te queden más ganas de pensar o reflexionar sobre tu vida o tus
experiencias personales. Es un baño de bosta que te abraza y asfixia.&lt;/p&gt;

&lt;p&gt;O tal vez sólo me estoy viniendo viejo.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/ifOT92oFOJY&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>La Novedad</title>
   <link href="https://davidcapello.com/blog/ideas/la-novedad/"/>
   <updated>2020-03-25T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/la-novedad</id>
   <content type="html">&lt;p&gt;Los seres humanos nos sorprendemos
–&lt;a href=&quot;https://es.wikipedia.org/wiki/B%C3%BAsqueda_de_la_novedad&quot;&gt;obsesionamos&lt;/a&gt;–
ante una nueva idea, una nueva forma de ver el mundo o resolver un
problema, o una nueva tecnología, o algo que nos hace sentir
especiales. Como que conocemos algo nuevo que los demás no conocen. Y
todo parece encajar en esa nueva forma.&lt;/p&gt;

&lt;p&gt;La magia perdura por días, semanas, o meses, pero luego de unos años
las máscaras terminan cayendo, y lo que parecía novedoso y perfecto
tiene sus fallas. Empieza a notarse el óxido, la mugre, el
mantenimiento.&lt;/p&gt;

&lt;p&gt;Las ideas terminan siendo no tan perfecta como parecían, sino más
bien, un artefacto más del mundo: con sus errores, algo que vino
evolucionando y nosotros lo encontramos en medio del camino, todavía
imperfecto –y nunca lo será– pero con camino por recorrer.&lt;/p&gt;

&lt;p&gt;Esto pasa en todos los ámbitos del universo físico y metafísico: seres
vivos, ideas políticas, sociológicas, lenguas y lenguajes de
programación, software y hardware, incluso el cuerpo y el sexo, las
relaciones, la mente, etc.&lt;/p&gt;

&lt;p&gt;Debemos aceptar que sólo estamos en el mundo para ver una parte del
tiempo, una versión “no tan buena” de las cosas. Y son nuestros deseos
de mejorarlas que crearán la próxima novedad que inspire a las
generaciones que siguen —si es que no morimos por una pandemia
global dentro de unas semanas.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;La evolución de la naturaleza nos gana en tres aspectos al crear
artefactos físicos: 1) millones de años de ventaja, 2) no piensa ni
razona, 3) oculta los porqués y las relaciones en su larga historia
de caos.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Todo Constexpr: Parte 1</title>
   <link href="https://davidcapello.com/blog/cpp/todo-constexpr-parte-1/"/>
   <updated>2019-09-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/todo-constexpr-parte-1</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Este post es la primera parte de una serie en el que hablaremos un
poco sobre la historia de la palabra clave &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt;, la aparición de
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; (C++11), y las futuras &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consteval&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constinit&lt;/code&gt;
(C++20).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anteriormente vimos que usar
&lt;a href=&quot;/blog/cpp/const-a-todo/&quot;&gt;const en todo&lt;/a&gt;
es una buena idea para que el compilador
chequee que no estamos modificando algo que no deberíamos modificar.
Lo mismo se aplica con los
&lt;a href=&quot;/blog/dev/contratos/&quot;&gt;contratos de las APIs&lt;/a&gt;,
el compilador puede chequear que los tipos de &lt;a href=&quot;https://en.wikipedia.org/wiki/Function_prototype&quot;&gt;los argumentos y
valor de retorno de una función&lt;/a&gt;
coinciden al ser usada.
En una forma más general, podemos decir que un lenguaje de
programación debería permitirnos que la mayor parte de código se
ejecute y evalúe en &lt;a href=&quot;https://es.wikipedia.org/wiki/Tiempo_de_compilaci%C3%B3n&quot;&gt;tiempo de compilación&lt;/a&gt;
—en vez de &lt;em&gt;run-time&lt;/em&gt;, &lt;a href=&quot;https://es.wikipedia.org/wiki/Tiempo_de_ejecuci%C3%B3n&quot;&gt;tiempo de ejecución&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En estos días estuve haciendo una búsqueda bibliográfica sobre las palabras claves
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;, ya que existen algunas propuestas para C++20
que agregarían aún más ruido al asunto, como
&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1073r3.html&quot;&gt;P1073r3: Immediate functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consteval&lt;/code&gt;)&lt;/a&gt;
y &lt;a href=&quot;https://gist.github.com/EricWF/128781c188b1a4fca7581e7ea943d58b&quot;&gt;P1143r3: Adding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constinit&lt;/code&gt; keyword&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;origen-de-la-palabra-clave-const&quot;&gt;Origen de la palabra clave const&lt;/h2&gt;

&lt;p&gt;&lt;img title=&quot;The Design And Evolution of C++&quot; src=&quot;the-design-and-evolution-of-cpp.jpg&quot; align=&quot;right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Conseguí una copia del libro &lt;em&gt;The Design and Evolution of C++&lt;/em&gt; de Bjarne Stroustrup,
siguiendo las recomendación del paper
&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0939r3.pdf&quot;&gt;P0939r3: Direction for ISO C++&lt;/a&gt;
para que los que quieran sumarse u oponerse a las propuestas al
&lt;a href=&quot;http://eel.is/c++draft/&quot;&gt;estándar de C++&lt;/a&gt;, tengan una idea del cómo
y el porqué del origen del diseño de determinadas características de C++.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Jamás podré proponer algo al estándar, pero si lo hiciera,
sería sólo para quitar &lt;em&gt;features&lt;/em&gt;, no para agregarlas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En la sección &lt;em&gt;3.8 Constants&lt;/em&gt;, Bjarne indica que el origen de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; se remonta
a la idea de los sistemas operativos de asignar memoria de sólo
lectura o sólo escritura a los procesos. Inicialmente se proponían dos
palabras claves: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readonly&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;writeonly&lt;/code&gt;, con lo cual podrían haber
sido posible escribir cosas como:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void f(readonly char* entrada,
       writeonly char* salida)
{
  // Se puede sólo leer datos desde &quot;entrada&quot;, y sólo escribir en &quot;salida&quot;.
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;La historia hizo que sólo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readonly&lt;/code&gt; sobreviviera como la palabra
clave &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; y el cambio se adoptara en C, no sólo en C++ —según
cuenta Bjarne, este fue su primer contacto con los estándares en el
&lt;em&gt;Bell Labs C standards group&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Es interesante notar que nuevos lenguajes como Rust ahora cambiaron
la opción por defecto, haciendo que todo sea read-only, y obligando a
usar &lt;a href=&quot;https://doc.rust-lang.org/1.0.0/book/mutability.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mut&lt;/code&gt; para las variables que se pueden modificar&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero esto no quedó ahí. Bjarne experimentó un poco más con la palabra
clave &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; como una alternative a las macros para especificar constantes
(&lt;em&gt;tipadas&lt;/em&gt; y con &lt;em&gt;scope&lt;/em&gt;):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const int n = 100;

int main()
{
  int valores[n]; // Podemos usar &quot;n&quot; en expresiones constantes
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En vez de:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define n 100
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y así evitar aún más el uso del preprocesador en el lenguaje —uno de
los objetivos de C++ es eliminar el uso del preprocesador.&lt;/p&gt;

&lt;h2 id=&quot;inicialización-de-objetos-globales&quot;&gt;Inicialización de objetos globales&lt;/h2&gt;

&lt;p&gt;En la sección &lt;em&gt;3.11.4 Initialization of Global Objects&lt;/em&gt;, Bjarne nos
recuerda cuál fue su objetivo con los tipos de datos definidos por el
usuario: poder ser utilizados en cualquier lugar donde un &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/types&quot;&gt;tipo de dato
built-in&lt;/a&gt; puede ser usado.
Esto incluía la posibilidad de crear
variables globales del tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt;
(algo que &lt;a href=&quot;https://en.wikipedia.org/wiki/Simula&quot;&gt;Simula&lt;/a&gt; no poseía):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Doble {
public:
  double valor;
  Doble(double v) : valor(v) { }
};

Doble s1 = 2;
Doble s2 = sqrt(2); // Se construye s2 llamando la función sqrt(2) en run-time
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Aquí Bjarne explica que este tipo de inicialización no puede
realizarse completamente en tiempo de compilación ni en tiempo de
&lt;em&gt;linkeado&lt;/em&gt;.  Para eso se necesita una inicialización dinámica en
&lt;em&gt;run-time&lt;/em&gt; de este tipo de variables globales.&lt;/p&gt;

&lt;p&gt;El orden de inicialización es:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Se inicializan todas las variables globales &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; (&lt;a href=&quot;http://eel.is/c++draft/basic.start#static&quot;&gt;static initialization&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Se inicializan las variables globales dinámicamente (&lt;a href=&quot;http://eel.is/c++draft/basic.start#dynamic&quot;&gt;dynamic initialization&lt;/a&gt;):
    &lt;ul&gt;
      &lt;li&gt;la inicialización dinámica se realiza en orden sólo para variables dentro del mismo archivo (&lt;a href=&quot;http://eel.is/c++draft/lex#separate-1&quot;&gt;&lt;em&gt;translation unit&lt;/em&gt;&lt;/a&gt;),&lt;/li&gt;
      &lt;li&gt;pero no se establece ningún orden para variables definidas en distintos &lt;em&gt;translation units&lt;/em&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Se llama a la función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esta relajación donde “no se establece ningún orden para inicializar
variables globales definidas en distintos &lt;em&gt;translate units&lt;/em&gt;” generó algunos
problemas —explicados en la sección &lt;em&gt;3.11.4.1 Problems with Dynamic
Initialization&lt;/em&gt;—.  Aunque el mismo Bjarne admite que si dos variables
globales dependen de un orden específico de inicialización, podríamos
estar frente a un “diseño pobre” de nuestro software, la misma
librería C++ sufre de esta falla con &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cout&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cin&lt;/code&gt;. Un simple ejemplo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

class A {
public:
  A() { std::cout &amp;lt;&amp;lt; &quot;A\n&quot;; }
};

A a;

int main() { }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Cómo sabemos que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::cout&lt;/code&gt; está inicializado si es una variable
global definida en otro &lt;em&gt;translation unit&lt;/em&gt;?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In other words, we had been bitten by the order dependency that I
had considered “unlikely and poor design.” – Bjarne Stroustrup&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;segunda-parte&quot;&gt;Segunda parte&lt;/h2&gt;

&lt;p&gt;En la segunda parte de este artículo —todavía a escribirse en un
futuro incierto— veremos cómo usar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt; para unir estos dos
conceptos: variables globales que se inicializan con una evaluación de
una función en tiempo de compilación.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Rock</title>
   <link href="https://davidcapello.com/blog/meta/rock/"/>
   <updated>2019-03-19T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/rock</id>
   <content type="html">&lt;p&gt;¿Cuándo empecé a escuchar rock? Probablemente mucho antes de lo que
pienso, pero no lo recuerdo. Sólo tengo una clara memoria de un evento
en particular: cuando empecé a escuchar Queen, me empezó a gustar el
rock —y probablemente el funk—.&lt;/p&gt;

&lt;p&gt;De chico, en las vacaciones —o en fines de semanas largos— visitaba
junto a uno de mis hermanos a mi padre en Rosario, en el monoambiente
que alquilaba —en el cual también vivía otro de mis hermanos—.
Ese monoambiente tenía una gran ventaja: nos podíamos aburrir. Entre
cajas, papeles, y libros, también había un pequeño tesoro: una
radio. La combinación &lt;em&gt;aburrimiento + radio&lt;/em&gt; nos hacía buscar alguna
estación para escuchar algo entretenido.&lt;/p&gt;

&lt;p&gt;No tengo un claro registro en mi mente de haberme interesado por la
música antes de un día en particular. Ni tampoco tengo registro por
aprender el nombre de una banda, ni de una estación de radio antes de
ese mismo día. Ese día escuché esto:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/CzxMpXBBOU4&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;

&lt;p&gt;Desde ese entonces supe que me gustaba el rock, y Queen, y que la
estación era Radiofónica, y que la iba a sintonizar en futuras visitas
a Rosario. Esa versión de &lt;em&gt;Another One Bites the Dust&lt;/em&gt; siempre me gustó
antes que todo. (El fanatismo temporal generó un video juego que es
&lt;a href=&quot;https://davidcapello.com/games/tetris-queen/&quot;&gt;una bizarreada que mezcla Tetris + Queen + bombas&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;¿A qué viene todo esto? A absolutamente nada relevante para el
lector. Esto me llevó a conocer un compañero en la secundaria que
vendía un par de CDs de Queen –Greatest Hits I y II– con el cual
luego terminamos yendo a clases de guitarra –por tres cortos
meses—, y que hoy en día es como otro hermano.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/bY6PucZD_fs&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>A quemar todas las gomas</title>
   <link href="https://davidcapello.com/blog/ideas/a-quemar-todas-las-gomas/"/>
   <updated>2018-11-03T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/a-quemar-todas-las-gomas</id>
   <content type="html">&lt;p&gt;Esto es el futuro. Un infinito flujo de videos. Graffitis en una pared
digital. Máximas de gente que nunca se equivocó en la vida. Bots
luchando en una red social. Trolls ladrando en su eterna soledad.&lt;/p&gt;

&lt;p&gt;Rellenando cada espacio vacío de nuestra vida con nuestros
celulares. De abuelos nos preguntarán &lt;em&gt;“¿cómo era vivir en tu época,
nono?,”&lt;/em&gt; y la respuesta me da terror. &lt;em&gt;“Había tantos memes que no
podíamos ni pensar.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bienaventurados los que puedan experimentar la vida sin necesidad de
contar cuántos vieron sus historias.&lt;/p&gt;

&lt;p&gt;Internet, a vos te digo: &lt;em&gt;I gave you my money, I gave you my time. Why
you want to hurt me, girl.&lt;/em&gt;&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/tmcncGirAU4&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>Inteligencia Artificial</title>
   <link href="https://davidcapello.com/blog/ideas/inteligencia-artificial/"/>
   <updated>2017-07-16T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/inteligencia-artificial</id>
   <content type="html">&lt;p&gt;Para los que no saben,
&lt;a href=&quot;https://twitter.com/davidcapello/status/531962398631297024&quot;&gt;tengo una libreta donde anoto cosas “importantes”&lt;/a&gt;
—importantes para mí, claro. El 12 de marzo de 2015 escribía:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;El mundo virtual es una hermosa puerta al mundo “ideal.” El mundo
ideal no existe, pero es un mundo ficticio formado en nuestra
cabeza, donde todo parece funcionar perfecto, y se acerca a lo que
nosotros queremos. Donde somos pequeños dioses
omnipresentes. Podemos “escuchar” todo y “participar” en todo. Como
si fuéramos posibles engranajes en la construcción de algo
importante que nunca llega. Pero que ahí parece estar.&lt;/p&gt;

  &lt;p&gt;Un mundo ideal de posible —aparente— construcción. Y en este
mundo nuestra palabra parece tener importancia. Nos convencemos
—mentimos— que nuestras contribuciones son significativas, que
hacemos un aporte a la sociedad con la más mínima intervención. Que
nuestros gustos y opiniones tienen algún tipo de valor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Al usar la computadora, nos acercamos a un mundo platónico, de ideas
perfectas. Probablemente este mundo ideal sea para seres
ideales. Nosotros —seres humanos— no estamos incluidos en esta
ecuación.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Consejos para desarrolladores de herramientas</title>
   <link href="https://davidcapello.com/blog/dev/consejos-para-desarrolladores-de-herramientas/"/>
   <updated>2017-07-13T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/consejos-para-desarrolladores-de-herramientas</id>
   <content type="html">&lt;p&gt;Hace unos días me preguntaron por algunos consejos que pueda ofrecer
para los desarrolladores independientes de herramientas de software
para escritorio. No se me ocurren muchas cosas pero estos son algunos
puntos:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Primero concentrarse en Windows, sólo porque existe la mayor
cantidad de usuarios y puede ser el mejor &lt;em&gt;pay-off&lt;/em&gt; a corto
plazo —y además no van a querer dar soporte en tres plataformas
inicialmente si son realmente independientes.&lt;/li&gt;
  &lt;li&gt;Seguiría con macOS —empezaría por macOS si la aplicación es de
diseño gráfico o sonido— y finalmente Linux.&lt;/li&gt;
  &lt;li&gt;Si el framework que utilizan provee soporte a estas tres
plataformas casi de manera automática, podrían publicar para las
tres plataformas desde el arranque de su proyecto.&lt;/li&gt;
  &lt;li&gt;Prefieran librerías en vez de frameworks, y envuelvan la librería
con su propia capa. Si en el futuro necesitan cambiar la librería,
deberán sólo cambiar la implementación debajo de esa capa, todo el
resto del programa está a salvo y sin requerir modificaciones.&lt;/li&gt;
  &lt;li&gt;Si eligen un framework, tengan en cuenta que a futuro podría
limitarlos mortalmente. Literalmente un framework puede condenar a
un programa a no tener determinado feature o no poder arreglar un
bug en particular. Elijan los frameworks con cuidado.&lt;/li&gt;
  &lt;li&gt;Necesitarán una PC con Windows —preferentemente una Surface—
para dar soporte apropiado a usuarios en Windows 7/10, y una Mac
para macOS —y una MacBook o un Magic Trackpad para dar soporte
apropiado a eventos touch. En otras palabras: necesitarán hardware
real para saber cómo funcionan sus programas en ese mismo
hardware. Las máquinas virtuales no sirven para esto.&lt;/li&gt;
  &lt;li&gt;Recuperación de errores: Si alguien crea o diseña cosas con sus
herramientas tengan en cuenta que los errores valen oro. Intenten
obtener la mayor cantidad de información de cada usuario que tiene
un error —memory dumps, bug reports, etc. No subestimen la
importancia de los memory dumps y .pdbs en Windows.
Y recuerden que perder datos es lo peor que les puede pasar a sus
usuarios —y más cuando estos datos son &lt;em&gt;arte&lt;/em&gt;. Aprovechen un crash
para arreglar un bug.&lt;/li&gt;
  &lt;li&gt;Tratar de dar el mejor soporte de usuario, y de ser posible,
centralizado —ej: un foro propio. También dar una dirección de
email &lt;em&gt;support@my-desktop-tool.com&lt;/em&gt; podría ser bueno para tener una
conversación privada en caso de ser necesario —ej: para compartir
un memory dump.&lt;/li&gt;
  &lt;li&gt;¿Código fuente abierto? ¿Libre? ¿O cerrado? Hagan lo que
quieran. Son libres de elegir la licencia que vaya mejor con
ustedes y recuerden que no le deben nada a nadie. Sus creaciones
son suyas y pueden hacer con ellas lo que quieran.&lt;/li&gt;
  &lt;li&gt;Intenten ponerse en contacto con gente que sea profesional en el
área que maneja su programa y sigan sus consejos. Deberán aprender
a procesar todas las ideas recibidas y crear una interfaz que se
ajuste a sus requerimientos, y en el mejor de los casos, que los
supere.&lt;/li&gt;
&lt;/ol&gt;
</content>
 </entry>
 
 <entry>
   <title>Apaguen Todo</title>
   <link href="https://davidcapello.com/blog/ideas/apaguen-todo/"/>
   <updated>2017-02-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/apaguen-todo</id>
   <content type="html">&lt;p&gt;Veo este blog y cada vez escribo menos aquí –y más en otros lugares
privados–. Un blog es una fuente de preguntas que nadie hizo. Y las
redes sociales comparten el mismo problema. Nos ofrecen millones de
bytes de información, datos, hechos –y &lt;em&gt;no-hechos&lt;/em&gt;–, que nunca nos
llegamos a preguntar en primer lugar. ¿Para qué los necesitamos?  Y
aún así las seguimos usando. Eso es una adicción. (Aunque los blogs no
comparten esa adicción con respecto a las redes sociales, parecen ser
más aburridos, tal vez porque hay que procesar más datos.)&lt;/p&gt;

&lt;p&gt;La mejor forma de obtener nueva información –&lt;em&gt;leer&lt;/em&gt;– hoy en día es
como lo hacían siglos atrás. Apagando todos los aparatos –menos el
aire acondicionado– y prendiendo una vela. Incluso sospecho que la
luz artificial está ayudando al cansancio de mi vista. Citando
&lt;a href=&quot;https://es.wikipedia.org/wiki/Led#Desventajas&quot;&gt;Wikipedia&lt;/a&gt; –la fuente
de “la verdad”–:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Según un estudio reciente parece ser que los ledes que emiten una
frecuencia de luz muy azul, pueden ser dañinos para la vista y
provocar contaminación lumínica.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;¿Vas a correr el riesgo de arruinar tu vista con esas luces? Por eso
ayer hice una prueba: Teniendo la vista muy cansada de ver tantas
pantallas intenté leer, pero a la luz de la vela. Noté dos cosas
inmediatamente: 1) La vista ya no me resultaba cansada luego de un rato,
2) No me sentí con más sueño al final de la lectura que al
inicio. ¿Será la luz artificial el problema?&lt;/p&gt;

&lt;p&gt;Como gran &lt;em&gt;wikipediano&lt;/em&gt; –y mentiroso del mundo real– me gusta sacar
conclusiones universales a partir de una sola muestra. En unos meses
tendré información más concreta sobre mi experimento. Por ahora,
apaguen todo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cajas Caminando</title>
   <link href="https://davidcapello.com/blog/ideas/cajas-caminando/"/>
   <updated>2016-10-15T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/cajas-caminando</id>
   <content type="html">&lt;p&gt;Veo un futuro donde caminamos por las calles, subimos a los
colectivos, entramos a negocios y nunca nos hablamos. Un futuro donde
una palabra, un gesto o una opinión podrá ser tomada en tu contra.&lt;/p&gt;

&lt;p&gt;Veo un futuro lleno de cajas caminando. Sin boca ni ojos. Sin poder
desear un buen día, o decir algo bonito a otra persona. Veo un futuro
donde el saludo será considerado un insulto. Y la sonrisa un intento
de violación.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>El Nuevo Sentido</title>
   <link href="https://davidcapello.com/blog/ideas/el-nuevo-sentido/"/>
   <updated>2016-08-28T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/el-nuevo-sentido</id>
   <content type="html">&lt;p&gt;Quiero creer que una sociedad que desarrolla la capacidad de los
viajes interestelares también desarrolla la capacidad de despojarse de
toda creencia religiosa, egocentrismo, y sentimiento de conquista
hostil.&lt;/p&gt;

&lt;p&gt;Generalmente existe un temor sobre el posible accionar de una llegada
de extraterrestres al toparse con la tierra, poniendo de ejemplo el
mismo comportamiento del hombre al colonizar otras regiones. Hay que
tener en cuenta que este miedo se da a partir de la historia humana
del pasado, lo que no establece un parámetro o condición a futuro para
una civilización que puede viajar a otros mundos.&lt;/p&gt;

&lt;p&gt;La pregunta es ¿cómo nos comportaríamos al poder visitar otros
planetas?, al enterarnos que las religiones existentes eran sólo
historias que abarcaban nuestra visión miope, ¿qué nuevas religiones
vendrán a explicar lo inexplicable? ¿qué será lo inexplicable?&lt;/p&gt;

&lt;p&gt;El futuro de la humanidad nadie lo conoce y el comportamiento, o nivel
de sinceridad espiritual, al que llegaremos al conquistar nuevos
mundos no podemos predecirlo. Mi único consejo para las civilizaciones
futuras es: &lt;em&gt;“estemos preparados para cambiar nuestras mentes y
deshacernos de todo lo que ya no tenga sentido, cuando el nuevo
sentido llegue.”&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Escrito originalmente el 12 de abril de 2016.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Lambda en C++</title>
   <link href="https://davidcapello.com/blog/cpp/lambda-en-cpp/"/>
   <updated>2016-06-26T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/lambda-en-cpp</id>
   <content type="html">&lt;p&gt;C++11 proporciona funciones lambda a C++. A veces me pregunto &lt;em&gt;¿cómo
se imagina alguien que viene de C qué son las funciones lambda en
C++?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Supongamos una estructura que puede trasladar un punto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x, y&lt;/code&gt; unas
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dx, dy&lt;/code&gt; unidades:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Trasladar {
  int dx, dy;

  Trasladar(int du, int dv) {
    dx = du;
    dy = dv;
  }

  void aplicar(int* x, int* y) {
    (*x) += dx;
    (*y) += dy;
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Con esta estructura podemos crear traslaciones y aplicarlas cuantas
veces queramos a un punto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x, y&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int main() {
  int x = 5;
  int y = 10;

  Trasladar t(2, 4);
  t.aplicar(&amp;amp;x, &amp;amp;y);
  t.aplicar(&amp;amp;x, &amp;amp;y);

  assert(x == 9);  // 9 = 5+2+2 al aplicar &quot;t&quot; dos veces
  assert(y == 18);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En vez de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aplicar&lt;/code&gt; podríamos sobrecargar el operador de llamada a
función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt;, entonces la estructura &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Trasladar&lt;/code&gt; puede ser
utilizada como una función (a nivel sintaxis):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Trasladar {
  int dx, dy;

  Trasladar(int du, int dv) {
    dx = du;
    dy = dv;
  }

  void operator() (int* x, int* y) {
     //^ &quot;operator()&quot; no es distinto a cualquier otro nombre de
     //  función, ej: como nuestra anterior función &quot;aplicar&quot;
    (*x) += dx;
    (*y) += dy;
  }
};

int main() {
  int x = 5;
  int y = 10;

  Trasladar t(2, 4);
  t(&amp;amp;x, &amp;amp;y);
  t(&amp;amp;x, &amp;amp;y);
//^ La única diferencia es que ahora podemos usar &quot;t&quot; con la
//  misma sintaxis que una llamada a función
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Qué ventaja tiene utilizar &lt;em&gt;“la sintaxis de llamada a función”&lt;/em&gt; (ej
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t(...)&lt;/code&gt;) en vez de una llamada a una función miembro como
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t.aplicar(...)&lt;/code&gt;?  La ventaja es que la sintaxis a llamada a función
es “más genérica” para componer otras funciones:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template&amp;lt;typename T&amp;gt;
void aplicar_n(int n, int* x, int* y, T t) {
  for (; n &amp;gt; 0; --n, ++x, ++y)
    t(x, y); // Llamar la transformación &quot;t&quot; para los &quot;n&quot; puntos
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Lo bueno de esta función genérica &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aplicar_n&lt;/code&gt; es que sirve para
cualquier “cosa” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; que soporte la sintaxis de llamada a función:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void mover_x_2_unidades(int* x, int *y) {
  (*x) += 2;
}

int main() {
  int u[] = { 1, 2, 5 };
  int v[] = { 3, 5, 2 };
  aplicar_n(3, u, v, mover_x_2_unidades);

  // O lo que sería igual a usar nuestra estructura &quot;Trasladar&quot;
  aplicar_n(3, u, v, Trasladar(2, 0));

  assert(u[0] == 5);
  assert(u[1] == 6);
  assert(u[2] == 9);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En este punto, se dice que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Trasladar&lt;/code&gt; es un
&lt;a href=&quot;https://en.wikipedia.org/wiki/Function_object#In_C_and_C.2B.2B&quot;&gt;functor&lt;/a&gt;
(objeto que actúa como una función). En C++11, la nueva sintaxis para
funciones lambda básicamente nos permite crear “functors” al vuelo,
anónimos, sin nombre, en la misma línea donde los necesitamos:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;aplicar_n(3, u, v,
  [](int* x, int* y) {
    (*x) += 2;
  });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El parámetro&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[](int* x, int* y) {
  (*x) += 2;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Crea la estructura&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Lambda {

  void operator() (int* x, int* y) {
    (*x) += 2;
  }

};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;También podríamos utilizar variables del ámbito donde creamos la
“función” lambda&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int a = 2;
aplicar_n(3, u, v,
  [a](int* x, int* y) {
    (*x) += a;
  });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Lo que crearía un “functor” como el siguiente&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Lambda {
  int a;

  Lambda(int a) {
    this-&amp;gt;a = a;
  }

  void operator() (int* x, int* y) {
    (*x) += a;
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En conclusión, la sintaxis para funciones lambdas en C++11 no es más
que una forma de crear estructuras anónimas con el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt;
sobrecargado.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Puertas</title>
   <link href="https://davidcapello.com/blog/ideas/puertas/"/>
   <updated>2016-02-16T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/puertas</id>
   <content type="html">&lt;p&gt;Nuestra mente está llena de puertas. Cada vez que leemos un cuento o
vemos una película, abrimos una de estas puertas. Y ahí aparecen los
personajes, como si hubieran estado todo este tiempo dentro nuestro
pero sin ser descubiertos, en un mundo de oscuridad.&lt;/p&gt;

&lt;p&gt;Ahora sentimos cosas por ellos y no se van. Se quedan con nosotros y
nos acompañan. Aunque cerremos la puerta, o los tapemos con una
sábana, sabemos que ahí están. No los podemos matar. No podemos
destruirlos nunca más.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>UI Eterna</title>
   <link href="https://davidcapello.com/blog/dev/ui-eterna/"/>
   <updated>2015-12-02T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/ui-eterna</id>
   <content type="html">&lt;p&gt;¿Existe una Interfaz de Usuario eterna al tiempo? ¿Que atraviese todas
las épocas y nunca quede obsoleta? ¿Que pueda ser utilizada en el
presente y en el futuro, o mejor aún, en todos los futuros posibles?&lt;/p&gt;

&lt;p&gt;¿Hay una interfaz que perdure más allá de los estándares actuales?
¿Algo que no sea ni
&lt;a href=&quot;https://en.wikipedia.org/wiki/Desktop_environment&quot;&gt;desktop&lt;/a&gt;, ni
&lt;a href=&quot;https://en.wikipedia.org/wiki/Touch_user_interface&quot;&gt;touch&lt;/a&gt;, ni
&lt;a href=&quot;https://en.wikipedia.org/wiki/Virtual_reality&quot;&gt;realidad virtual&lt;/a&gt;, y
al mismo tiempo sea todo eso?&lt;/p&gt;

&lt;p&gt;¿Por qué hablamos de
&lt;a href=&quot;https://en.wikipedia.org/wiki/Button_%28computing%29&quot;&gt;botones&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Menu_%28computing%29&quot;&gt;menús&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Checkbox&quot;&gt;check boxes&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Combo_box&quot;&gt;combo boxes&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/List_box&quot;&gt;list boxes&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Radio_button&quot;&gt;radio buttons&lt;/a&gt;? ¿Cuáles
son los conceptos y datos que se esconden detrás de ellos? ¿Y por qué
existen tantas cosas para seleccionar o decir lo mismo? ¿Serán Ctrl+C,
Ctrl+X y Ctrl+V (o ⌘C, ⌘X y ⌘V) atajos del teclado en el futuro?&lt;/p&gt;

&lt;p&gt;¿Por qué los elementos en la pantalla no mutan y se transforman a algo
más acorde a nuestro dispositivo? ¿Por qué un list box es un list box?
¿Por qué no se convierte en un combo box cuando achicamos la ventana,
o en un botón con un ícono que al “clickearlo” muestra un
&lt;a href=&quot;https://en.wikipedia.org/wiki/Context_menu&quot;&gt;menú contextual&lt;/a&gt;? ¿Y por
qué no en una
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hamburger_button&quot;&gt;hamburguesa&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Todo este conglomerado de
&lt;a href=&quot;https://en.wikipedia.org/wiki/Graphical_user_interface_elements&quot;&gt;widgets&lt;/a&gt;
forman el “estándar actual” de las interfaces de usuario. Y
desarrollar aplicaciones para los distintos dispositivos implica crear
una interfaz de usuario totalmente distinta para cada uno de ellos. Y
en la mayoría de los casos, cada interfaz en su propio lenguaje de
programación –utilizando herramientas completamente disímiles–.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;¿Puede una
&lt;a href=&quot;https://en.wikipedia.org/wiki/Command-line_interface&quot;&gt;CLI&lt;/a&gt;, una
&lt;a href=&quot;https://en.wikipedia.org/wiki/Graphical_user_interface&quot;&gt;GUI&lt;/a&gt;, y una
&lt;a href=&quot;https://en.wikipedia.org/wiki/Application_programming_interface&quot;&gt;API&lt;/a&gt;
ser lo mismo? ¿Pueden modificar, accionar, y ejecutar el mismo
modelo de datos? ¿Existirá una forma de generar todo el código de
estas interfaces a partir de un conjunto de reglas sencillas?
¿Serán los estándares web la forma de desarrollar aplicaciones en el
futuro? ¿Será HTML5+CSS3+JavaScript ese conjunto de reglas
“sencillas”? Espero que no.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;¿Qué es un click en la realidad virtual?&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Const a todo</title>
   <link href="https://davidcapello.com/blog/cpp/const-a-todo/"/>
   <updated>2015-11-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/const-a-todo</id>
   <content type="html">&lt;p&gt;Aquí algo para enseñar &lt;em&gt;el día uno&lt;/em&gt; en un curso de programación. Dada la
siguiente función que suma dos enteros:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; int suma(int x, int y) {
   return x + y;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Qué está mal con este código? Respuesta: Que permite cometer errores
como el siguiente:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; int suma(int x, int y) {
   x = 0;
   return x + y;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Por qué podemos modificar un argumento de entrada que se supone que
no debe cambiar? Es decir, en nuestra cabeza hemos diseñado una
función, pero en código hemos escrito algo que permite equivocarnos
más de lo que debería.&lt;/p&gt;

&lt;p&gt;Si forzamos a que un argumento sea &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; (de sólo lectura, read-only):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; int suma(const int x, const int y) {
   return x + y;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Podemos detectar errores en tiempo de compilación:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; int suma(const int x, const int y) {
   x = 0; // Error de compilación porque &quot;x&quot; es &quot;const&quot;
   return x + y;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En un ejemplo simple como esta función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suma&lt;/code&gt; no parece tener sentido,
pero en funciones complejas, el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const&lt;/code&gt; de los argumentos se propaga a
otras funciones internas y los chequeos que el compilador puede
realizar crecen exponencialmente.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Esto nos hace recordar que los argumentos en las funciones son
variables locales. Y como cualquier otra variable se puede modificar
en el mismo cuerpo de la función. Por ejemplo:&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void desde_i_hasta_j(int i, const int j) {
  for (; i &amp;lt;= j; ++i) {
    // Hacer algo con &quot;i&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Oda a los terrícolas</title>
   <link href="https://davidcapello.com/blog/ideas/oda-a-los-terricolas/"/>
   <updated>2015-09-11T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/oda-a-los-terricolas</id>
   <content type="html">&lt;!-- &lt;div class=&quot;container main&quot;&gt; --&gt;

  &lt;div class=&quot;row&quot;&gt;

	&lt;!-- &lt;div class=&quot;col-md-12&quot; style=&quot;text-align:center;padding-top:32px&quot;&gt; --&gt;
	&lt;!--   &lt;h2&gt;Oda a los terrícolas&lt;/h2&gt; --&gt;
	&lt;!-- &lt;/div&gt; --&gt;
	&lt;div class=&quot;col-md-6&quot; style=&quot;text-align:center;&quot;&gt;

&lt;p&gt;Tentáculos apasionados.&lt;br/&gt;
Tus abrazos hacen sangrar huesos.&lt;br/&gt;
No me aprietes despacio,&lt;br/&gt;
prefiero morir completo&lt;br/&gt;
antes que esta agonía. &lt;a href=&quot;https://twitter.com/davidcapello/status/507655675661799424&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alien embrionario&lt;br/&gt;
tu aliento levanta muertos.&lt;br/&gt;
No importa el destino,&lt;br/&gt;
esta nave está perdida.&lt;br/&gt;
Igual batalla damos,&lt;br/&gt;
el dentífrico olvidamos. &lt;a href=&quot;https://twitter.com/davidcapello/status/499894758521991168&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un Alf de terciopelo&lt;br/&gt;
te espera en la garita.&lt;br/&gt;
Este universo tiene dos paradas,&lt;br/&gt;
y el boleto come billeteras.&lt;br/&gt;
Gatos acá no suben. &lt;a href=&quot;https://twitter.com/davidcapello/status/500234443253362689&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pichón del televisor.&lt;br/&gt;
Esponja de mentiras.&lt;br/&gt;
Te venden perros&lt;br/&gt;
mientras tu correa aprieta.&lt;br/&gt;
Loro promiscuo,&lt;br/&gt;
deja de ladrar autores. &lt;a href=&quot;https://twitter.com/davidcapello/status/499704503726510080&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Profesor con elevada facturación.&lt;br/&gt;
No tanto por enseñar&lt;br/&gt;
sino más bien por películas hacer.&lt;br/&gt;
Otra historia de garras&lt;br/&gt;mutantes va a vender. &lt;a href=&quot;https://twitter.com/davidcapello/status/503591847357579264&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;/div&gt;
	&lt;div class=&quot;col-md-6&quot; style=&quot;text-align:center;&quot;&gt;

&lt;p&gt;Tractor galáctico,&lt;br/&gt;
esa cosecha no se echó a perder.&lt;br/&gt;
Vayamos a Venus a rescatarla.&lt;br/&gt;
Las palabras no son en vano,&lt;br/&gt;
es el juego del planeta. &lt;a href=&quot;https://twitter.com/davidcapello/status/529320364015648768&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hovercraft del pasado,&lt;br/&gt;
hasta donde llegan tus colchones.&lt;br/&gt;
Ir por tierra no es lo mío,&lt;br/&gt;
sólo el agua me interesa.&lt;br/&gt;
Inflador del tiempo llevo. &lt;a href=&quot;https://twitter.com/davidcapello/status/499692071624523777&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pitufo corriendo un rally&lt;br/&gt;
en un plato de ravioles.&lt;br/&gt;
No por imposible&lt;br/&gt;
los motores no existen.&lt;br/&gt;
Este blue ya se escapa,&lt;br/&gt;
ni por salsa ni ricota. &lt;a href=&quot;https://twitter.com/davidcapello/status/510383775566823424&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aperitivo galáctico.&lt;br/&gt;
Colectivo lleno de cumbias.&lt;br/&gt;
No cambio tus labios por estos sonidos.&lt;br/&gt;
Más que sonidos son ruidos.&lt;br/&gt;
Más que ruido gritos. &lt;a href=&quot;https://twitter.com/davidcapello/status/500868910674366464&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instantáneo, cuantas veces&lt;br/&gt;
me has salvado las papas.&lt;br/&gt;
Tus proporciones no las entiendo,&lt;br/&gt;
pongo cualquier cosa&lt;br/&gt;
y siempre puré aparece. &lt;a href=&quot;https://twitter.com/davidcapello/status/501051726154436608&quot; class=&quot;external&quot;&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;/div&gt;
  &lt;/div&gt;

&lt;!-- &lt;/div&gt; --&gt;
</content>
 </entry>
 
 <entry>
   <title>Callbacks</title>
   <link href="https://davidcapello.com/blog/cpp/callbacks/"/>
   <updated>2015-06-01T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/callbacks</id>
   <content type="html">&lt;p&gt;Los viejos callbacks de C, ¿quién los recuerda? ¿nadie? ¿punteros a
una función? ¿no? Meh, no importa. Imaginemos esta interfaz:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;interface Callback {
  bool match(int valor);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match()&lt;/code&gt; devolvería &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; si el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valor&lt;/code&gt; es de interés.&lt;/p&gt;

&lt;p&gt;En C++ se escribe lo mismo así:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Callback {
public:
  virtual ~Callback() { }
  virtual bool match(int valor) = 0;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Podemos tener un algoritmo que nos dé como resultado el índice del
primer ítem que &lt;em&gt;match&lt;/em&gt;ea nuestro &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Callback&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int buscar_primera_coincidencia(const int* array,
                                int elementos,
                                Callback* callback) {
  for (int i=0; i&amp;lt;elementos; ++i) {
    if (callback-&amp;gt;match(array[i]))
      return i; // El item i es el primero en cumplir match() == true
  }
  return -1;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Así podemos crear miles de implementaciones &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Callback&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class EsCinco : public Callback {
public:
  bool match(int valor) override {
    return (valor == 5);
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;O también:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class DistintoDeCero : public Callback {
public:
  bool match(int valor) override {
    return (valor != 0);
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;O mucho mejor, hacer una clase genérica:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template&amp;lt;int VALOR&amp;gt;
class EsIgualA : public Callback {
public:
  bool match(int valor) override {
    return (valor == VALOR);
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y usarla así:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int main() {
  int array[] = { 4, 8, 15, 16, 23, 42 };

  EsIgualA&amp;lt;16&amp;gt; igual16;
  int resultado = buscar_primera_coincidencia(array, 6, &amp;amp;igual16);

  assert(resultado == 3);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Podríamos decir que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Callback&lt;/code&gt; es algo así como interfaz
&lt;a href=&quot;http://en.wikipedia.org/wiki/Delegation_pattern&quot;&gt;delegate&lt;/a&gt;: Alguien a
quien le derivamos parte del trabajo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;buscar_primera_coincidencia&lt;/code&gt;
necesita.&lt;/p&gt;

&lt;p&gt;Un ejemplo exactamente igual se da en la
función &lt;a href=&quot;http://en.cppreference.com/w/cpp/algorithm/qsort&quot;&gt;qsort&lt;/a&gt;.
Sólo que la interfaz &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Callback&lt;/code&gt; en este caso es un puntero
a una función:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void qsort(void*  ptr,
           size_t count,
           size_t size,
           int  (*comp)(const void*, const void*));
                 //^ Un verdadero callback: un puntero a una función
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Lo que sería igual a:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Comp {
public:
  virtual ~Comp() { }
  virtual int comp(const void* elementoA, const void* elementoB) = 0;
};

void qsort(void*  ptr,
           size_t count,
           size_t size,
           Comp*  comp);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En un próximo post vamos a ver cómo la STL utiliza conceptos similares
a callbacks y delegates en su diseño.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Este es el primer post de una seguidilla que tengo planeada sacar
respecto a &lt;a href=&quot;http://es.wikipedia.org/wiki/Callback_%28inform%C3%A1tica%29&quot;&gt;callbacks&lt;/a&gt;,
&lt;a href=&quot;http://en.wikipedia.org/wiki/Signal_programming&quot;&gt;signal programming&lt;/a&gt;,
&lt;a href=&quot;http://en.wikipedia.org/wiki/Signals_and_slots&quot;&gt;signals y slots&lt;/a&gt;,
&lt;a href=&quot;http://es.wikipedia.org/wiki/Observer_%28patr%C3%B3n_de_dise%C3%B1o%29&quot;&gt;patrón observer&lt;/a&gt;,
&lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%A1lculo_lambda#C.C3.A1lculo_lambda_y_los_lenguajes_de_programaci.C3.B3n&quot;&gt;cálculo lambda&lt;/a&gt;,
&lt;a href=&quot;http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_control&quot;&gt;inversión de control&lt;/a&gt;,
&lt;a href=&quot;http://es.wikipedia.org/wiki/Inyecci%C3%B3n_de_Dependencias&quot;&gt;inyección de dependencias&lt;/a&gt;, etc.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>REPL y tests</title>
   <link href="https://davidcapello.com/blog/cpp/repl-y-tests/"/>
   <updated>2015-04-29T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/repl-y-tests</id>
   <content type="html">&lt;p&gt;Un REPL (&lt;a href=&quot;http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop&quot;&gt;Read–Eval–Print Loop&lt;/a&gt;)
es un pequeño programa que lee un comando del usuario, lo interpreta,
lo evalúa, e imprime el resultado.&lt;/p&gt;

&lt;p&gt;Este tipo de interfaces pueden usarse para: 1) tener una forma
simplificada de acceder y ejecutar funcionalidad de nuestro programa,
y 2) probar la lógica de una forma directa.&lt;/p&gt;

&lt;p&gt;Por ejemplo, supongamos que tenemos una función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suma&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int suma(int x, int y) {
  return x + y;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y queremos ver que realmente esté haciendo lo que debería estar
haciendo. Una opción es hacer un programa de prueba con varios
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assert&lt;/code&gt;s:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define _DEBUG
#include &amp;lt;cassert&amp;gt;

int main() {
  assert(suma(0, 0) == 0);
  assert(suma(2, 3) == 5);
  assert(suma(4, 8) == 12);
  assert(suma(2, -3) == -1);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pero supongamos que tenemos cientos de funciones, y que cada una puede
interactuar con las demás generando distintos resultados y
combinaciones. (O incluso los resultados esperados pueden no entrar en
un archivo de código fuente, ej: el resultado puede ser una imagen.)
En estos casos puede ser beneficioso tener un “script” al que se le
puedan agregar pruebas.&lt;/p&gt;

&lt;p&gt;En C++, la forma más simple de implementar un REPL es utilizando la
función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::getline&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

int main() {
  string line;
  while (getline(cin, line)) {
    if (line == &quot;exit&quot;)
      break;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Con este código leemos línea a línea la entrada estándar hasta que el
usuario ingrese &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit&lt;/code&gt;. Ahí termina todo. Lo interesante es que
podríamos leer cada línea e intentar interpretar los comandos que se
ingresan. Una línea representaría una prueba distinta. Por ejemplo,
teniendo un archivo de texto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pruebas.txt&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;suma 0 0 0
suma 2 3 5
suma 4 8 12
suma 2 -3 -1
exit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Podemos crear un programa que lea estas líneas, ejecute las llamadas a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suma&lt;/code&gt;, y muestre los resultados:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

bool eval(const string&amp;amp; line);

int main() {
  string line;
  while (getline(cin, line)) {
    if (!eval(line))
      break;
  }
}

bool eval(const string&amp;amp; line) {
  stringstream input(line);

  string cmd;
  input &amp;gt;&amp;gt; cmd;

  if (cmd == &quot;exit&quot;) {
    return false;
  }
  else if (cmd == &quot;suma&quot;) {
    int x, y, expected;
    input &amp;gt;&amp;gt; x &amp;gt;&amp;gt; y &amp;gt;&amp;gt; expected;

    int result = suma(x, y);

    cout &amp;lt;&amp;lt; &quot;suma(&quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &quot;, &quot; &amp;lt;&amp;lt; y &amp;lt;&amp;lt; &quot;) = &quot;
         &amp;lt;&amp;lt; result &amp;lt;&amp;lt; &quot; &quot;
         &amp;lt;&amp;lt; (result != expected ? &quot;(FAILED) &quot;: &quot;(OK)&quot;)
         &amp;lt;&amp;lt; endl;
  }

  return true;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Así podemos ejecutar el programa por medio de la línea de comando
pasándole el archivo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pruebas.txt&lt;/code&gt; como entrada estándar. Es como si
cada línea del archivo fuera escrita por el usuario a mano, sólo que
todo sucede de forma automática y obtenemos los resultados al instante:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;suma(0, 0) = 0 (OK)
suma(2, 3) = 5 (OK)
suma(4, 8) = 12 (OK)
suma(2, -3) = -1 (OK)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Creamos un pequeño script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tests.bat&lt;/code&gt; que sólo haga:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;repl.exe &amp;lt; pruebas.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿La ventaja? Podemos –nosotros y otra gente– agregar más pruebas sin
recompilar el programa original, y con doble-click ver los resultados.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Somos bufones</title>
   <link href="https://davidcapello.com/blog/ideas/somos-bufones/"/>
   <updated>2015-04-28T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/somos-bufones</id>
   <content type="html">&lt;p&gt;¿Todavía siguen haciendo eso de &lt;em&gt;votar&lt;/em&gt;? Porque aquí en Argentina es
obligatorio.&lt;/p&gt;

&lt;p&gt;Encuentro fascinante todo el acto de la votación. Esa pantomima
berreta que nos ofrece la dosis justa de sedante para olvidarnos
de un posible despertar. &lt;em&gt;“Oigan, podríamos estar haciendo algo
verdaderamente significativo para la gente.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Toda la imagen me parece surrealista. Esa cola en espera para el cuarto
oscuro –debe llamarse así por lo macabro de la situación–. Viéndonos
a pasos de dar un voto a personas que no conocemos –y que
nunca vamos a conocer–. Dando votos a seres que probablemente ni
los amigos conocen del todo. Que ni sus parejas confían en ellos.
¡Qué verdadero salto de fe –al vacío– al que nos obligan!&lt;/p&gt;

&lt;p&gt;El acto viene condimentado con un poco de todo, hasta se
asimila a esos casamientos arreglados: &lt;em&gt;“Sí hijo, está mujer es la que
te conviene, ya nos pusimos en los detalles con sus padres, vos no te
preocupes.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Siempre que voto, en mi mente repaso las opciones: El voto en blanco es
el de la anarquía. El de la izquierda un engaño. Y el de la derecha
imposible que falle –para otro bando–. Pero seguimos votando
chantas, porque no sólo nos obligan a votar, nos convencieron de
que es justo, a la fuerza. &lt;em&gt;“¡Mirame! Valgo la pena, no soy un
impostor, ¡votame!”&lt;/em&gt; Y ahí va otro voto ciego a esos fanáticos
de la mercadotecnia. ¡Vivan los representantes –de no sé qué– carajo!&lt;/p&gt;

&lt;p&gt;Por suerte, de vez en cuando en una elección aparece un payaso. Esos
bufones que hacen que los demás candidatos parezcan hombres de
bien. Honrados. Hasta inteligentes. ¡Me mato de risa de los que
se horrorizan de estos grotescos seres! Pensando que los
“honrados” son ahora dignos de recibir voto alguno.
Para que todo el teatro continúe.
¡Cómo necesita la política de esas nefastas caricaturas!
Porque los ridículos enaltecen hasta al más incompetente.
&lt;em&gt;“Vení, ponete al lado mío, me haces sentir más lindo.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Y quiero aclarar que esto no es un ataque a la democracia. ¡Nada más
errado! Soy pro-democracia, pero no representativa. Y aquí quiero
hacer notar que encuentro fascinante –y no distingo diferencias–
tanto en el que dice &lt;em&gt;“hoy vamos a cumplir con ese hermoso deber
cívico”&lt;/em&gt; como el que lo afronta desde un &lt;em&gt;“vamos a votar así nos
sacamos este peso de encima.”&lt;/em&gt; Ahí siempre está, en ambos casos, la
actitud infantil de votar un rostro.&lt;/p&gt;

&lt;p&gt;— ¿Y nene? ¿Ya votaste? ¿Votaste bien? ¿A la más linda, no? &lt;br /&gt;
— Sí pa, voté a la más linda, ¿puedo seguir viendo televisión ahora?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;¿Tendrá la democracia representativa los días contados? Sé que debe
existir una gran cantidad de gente que vale la pena votar y lucha
contra todo un sistema corrupto, políticos honestos –dos palabras
difíciles de escuchar juntas–, pero el estado actual de la política
no promueve un flujo de voto hacia ellos, sino más bien, todo lo
contrario.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Sentido de hogar</title>
   <link href="https://davidcapello.com/blog/ideas/sentido-de-hogar/"/>
   <updated>2015-03-08T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/sentido-de-hogar</id>
   <content type="html">&lt;p&gt;¿Existirá grabado en nuestro cerebro un &lt;em&gt;sentido de hogar&lt;/em&gt;? ¿Un
sentido de &lt;em&gt;estar en casa&lt;/em&gt;? ¿Estar &lt;em&gt;a salvo&lt;/em&gt;? ¿Es sólo el miedo lo que
nos moviliza a protegernos en cuatro paredes? ¿Es también la
vergüenza? ¿A veces estamos más seguros afuera que adentro?&lt;/p&gt;

&lt;p&gt;Existe un lugar –sea un departamento alquilado, una casa rodante, o
un castillo– donde estamos a salvo de los fantasmas del mundo.
Parece ser que necesitamos un lugar donde poder sobrevivir del
exterior, y vivir en nuestra privacidad. Poder pensar tranquilos,
poder dormir y dejar afuera el mundo hostil.&lt;/p&gt;

&lt;p&gt;La necesidad de techo debe ser la primera necesidad no fisiológica. Las
cuevas, nuestros primeros refugios. Nada sofisticadas, pero
suficientes como para no morir de una lluvia, el frío y el
viento. Parece ser que necesitamos estar envueltos para sentir
seguridad. Al menos sea con unos diarios.&lt;/p&gt;

&lt;p&gt;Luego el exceso de modernización convirtió al hogar en cuatro
paredes. Llenas de adornos y comodidades. Y aun así, el exceso trajo
los miedos a nuestro propio hogar. Ahora el fantasma no está sólo
afuera, sino también adentro. Debemos salir para no morir asfixiados
por lo cotidiano de estas paredes. Lo artificial es nuestro nuevo
peligro, y probablemente el &lt;em&gt;sentido de hogar&lt;/em&gt; esté afuera más que
adentro.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Energía del desamor</title>
   <link href="https://davidcapello.com/blog/ideas/energia-del-desamor/"/>
   <updated>2014-12-08T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/energia-del-desamor</id>
   <content type="html">&lt;p&gt;Uno necesita tiempo, recursos y energía para poder mantener una
relación estable. La idea es que si esas cosas se dan naturalmente
entonces se disfruta todo el proceso –en teoría, según dicen–.
Aunque la estabilidad de una relación ya es suficiente motivo para
sorprenderme, esto no es lo más extraordinario. Lo más extraño del ser
humano es toda la energía utilizada en la &lt;em&gt;no relación&lt;/em&gt;, o mejor
dicho, el &lt;em&gt;desamor&lt;/em&gt;. Esos restos que quedan de una relación que no
funcionó –o que nunca fue–.&lt;/p&gt;

&lt;p&gt;La cantidad de tiempo que uno piensa en lo que &lt;em&gt;no fue&lt;/em&gt; es
monumental. Cuando uno se embarca con una persona el viaje asegura un
consumo de tiempo y energía –tanto en lo que dure la relación como a
futuro–. Romper con alguien es como sacar vacaciones inversas: pasar
tu tiempo libre en tu casa consumiendo energía en algo que no estás disfrutando.&lt;/p&gt;

&lt;p&gt;Hay dos cosas que me resultan interesantes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;La facilidad con la que podemos dejar entrar a alguien a nuestra
vida, decirle “bienvenido a mi mundo”, “quiero que me acompañes”, etc.&lt;/li&gt;
  &lt;li&gt;La facilidad con la que pueden echarte de ese mundo. Algo
así como un firme &lt;em&gt;fuck you&lt;/em&gt; antes de que te cierren la puerta en
la cara.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Es esa energía que fluye en el universo la que más me sorprende.  Esa
posibilidad de abrir y cerrar puertas con facilidad por un lado, y con
dificultad del otro.&lt;/p&gt;

&lt;p&gt;Tal vez tenga que ver con la
&lt;a href=&quot;http://es.wikipedia.org/wiki/Conservaci%C3%B3n_de_la_energ%C3%ADa&quot;&gt;conservación de la energía&lt;/a&gt;:
para que una pareja funcione tienen que existir los desamores de
otros. O tal vez es un poco de
&lt;a href=&quot;http://es.wikipedia.org/wiki/Energ%C3%ADa_oscura&quot;&gt;energía oscura&lt;/a&gt;:
El desamor es esa energía que ayuda a expandir el universo, principalmente
el personal, el de los solteros.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>No sé si existo</title>
   <link href="https://davidcapello.com/blog/scifi/no-se-si-existo/"/>
   <updated>2014-11-09T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/scifi/no-se-si-existo</id>
   <content type="html">&lt;p&gt;Intentando escribir ficción me di cuenta que no existo. No sé si soy
real, eso está en otro sitio. Nadie más que vos y mi cerebro ven esta
danza de dedos y ahora lees algo nuevo. ¿Dónde va nuestro ser cuando
estamos escribiendo, creando, produciendo? Existo cuando no pienso, no
existo cuando escribo.&lt;/p&gt;

&lt;p&gt;A las palabras el viento ni las toca. Ni cuerpo tienen fuera de
nuestra cabeza. Conceptos relampagueando en el cráneo, sólo aparecen y
desaparecen a medida que nos alimentamos de estos garabatos, líneas
negras sobre blanco.&lt;/p&gt;

&lt;p&gt;A las palabras se las llevan los teclados. Combinaciones exactas de
golpes producen un viaje de la mente a otros universos. Una secuencia
irrepetible de teclas produce un texto único. ¿Cuántos años pasarán
para que otras manos pasen por los mismos interruptores? ¿Es la ficción una
mano sobre un teclado? ¿Unos dedos escribiendo? ¿Un cerebro pensando?
¿Unos conceptos volando? ¿Son sólo una simulación de relámpagos?
¿Negro sobre blanco?&lt;/p&gt;

&lt;p&gt;La ficción existe, pero es como una hermosa mujer inalcanzable, que ya
está adentro de tu cabeza intentando escapar, y no puede salir nunca
más.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Parásitos del open source</title>
   <link href="https://davidcapello.com/blog/dev/parasitos-del-open-source/"/>
   <updated>2014-04-09T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/parasitos-del-open-source</id>
   <content type="html">&lt;p&gt;El &lt;a href=&quot;http://heartbleed.com/&quot;&gt;reciente bug de OpenSSL&lt;/a&gt; deja al
descubierto la cultura que rodea al open source: &lt;em&gt;&lt;del&gt;todos&lt;/del&gt;
muchos son unos parásitos.&lt;/em&gt; ¿Cuántos proveedores de hosting habrán
dado tiempo, dinero o recursos para mejorar el código de OpenSSL?
¿Uno? ¿Dos? ¿Cien?  ¿Cuántos millones usarán servidores HTTP como
Apache sin devolver absolutamente nada a la comunidad? ¿Cuántos tienen
corriendo su negocio “de arriba”?&lt;/p&gt;

&lt;p&gt;El software sin bugs no existe, pero si tu empresa depende de un
software X, deberías invertir &lt;em&gt;algo&lt;/em&gt; en ese software. Los bugs no
desaparecen por arte de magia, sino más bien aparecen por arte de
magia. Y en este caso me alegra decir esto: La culpa no es de los
desarrolladores de OpenSSL. La culpa es de &lt;em&gt;todos los que usan&lt;/em&gt; el
software y nunca pusieron un peso para nada. (Por ejemplo para montar
una buena estructura de testing automatizado que mitigue la
introducción de nuevos bugs.)&lt;/p&gt;

&lt;p&gt;¿Cómo sería una buena cultura de open source? Que los que usen un
programa open source sepan que le &lt;em&gt;deben&lt;/em&gt; algo a sus desarrolladores.
Si alguna vez pierden datos por un crash, información sensible de sus
clientes por un bug, o la vida de alguien está en riesgo por un error
en un pedazo de código abierto, la culpa es suya por usarlo y no
devolver nada a cambio.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ideas Interesantes</title>
   <link href="https://davidcapello.com/blog/ideas/ideas-interesantes/"/>
   <updated>2014-03-24T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/ideas-interesantes</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;¿De dónde vienen las ideas interesantes? ¿Por qué lo que a mí me
resulta interesante lo que a otro no? ¿Existe una fuente de ideas?
¿Existe la “cigüeña de ideas”? Y si existe, ¿por qué no me contaron
ese cuento? ¡Malditos!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Llega el final de marzo y no escribí ningún artículo, post, y/o
barbaridad en esto que se hace llamar blog. Es feriado y aprovecho a
escribir. Me preparo un café. Leo algo, intento escribir. Nada. Más
café. No viene ninguna idea interesante a mí. Miro el desorden de mi
casa. Realmente prefiero escribir antes que ordenar este chiquero.
“Ideas vengan a mí.”&lt;/p&gt;

&lt;p&gt;¿Qué hace que algo genere interés? Ayer –hoy– estaba leyendo
artículos de diario a la una de la mañana –sí, una de la mañana, yo,
leyendo el diario–. Estuve tan inmerso a tal punto que dormí entre
diarios. No podía dejar de leer o dejar pasar por alto ciertos
artículos. Algunos de los cuales ya no me explicó porqué no podía
dejar de leerlos. Si pasaba a otra cosa, luego tenía que volver al
anterior y terminarlo.&lt;/p&gt;

&lt;p&gt;Pero poniendo la pava para calentar más agua, tuve algo revelador: La
idea no importa, todas son interesantes. El problema no es &lt;em&gt;el
contenido&lt;/em&gt;, el problema es &lt;em&gt;la forma&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Es cierto que algunas ideas son interesantes por la misma naturaleza
de la pregunta. Por ejemplo, “¿existe vida después de la muerte?” es
el tipo de pregunta que puede hacernos volar por un buen rato. Pero
también es una pregunta que se puede arruinar completamente. Si la
presentamos como “sí, la vida después de la muerte existe, vino un
alienígena ancestral y me tiró la posta” corremos el riesgo de perder
el interés rápidamente.&lt;/p&gt;

&lt;p&gt;Nuestro cerebro parece estar más &lt;em&gt;a gusto&lt;/em&gt; con ciertos patrones de
belleza. El diseño gráfico, la publicidad, la producción editorial, no
son cosas que aparecieron “por casualidad”. Una buena historia no es
buena si no está bien contada. Un chiste no es gracioso si no se
cuenta bien. Y si cosas tan pequeñas como los chistes nos abren un sin
fin de posibilidades de cómo contarlo mal, no quiero pensar en
artículos, cuentos o novelas.&lt;/p&gt;

&lt;p&gt;¿Entonces las buenas ideas son ilimitadas? Sí, están por todas
partes. Cualquier cosa puede ser una idea interesante. Sólo hay que
ponerles un buen escote y la gente tendrá ganas de consumirlas.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Reading time in Jekyll</title>
   <link href="https://davidcapello.com/blog/tips/reading-time-in-jekyll/"/>
   <updated>2014-02-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/tips/reading-time-in-jekyll</id>
   <content type="html">&lt;p&gt;Do you want to display the reading time in your Jekyll’s blog
–e.g. like in &lt;a href=&quot;http://medium.com&quot;&gt;Medium.com&lt;/a&gt;–? Here you have a simple way –without
plugins–. First of all we’ve to calculate the reading time dividing
the number of words of your page’s content by 180 –assuming that
&lt;a href=&quot;http://en.wikipedia.org/wiki/Words_per_minute#Reading_and_comprehension&quot;&gt;we can read 180 wpm on a monitor&lt;/a&gt;–:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{% capture read_time %}
  {{ page.content | number_of_words | divided_by: 180 }}
{% endcapture %}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read_time&lt;/code&gt; variable is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, we can display &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;
just to avoid a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0 min read&lt;/code&gt; message:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{% if read_time != &apos;0&apos; %}
  {{ read_time }}
{% else %}
  1
{% endif %} min read
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that’s all. You can put those two snippets of code in your
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_layouts/post.html&lt;/code&gt; file.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>El problema de Bitcoin</title>
   <link href="https://davidcapello.com/blog/ideas/el-problema-de-bitcoin/"/>
   <updated>2014-02-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/el-problema-de-bitcoin</id>
   <content type="html">&lt;p&gt;Más que &lt;em&gt;el&lt;/em&gt; problema son &lt;em&gt;los&lt;/em&gt; problemas. En este post intento
explicar las fallas que veo en Bitcoin –y cualquier moneda virtual
basada en Bitcoin– desde un punto de vista de usuario y humano.&lt;/p&gt;

&lt;h2 id=&quot;uso-masivo-limitado&quot;&gt;Uso masivo, limitado&lt;/h2&gt;

&lt;p&gt;Para llegar a la masa de gente se necesita comprensión sobre “cómo
funciona” la moneda. Bitcoin es complejo de entender y explicar en un
100% sin entrar en detalles técnicos. Comprender cómo funciona la
criptografía con pares de claves públicas y privadas puede no ser
tan sencillo de digerir para la gente común.&lt;/p&gt;

&lt;p&gt;En pocas palabras, la complejidad aleja a la gente común, salvo que
ofrezcamos facilidad de uso.&lt;/p&gt;

&lt;h2 id=&quot;facilidad-complejidad-de-uso&quot;&gt;&lt;s&gt;Facilidad&lt;/s&gt; Complejidad de uso&lt;/h2&gt;

&lt;p&gt;Existen dos puntos en conflicto: Facilidad de uso vs. Seguridad.
Guardar una clave privada –un bloque de bits– a salvo puede ser una
de las tareas más complejas hoy en día. Debido a que la clave debe ser
generada por una máquina, siempre hay sospechas de que 1) el programa
que la genera también se encarga de enviarla a “alguien más”, o 2) la
máquina tenga un virus de un tercero que se encargue de robar claves.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lo más seguro&lt;/em&gt;: Crear una clave privada en una computadora sin acceso
a Internet, imprimirla en papel, guardar el papel como si fuera oro,
quemar la computadora que usamos para generar la clave.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lo más fácil de usar&lt;/em&gt;: Que un sitio al que entramos con
usuario/contraseña nos mantenga nuestra la billetera por nosotros, y
mediante una app en el celular podemos comprar y vender. Claro está
que además de sencillo, esto es infinitamente inseguro –el dueño de
la app es dueño de nuestra clave–.&lt;/p&gt;

&lt;h2 id=&quot;medio-de-ahorro-consumo&quot;&gt;Medio de &lt;s&gt;ahorro&lt;/s&gt; consumo&lt;/h2&gt;

&lt;p&gt;Por un lado, existen
&lt;a href=&quot;http://www.reddit.com/r/Bitcoin/comments/1rnd58/just_lost_96301_btc_due_to_virusbugbackdoor_in/&quot;&gt;casos&lt;/a&gt;
de
&lt;a href=&quot;http://www.reddit.com/r/Bitcoin/comments/1ufbt0/my_blockchaininfo_account_got_hacked_and_i_lost/&quot;&gt;personas&lt;/a&gt;
que
&lt;a href=&quot;http://www.reddit.com/r/Bitcoin/comments/1bd1d1/i_think_i_just_lost_90btc_are_they_stolen_help/&quot;&gt;perdieron&lt;/a&gt;
todas sus bitcoins. Casos donde le roban a alguien su clave privada
para hacer transacciones a su nombre, y al otro día –o minuto– se da
cuenta que ya no tiene nada, su dinero se fue, por siempre.&lt;/p&gt;

&lt;p&gt;Por otro lado, el precio de las bitcoins parece una montaña rusa,
podes
&lt;a href=&quot;http://www.coindesk.com/price/#2014-02-03,2014-02-10,close&quot;&gt;perder 25%&lt;/a&gt;
en unos días –o
&lt;a href=&quot;http://www.coindesk.com/price/#2013-10-11,2013-12-05,close&quot;&gt;ganar 10 veces&lt;/a&gt;–.&lt;/p&gt;

&lt;p&gt;Al parecer tener bitcoins ahorradas por mucho tiempo no parece ser un
negocio debido a la volatilidad e inseguridad. Es mejor quemarlas lo
antes posible –sirve más para consumir que para ahorrar–.&lt;/p&gt;

&lt;h2 id=&quot;conversión-a-dinero-real&quot;&gt;Conversión a dinero real&lt;/h2&gt;

&lt;p&gt;Los billetes tienen sus ventajas: Existe una autoridad central que los
emiten y respaldan. Ese papel que tenemos en la mano equivale a una
fracción de metal precioso –u otros papeles– que alguien está
guardando en una bóveda por nosotros. Alguien en quien todos confían.&lt;/p&gt;

&lt;p&gt;Por otro lado, con las bitcoins la información sobre qué cantidad de
dinero tiene cada billetera está distribuida en una red &lt;a href=&quot;http://es.wikipedia.org/wiki/Peer-to-peer&quot;&gt;P2P&lt;/a&gt;. Nosotros
no vemos nada físico, son sólo ceros y unos en un gran archivo que
guarda las transacciones desde la primera hasta la última. La red se
dedica a alojar y validar transacciones, por lo tanto podemos confiar
en que las billeteras dicen tener la cantidad de dinero que tienen.&lt;/p&gt;

&lt;p&gt;El problema es que no hay autoridad central que de soporte a nuestras
bitcoins con otro tipo de moneda/metal. Si la red dice que mi
billetera tiene 10 bitcoins, podemos asegurar que eso es válido, pero,
¿a cuántos dólares equivalen 10 bitcoins? El valor depende de la
disponibilidad de convertir bitcoins en alguna otra moneda, o pagar
bienes o servicios. (Por eso cada vez que cierra una “casa de cambio”
de bitcoins, el valor de la moneda cae estrepitosamente.)&lt;/p&gt;

&lt;h2 id=&quot;legalidad-de-las-transacciones&quot;&gt;Legalidad de las transacciones&lt;/h2&gt;

&lt;p&gt;¿Qué pasa con todas las leyes fiscales de cada lugar del planeta?
Existen transacciones que –pasado cierto monto– deben ser
justificadas de algún modo, por ejemplo, para evitar prácticas de
lavado de dinero.
&lt;a href=&quot;http://krebsonsecurity.com/2014/02/florida-targets-high-dollar-bitcoin-exchangers/&quot;&gt;Ejemplo en Florida.&lt;/a&gt;
&lt;a href=&quot;http://www.abc.es/tecnologia/redes/20140210/abci-rusia-bitcoin-201402101213.html&quot;&gt;Ejemplo en Rusia.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;impacto-ambiental&quot;&gt;Impacto ambiental&lt;/h2&gt;

&lt;p&gt;Por último, el punto más macabro de las bitcoins es el posible
&lt;a href=&quot;http://www.bloomberg.com/news/2013-04-12/virtual-bitcoin-mining-is-a-real-world-environmental-disaster.html&quot;&gt;impacto ambiental&lt;/a&gt;
que presentan los
&lt;a href=&quot;http://www.bitcoinminingrigs.com/&quot;&gt;servidores haciendo &lt;em&gt;mining&lt;/em&gt;&lt;/a&gt;
continuamente. Algunos dicen que no hay costo en las transacciones de
bitcoins. Aunque a simple vista es lo que parece, la red P2P se
encarga de “absorber” ese costo. Creo que si en el futuro más gente
comienza a adoptar esta forma de pago, el consumo de energía puede
representar un impacto ambiental considerable.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Tarea para el hogar: ¿Qué impacto ambiental tiene nuestro dinero
actual? Teniendo en cuenta todo el sistema de extracción de metales,
almacenamiento/seguridad, transporte, emisión de moneda,
transacciones bancarias, funcionamiento de cajeros automáticos, etc.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Un no-lenguaje de programación</title>
   <link href="https://davidcapello.com/blog/dev/un-no-lenguaje-de-programacion/"/>
   <updated>2014-02-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/un-no-lenguaje-de-programacion</id>
   <content type="html">&lt;p&gt;¿Será la manipulación de árboles AST el futuro? En
&lt;a href=&quot;http://pchiusano.blogspot.co.nz/2011/12/future-of-programming.html&quot;&gt;The Future of Programming&lt;/a&gt;,
Paul Chiusano habla sobre una organización del código fuente en forma
de bases de datos relacionales. En vez de editar texto, editaríamos
esta base de datos –mediante alguna buena UI supongamos–. Así todo
un nuevo conjunto de herramientas se hace posible, y lo que hoy nos
parece complicado de implementar –por ejemplo un &lt;em&gt;refactor&lt;/em&gt;– se
podría implementar como un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UPDATE&lt;/code&gt; a un campo de una tabla. En otras
palabras, podríamos almacenar los
&lt;a href=&quot;http://es.wikipedia.org/wiki/%C3%81rbol_de_sintaxis_abstracta&quot;&gt;AST&lt;/a&gt;
en vez del texto crudo, y manipularlos directamente. Un proyecto que
apunta a esto es: &lt;a href=&quot;http://peaker.github.io/lamdu/&quot;&gt;Lamdu&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Existe todo un mundo detrás de la manipulación del texto en la
programación. Somos artesanos del texto. Y con esto no me refiero
exactamente a “escritores”. Sino a la cantidad de tiempo que
invertimos en cosas inútiles que no afectan al código. Por ejemplo:
espacios en blanco, tamaño de &lt;em&gt;tabs&lt;/em&gt;, cantidad de columnas en la
pantalla, nuevas líneas y &lt;em&gt;enters&lt;/em&gt; (CRLF vs CR vs LF), nivel de sangría,
etc. (A veces en vez de programar, siento que estoy pintando un cuadro.)&lt;/p&gt;

&lt;p&gt;Para empeorar la situación, las reglas deben ser acordadas entre todos
los miembros del equipo, que a su vez, tienen batallas constantes
dentro de sus cabezas entre lo acordado y sus preferencias personales.&lt;/p&gt;

&lt;p&gt;¿Por qué cuando programamos no nos podemos concentrar únicamente en la
lógica del programa? ¿Por qué debemos lidiar con todos estos problemas
sobre caracteres que &lt;em&gt;no vemos&lt;/em&gt;? Y el problema no es sólo en los
editores de texto, se extiende a programas controladores de versiones
(ej: git), websites para revisar código, herramientas para formatear
el código y para buscar dentro del código (&lt;em&gt;find/grep&lt;/em&gt;), etc. Si
pudiéramos desligarnos de la representación en texto, podríamos evitar
estos problemas.&lt;/p&gt;

&lt;p&gt;La edición, navegación, presentación, comparación y control de
versiones de árboles AST abre todo un nuevo mundo de opciones que hoy
en día se nos escapa por estar preocupados en si un &lt;em&gt;tab&lt;/em&gt; debe tener un
ancho de 4 u 8 espacios. Por ejemplo, la búsqueda de código duplicado
podría hacerse mediante búsqueda de árboles AST similares. Un nuevo
tipo de refactor podría buscar estos árboles y crear métodos,
funciones o clases que los agrupen automáticamente. Ya no estaríamos
manipulando texto, sino “pedazos de lógica”. ¿Qué pasaría si
convirtiésemos todo el código de GitHub en árboles AST y pusiéramos a
andar este &lt;em&gt;refactor&lt;/em&gt; semántico? Tal vez podríamos unir muchos cuerpos
de funciones en micro-librerías que se reutilizarían entre los
proyectos más disímiles.&lt;/p&gt;

&lt;p&gt;En fin, por ahora veo lejos la posibilidad de reemplazar los editores
de texto. A pesar de todos los problemas que presentan, la entrada y
navegación de caracteres es demasiado ágil. También sospecho que
existen elementos psicológicos e históricos guardados en nuestros
cerebros: hemos evolucionando y crecido leyendo y escribiendo, es “a
lo que estamos acostumbrados”.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Bonus: Esto me trae a la cabeza otra pregunta, ¿los árabes
encontrarán fácil de programar en lenguajes de programación que se
escriben de izquierda-a-derecha? Existen
&lt;a href=&quot;http://en.wikipedia.org/wiki/Non-English-based_programming_languages&quot;&gt;lenguajes que no están basados en el inglés&lt;/a&gt;,
y entre ellos
&lt;a href=&quot;http://en.wikipedia.org/wiki/Qalb_%28programming_language%29&quot;&gt;Qalb&lt;/a&gt;,
un lenguaje funcional parecido a Scheme pero que se programa
totalmente en árabe (de derecha-a-izquierda).&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Escalera a la privacidad</title>
   <link href="https://davidcapello.com/blog/dev/escalera-a-la-privacidad/"/>
   <updated>2013-11-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/escalera-a-la-privacidad</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Algunos secretos sobre cómo escalar permisos en las aplicaciones
móviles (o cómo hacerle perder toda la privacidad al
usuario).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;primeros-pasos&quot;&gt;Primeros pasos&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Hacemos una aplicación que pida muy pocos permisos.&lt;/li&gt;
  &lt;li&gt;De alguna manera debemos conocer cuánto tiempo el usuario pasa en
nuestra aplicación (ej: usando peticiones HTTP a un servidor
nuestro con todos los datos del usuario, la máxima información que
pudimos obtener con los permisos iniciales).&lt;/li&gt;
  &lt;li&gt;Luego, cuando sabemos que el usuario depende lo suficiente de
nuestra aplicación (ej: tiene muchas conexiones/comunicación con
otras personas), sacamos una actualización.&lt;/li&gt;
  &lt;li&gt;La actualización es una nueva versión de nuestra aplicación (tal
vez con cero beneficio) que requiere más permisos que la versión
original.&lt;/li&gt;
  &lt;li&gt;Finalmente el usuario cede cada vez más y más privacidad (en
realidad nunca estará seguro de cuánto ofreció).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esto son los &lt;em&gt;baby steps&lt;/em&gt; de una aplicación que quiere obtener cada
vez más datos del usuario. Lo importante en realidad no es tener mucha
información, sino &lt;em&gt;algo&lt;/em&gt; de información, y principalmente, la identidad
del teléfono.&lt;/p&gt;

&lt;p&gt;Ahora, ¿qué hacemos? tal vez existan otras personas que quieran
comprar nuestra información…&lt;/p&gt;

&lt;h2 id=&quot;todas-las-escaleras-confluyen-a-un-punto-el-cielo&quot;&gt;Todas las escaleras confluyen a un punto, ¿el cielo?&lt;/h2&gt;

&lt;p&gt;Ahora imaginemos que somos dueños de una empresa que compra información
de usuarios. Lo único que necesitamos es contactar a desarrolladores
de aplicaciones móviles, y ofrecerles algo de dinero por su bases de
datos. Lo interesante aquí no es la cantidad de información que tiene
cada uno de estos pequeños desarrolladores, lo importante es que
nosotros podemos reconstruir mucha más información haciendo
corresponder las identidades de los teléfonos.&lt;/p&gt;

&lt;p&gt;Por ejemplo, si una aplicación pide la identidad del teléfono y GPS,
sabemos que ese desarrollador puede darnos las coordenadas por donde
anduvo una persona. Si otra aplicación pide la identidad del teléfono,
el propietario y acceso a fotos, sabemos que ese otro desarrollador
puede darnos fotos de determinado teléfono, y el nombre del
propietario del celular.&lt;/p&gt;

&lt;p&gt;Si unimos los datos de ambos desarrolladores (haciendo coincidir la
“identidad del teléfono”), ya tenemos nombre de la persona,
ubicaciones por donde caminó, y su biblioteca de fotos. Y esto
comprando sólo los datos de dos aplicaciones.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Cabe destacar que lo expuesto aquí debería ser considerado una de
las peores prácticas en el desarrollo de software. Tal vez la menos
ética, y tal vez debería estar penado por ley. Por lo menos hasta
que se encuentre un caso en contra de esos check-boxes “Juro por
Dios y la Patria que he leído la licencia”. Es probable que algunos
lectores, al comenzar el artículo, hayan dicho &lt;em&gt;“es verdad, ¡yo
también puedo hacerlo!”&lt;/em&gt;, bueno, pues para ser sincero, sí, también
puedes hacerlo. Hasta que se termine la fiesta. (O hasta que la
fiesta nos termine matando a todos.)&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Contratos</title>
   <link href="https://davidcapello.com/blog/dev/contratos/"/>
   <updated>2013-11-09T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/contratos</id>
   <content type="html">&lt;h2 id=&quot;introducción&quot;&gt;Introducción&lt;/h2&gt;

&lt;p&gt;Este post es el desarrollo de una simple idea de un tweet que lancé
hace un mes atrás:&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p&gt;I&amp;#39;ve to write a post about this: with dynamic typing you get static code, with static typing you get dynamic code&lt;/p&gt;&amp;mdash; David Capello (@davidcapello) &lt;a href=&quot;https://twitter.com/davidcapello/statuses/390228612919873536&quot;&gt;October 15, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async=&quot;async&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;
&lt;/script&gt;

&lt;p&gt;Traducido, eso dice algo así:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Con el
&lt;a href=&quot;http://es.wikipedia.org/wiki/Tipado_dinámico&quot;&gt;tipado dinámico&lt;/a&gt;
obtienes código estático y con
&lt;a href=&quot;http://es.wikipedia.org/wiki/Tipado_estático&quot;&gt;tipado estático&lt;/a&gt;
obtienes código dinámico.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;¿Qué quiero decir con esto? El código con tipado estático es código
que busca un &lt;em&gt;contrato&lt;/em&gt; bien definido, una forma de comunicación entre
cliente y servidor. Puede ser una
&lt;a href=&quot;http://es.wikipedia.org/wiki/Tipo_abstracto&quot;&gt;interfaz&lt;/a&gt;, o la
&lt;a href=&quot;http://es.wikipedia.org/wiki/Signatura_%28inform%C3%A1tica%29&quot;&gt;signatura de una función&lt;/a&gt;,
o el &lt;a href=&quot;http://es.wikipedia.org/wiki/Tipo_de_dato&quot;&gt;tipo de una variable&lt;/a&gt;, o un
&lt;a href=&quot;http://es.wikipedia.org/wiki/Interfaz_de_programaci%C3%B3n_de_aplicaciones&quot;&gt;API&lt;/a&gt;
completo. Todos son contratos.&lt;/p&gt;

&lt;p&gt;Lo bueno de estos contratos es que están &lt;em&gt;ahí&lt;/em&gt;, definiendo
explícitamente lo que debe cumplir un cliente. Los compiladores
chequean que todos estos contratos (tipos, cantidad de argumentos,
valores de retorno) se cumplan correctamente, y mientras más
meta-información definamos en los contratos mejor será el chequeo
estático (en tiempo de compilación).&lt;/p&gt;

&lt;p&gt;En contrapartida, sin estos contratos, como ocurre con el tipado
dinámico y el &lt;a href=&quot;http://es.wikipedia.org/wiki/Duck_typing&quot;&gt;duck typing&lt;/a&gt;,
estamos al horno. Perdemos el compilador, nadie chequea nada, y sólo
en runtime podemos ver cómo falla estrepitosamente nuestro programa si
el contrato no se cumple. Es una forma de programar “a lo compilador”,
en vez de programadores nos convertimos en compiladores
(&lt;em&gt;¿comprogradores?&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Al no tener compilador, tomamos su puesto y empezamos a usar el
depurador como compilador, o en el mejor de lo casos, nuestros &lt;em&gt;test
automatizados&lt;/em&gt; pasan a ser el compilador.&lt;/p&gt;

&lt;h2 id=&quot;ejemplo&quot;&gt;Ejemplo&lt;/h2&gt;

&lt;p&gt;Vamos a ver un ejemplo muy sencillo en pseudocódigo. La siguiente es
una interfaz muy simple con un método, pero el método tiene dos
argumentos y cada argumento un tipo (todo esto es información útil
para los chequeos que hace el compilador):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inteface Logger {
  void log(int level, String message);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Existe sólo una forma de usar la interfaz. Llamando el método
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Logger.log()&lt;/code&gt; con dos argumentos, el primero es un entero y el
segundo una cadena de caracteres. No existe otra forma posible de usar
la interfaz. Podemos ver un ejemplo de cliente:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void ProcesarTareas(Logger logger) {
  logger.log(0, &quot;Comenzar a procesar tareas&quot;);

  while (tareas.pendientes()) {
    Tarea tarea = tareas.proxima();

    switch (tarea.hacer()) {
      case Exito:       logger.log(0, &quot;Tarea con éxito&quot;);       break;
      case Advertencia: logger.log(1, &quot;Tarea con advertencia&quot;); break;
      case Error:       logger.log(2, &quot;Tarea con error&quot;);       break;
    }
  }

  logger.log(0, &quot;Finalizar&quot;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Todas las llamadas a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Logger.log()&lt;/code&gt; son iguales. Un entero y una
cadena de caracteres. Si erramos en el contrato obtenemos un error de
compilación. ¡Gracias &lt;em&gt;compilador&lt;/em&gt; por ofrecernos tanto!&lt;/p&gt;

&lt;p&gt;También podemos notar que a simple vista el argumento &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;level&lt;/code&gt; del
método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Logger.log()&lt;/code&gt; indica el nivel de severidad del error, donde
cero (0) es éxito o mensajes de información, uno (1) es una
advertencia, y dos (2) es un error. Esta información está oculta en la
interfaz, y estaría bueno hacerla explícita (modificando la
interfaz). Imaginemos que cambiamos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Logger&lt;/code&gt; a algo como esto:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;interface Logger {
  void info(String message);
  void warn(String message);
  void error(String message);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Al compilar la función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcesarTareas()&lt;/code&gt; de arriba obtendríamos cinco
errores. Lo bueno es que los errores se detectan en tiempo de
compilación, no necesitamos ni ejecutar el programa para saber que
estamos fallando. Podemos saber las líneas exactas donde están los
errores y cuáles son nuestras faltas en el incumplimiento del
contrato. Una versión corregida del programa podría ser:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void ProcesarTareas(Logger logger) {
  logger.info(&quot;Comenzar a procesar tareas&quot;);

  while (tareas.pendientes()) {
    Tarea tarea = tareas.proxima();

    switch (tarea.hacer()) {
      case Exito:       logger.info(&quot;Tarea con éxito&quot;);       break;
      case Advertencia: logger.warn(&quot;Tarea con advertencia&quot;); break;
      case Error:       logger.error(&quot;Tarea con error&quot;);      break;
    }
  }

  logger.info(&quot;Finalizar&quot;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En un rato mejoramos el diseño del programa agregando mayor
información visible (qué queremos loguear, info, warning o error), y
eliminamos constantes duplicadas sin significado por todo el programa
(los números 0, 1 y 2). Lo bueno es que esto lo hicimos sin ejecutar
el programa. Sin &lt;em&gt;test cases&lt;/em&gt;. Sin tiempo de ejecución.&lt;/p&gt;

&lt;p&gt;Si magnificamos este simple ejemplo a millones de líneas de código,
con cientos de módulos que se conectan entre sí, podemos ver una
ventaja grandísima en el uso de estos contratos entre módulos para
poder hacer &lt;a href=&quot;http://es.wikipedia.org/wiki/Refactorizaci%C3%B3n&quot;&gt;refactoring&lt;/a&gt;
a gran escala.&lt;/p&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;Las interfaces definen contratos, pero estos contratos no son fijos,
pueden cambiar a lo largo del tiempo (y todos los programadores saben
que van a cambiar). Por suerte el compilador va a seguir chequeando
por nosotros el cumplimiento de los contratos hasta el infinito. En
definitiva, el tipado estático favorece el refactoring, porque permite
que herramientas extras (como el compilador) nos ayuden en la tarea.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;El tipado estático promueve el código dinámico.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por otro lado, el tipado dinámico no nos ofrece ninguna mano para
modificar el código, sino todo lo contrario: promueve el código
estático. Si tocamos las interfaces no tenemos más que ejecutar todo
el programa nuevamente para chequear que no rompimos nada. En el mejor
de los casos, vamos a tener
&lt;a href=&quot;http://es.wikipedia.org/wiki/Cobertura_de_c%C3%B3digo&quot;&gt;pruebas de cobertura&lt;/a&gt;,
pero eso raramente suele ocurrir. En el peor de los casos, no vamos a
tener ningún test, y tendremos que ejecutar toda la funcionalidad
afectada de nuestro sistema desde cero.&lt;/p&gt;

&lt;p&gt;Mi consejo personal: Los lenguajes de tipado dinámico no ayudan a
crear grandes sistemas mantenibles/modificables/dinámicos. Al
principio pueden parecer divertidos, interesantes, y de alta
productividad, pero sólo si estamos haciendo programas &lt;em&gt;de juguete&lt;/em&gt;.
Cuando lleguemos a mayores escalas, el tipado dinámico es el peor
enemigo con el que nos podemos encontrar. El peor.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Arriesgarse</title>
   <link href="https://davidcapello.com/blog/ideas/arriesgarse/"/>
   <updated>2013-07-27T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/arriesgarse</id>
   <content type="html">&lt;p&gt;La situación actual, o el &lt;em&gt;state-of-the-art&lt;/em&gt;, de la propaganda
política –al menos aquí en Argentina– es una foto del político con
su mayor cara de imbécil, sumado a una frase digna de ser escrita –y
tachada– en la puerta de un baño público.&lt;/p&gt;

&lt;p&gt;Así es, los políticos no se arriesgan por nada. La mínima transmisión
de una idea significa ubicarse en un lugar. Decir &lt;em&gt;“estas son mis
ideas, no aquellas, yo soy esto”&lt;/em&gt; es colocarse en un lugar. Una
posición incómoda, que trae como consecuencia perder los votos que no
están de acuerdo conmigo. Al fin de cuentas, no elegir ninguna
posición, resulta ser la mejor posición para un político sin ideas.&lt;/p&gt;

&lt;p&gt;La especulación perpetua sobre posibles votos ganados y perdidos hace
que los políticos estén &lt;em&gt;“ahí”&lt;/em&gt;. Muertos. Estampados en un
cartel. Clavados en una foto. Apretados en sus trajes. Acompañados con
un eslogan berreta, su único acompañante leal.&lt;/p&gt;

&lt;p&gt;Lo más interesante de esto, no es el mensaje nulo que transmite la
campaña. Lo que me resulta realmente inaudito es que esa gente luego
reciba voto alguno. En una legislación regida por el sentido común,
debería estar penado por ley –multado con 5 a 10 años de servicio
comunitario– el no transmitir ninguna posición política, ninguna
idea, ningún mensaje, y sólo generar ruido en el ambiente con un
cartel inservible que crea la más penosa polución visual.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>UI de un instalador</title>
   <link href="https://davidcapello.com/blog/dev/ui-de-un-instalador/"/>
   <updated>2013-02-28T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/ui-de-un-instalador</id>
   <content type="html">&lt;p&gt;Intenté instalar Fedora 18. Estos son los problemas en la primera
pantalla de la instalación. (Demás está decir que tuve ganas de dejar
la instalación acá mismo.)&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;img-responsive&quot; src=&quot;fedora-18.png&quot; style=&quot;width:100%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;La primera pantalla (ver screenshot) muestra la selección de
lenguaje. Una lista con todos los lenguajes, y por defecto
seleccionado inglés (fair enough). Selecciono español con el mouse. No
hay problemas por ahora.&lt;/p&gt;

&lt;p&gt;Debajo de la lista hay un texto box y un check box. No entiendo muy
bien para qué sirve el text box, y el checkbox dice &lt;em&gt;“Fijar la
distribución de teclado predeterminado para el idioma seleccionado.”&lt;/em&gt;
(mensaje totalmente incomprensible). Generalmente cuando instalo un
sistema operativo pienso “seguro voy a tener que configurar el
teclado”. Por experiencia previa en Windows siempre hay dos cosas que
configurar: idioma y teclado, después lo demás viene cocinado (o por
lo menos es lo mínimo que espero).&lt;/p&gt;

&lt;p&gt;Escribo algo en el text box y resulta ser que actúa como filtro del
lenguaje, como para buscar el lenguaje según escribimos. Esto tiene
tres fallas (sí, tres fallas en una misma pantalla):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;El text box sirve para filtrar una lista que está encima de él, no
por debajo, ¿para qué filtrar una lista que ya seleccioné con el
mouse?  generalmente los campos de búsqueda muestran los resultados
abajo, no arriba, inclusive una lupa dentro del text box no vendría
nada mal, por lo menos para saber que sirve para buscar,&lt;/li&gt;
  &lt;li&gt;Al escribir el lenguaje, puse “spanish”, pero no aparece nada, hay
que escribir “español” (extraño, ya que en el listado se muestra
una columna con el nombre del idioma en inglés),&lt;/li&gt;
  &lt;li&gt;Al intentar escribir “español” aparece “espa;ol”, porque todavía no
pude configurar el teclado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En conclusión: tengo un text box que sirve para filtrar según el
nombre del idioma, pero necesito colocar caracteres unicode que
todavía no puedo ingresar porque no configuré el teclado, o sea, el
text box no sirve &lt;em&gt;absolutamente&lt;/em&gt; para nada. ¡¿Quién demonios diseñó
esta pantalla?!&lt;/p&gt;

&lt;p&gt;Y todavía falta el check box, que dicho sea de paso lo presioné
pensando que servía para configurar el teclado. Pero después de
clickear en &lt;em&gt;“Continuar”&lt;/em&gt; comprendí el mensaje: &lt;em&gt;“Fijar el teclado
predeterminado”&lt;/em&gt;. &lt;em&gt;“Fijar predeterminado”&lt;/em&gt;. &lt;em&gt;“Set/use default”&lt;/em&gt;.
Entonces dije &lt;em&gt;“Ah claro no, no, no, yo quiero especificar mi teclado,
no quiero uno por defecto”&lt;/em&gt;, y luego no pude volver a la pantalla
anterior (no hay botón &lt;em&gt;“Volver”&lt;/em&gt;). Tuve que salir de la instalación y
comenzar de nuevo.&lt;/p&gt;

&lt;p&gt;A veces me preguntan &lt;em&gt;“¿qué tiene de malo Linux?”&lt;/em&gt;. Use Debian por más
de 5 años (por línea de comandos, porque el GUI nunca me terminó de
cerrar), y ya hace muchísimo tiempo volví a Windows, ¿por qué? por
esta mentalidad endemoniada y retorcida que está detrás del diseño de
cada simple pantalla, ventana, diálogo, botón.&lt;/p&gt;

&lt;p&gt;Si sos un programador, el entorno de Linux te puede beneficiar porque
tiene las herramientas justas para programar, de fácil acceso e
instalación, scripts, etc. Pero al tiempo que empieces a usar la
interfaz gráfica, te va a dañar el cerebro. Vas a comenzar a creer que
esas pantallas están bien diseñadas, y por lo tanto, terminarás siendo
un peor programador.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>¿Capacidad ilimitada o brain overflow?</title>
   <link href="https://davidcapello.com/blog/ideas/capacidad-ilimitada-o-brain-overflow/"/>
   <updated>2012-12-02T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/capacidad-ilimitada-o-brain-overflow</id>
   <content type="html">&lt;p&gt;¿Qué nos ofrece Internet? ¿Qué le podemos dar? ¿Qué somos? ¿Somos lo
que consumimos? Y si hoy hay un desborde de información, ¿no estaremos
engordando de información? ¿no necesitamos ponernos a dieta?&lt;/p&gt;

&lt;p&gt;Antes de la aparición de las redes sociales era un poco más complicado
publicar contenido en Internet, lo cual hacía que haya menos vías de
comunicación, menos canales de información, menos distracciones, y
menos gente publicando material.  Ahora, el “problema” es que cualquiera
puede publicar –y republicar– lo que sea. No sólo tenemos un exceso
de información, sino que tenemos duplicación de información en exceso.&lt;/p&gt;

&lt;p&gt;¿Qué pasa cuando vemos una imagen? ¿O cuando escuchamos una música? ¿O
leemos algo? ¿Dónde van a parar dentro nuestro?  Internamente, no
tenemos idea de cómo se almacenan esas imágenes en el cerebro, pero sí
podemos afirmar que: si vemos algo nuevamente, con seguridad somos
capaces de aseverar que ya lo vimos con anterioridad.  Estamos seguros
que esas imágenes están “guardadas” en nuestra mente. No podemos
recordarlas con exactitud –o tal vez no recordamos nada– pero cuando
la vemos nuevamente algo se activa, algo dentro nuestro que nos dice
“esto ya lo vi”.&lt;/p&gt;

&lt;p&gt;Y aquí introduzco la parte más interesante: todo esto que nosotros
vemos, esta marea de información que nos inunda, millones de imágenes
que día a día siguen entrando en nuestras cabezas, ¿realmente nos
sobrepasa? ¿o tenemos una capacidad ilimitada de decir “esto ya lo
vi”?&lt;/p&gt;

&lt;p&gt;Y es una de las dos respuestas: o tenemos una capacidad infinita de
recordar cosas, o nuestro cerebro, llegado su momento de la vida, no
da más, sufre un &lt;em&gt;brain overflow&lt;/em&gt;&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, donde: 1) lo que vemos con
nuestros ojos ya no entra en la cabeza –no asimilamos más–, o 2) el
cerebro va descartando –olvidando– las imágenes más antiguas.  Claro
que existe una tercera opción: 3) nos quedamos inmediatamente ciegos y
sordos.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;small&gt;Haciendo alusión a un &lt;a href=&quot;http://en.wikipedia.org/wiki/Stack_overflow&quot;&gt;stack overflow&lt;/a&gt;, que de manera simplificada es cuando una aplicación corriendo en una computadora se queda sin memoria para continuar, y la única resolución posible es matarla.&lt;/small&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Eternos</title>
   <link href="https://davidcapello.com/blog/meta/eternos/"/>
   <updated>2012-12-01T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/eternos</id>
   <content type="html">&lt;p&gt;&lt;em&gt;“¿Dónde puedo publicarlo?”&lt;/em&gt;, &lt;em&gt;“Necesito un blog”&lt;/em&gt;, &lt;em&gt;“Necesito otro blog”&lt;/em&gt;.
No, no necesito ningún blog. O al menos, no necesito
otro. A veces pienso que el contenido que genero va a mejorar por
cambiar de lugar. La realidad me demuestra que esto nunca sucede.&lt;/p&gt;

&lt;p&gt;La mayoría de gente no necesita un blog. La mayoría de gente no tiene
nada importante para compartir, o que decirnos. Yo no tengo nada
importante para ofrecerles. Y aún así, escribo esto. O mejor dicho, lo
estoy escribiendo –sí, con papel y lápiz, o papel y microfibra en
este caso–.&lt;/p&gt;

&lt;p&gt;Y mientras escribo, pienso, “¿qué pasaría si todos los servidores se
apagaran? ¿qué perderíamos? ¿qué parte como sociedad nos faltaría?
¿qué sociedad pasaríamos a ser? ¿o a volver a ser? El impacto no sería
tanto. Sería más a nivel personal, si es que teníamos cosas “ahí
afuera” en Internet. Y cuando digo “cosas” me refiero a material que
nos costó esfuerzo creativo realizarlo.&lt;/p&gt;

&lt;p&gt;Por eso, estoy pensando que sería muy triste –para uno– perder su
blog. Perder todo eso que escribió. A nadie más le importaría. Pero
sí, cada una de esas almas perdería un poco de sí mismas, de eso que
crearon y ahora no está más.  Para la gente que nunca creó, la
angustia sería nula. Como hacer zapping en el TV, o pasar a otro
libro. &lt;em&gt;“¿Ahora qué dan?”&lt;/em&gt; se escucharía a continuación del apagón.&lt;/p&gt;

&lt;p&gt;Tal vez los servidores nunca exploten. Tal vez la nube llegó para
quedarse. Igual, el mejor consejo que se me ocurre es: si realmente
tienes algo que vale la pena compartir, escríbelo, dibújalo, grábalo,
hazlo partitura. Porque en el futuro, es muy probable que sea lo único
que tengamos para recordarnos que fuimos jóvenes, y soñamos, y un día
nos sentamos, y escribimos en una hoja, pensando que seríamos eternos.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Aclaración: Esto fue escrito bajo el título “Nada que decir”, en papel, el
día 14 de noviembre del 2012 a las 19:30 hs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ayer leí &lt;a href=&quot;https://medium.com/writers-on-writing/1eb613ce9828&quot;&gt;esto&lt;/a&gt;
lo cual va un poco con este estilo de escribir en papel.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Excepciones desde un destructor</title>
   <link href="https://davidcapello.com/blog/cpp/excepciones-desde-un-destructor/"/>
   <updated>2012-08-20T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/excepciones-desde-un-destructor</id>
   <content type="html">&lt;p&gt;Hace tres días, en C++Next publicaron
&lt;a href=&quot;http://cpp-next.com/archive/2012/08/evil-or-just-misunderstood/&quot;&gt;un artículo&lt;/a&gt;
sobre tirar excepciones en los destructores. Hasta el mismo
&lt;a href=&quot;http://cpp-next.com/archive/2012/08/evil-or-just-misunderstood/comment-page-1/#comment-1958&quot;&gt;Herb Sutter anda por los comentarios&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para los que no saben, los destructores no deberían tirar
excepciones. Y si la clase se usa en los contenedores de la STL, las
excepciones en los destructores están completamente prohibidas. Por lo
tanto, ya existe un consenso general en donde tirar excepciones desde
un destructor es sólo una fuente de problemas.&lt;/p&gt;

&lt;p&gt;Así, ¿qué trae de nuevo el artículo? Bueno, aunque el artículo es
interesante y lo recomiendo leer, básicamente no llega a nada. A
tener en cuenta:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Si tiramos una excepciones en un destructor, la excepción se
propaga como en cualquier otra función. Se siguen llamando los
destructores de los subobjetos (variables miembro) y se libera la
memoria utilizada por el objeto. La excepción se propaga hasta
algún &lt;em&gt;catch&lt;/em&gt;. Aquí todo funciona bien, no quedan objetos &lt;em&gt;zombies&lt;/em&gt;
ni &lt;em&gt;memory leaks&lt;/em&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Cuando ocurre una excepción, se destruyen los objetos que estaban
en su ámbito y en todos los ámbitos hasta llegar al &lt;em&gt;catch&lt;/em&gt; (este
proceso se llama &lt;em&gt;stack unwinding&lt;/em&gt;). ¿Qué ocurre si en medio de
esos objetos que se están destruyendo ocurre otra excepción? Veamos
el siguiente ejemplo:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class A { ... }

class B {
public:
  ~B() { throw 2; }
}

int main() {
  try {
    A a;
    B b;
    throw 1;   // Comienza el stack unwinding, los destructores
               // se llamarán en orden: ~B y luego ~A, pero ~B tira
               // otra excepción
  }
  catch (...) { }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;La pregunta prevalece: ¿qué pasa en este caso donde &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~B&lt;/code&gt; tira una
excepción en su destrucción? ¿qué excepción continúa? ¿la primera o
la segunda que generó el destructor?&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El artículo propone pensar sobre este tema y que tal vez podríamos
descartar la segunda excepción. El estándar propone resolverlo con un
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;terminate&lt;/code&gt; (ver §15.2 párrafo 3). Sencillamente, no se puede tirar
otra excepción en medio del &lt;em&gt;stack unwinding&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;De los comentarios de Herb Sutter podemos sacar varios puntos muy
concisos:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Una excepción es un error dentro de una función, y un error ocurre
cuando las postcondiciones de la función no se pueden cumplir.&lt;/li&gt;
  &lt;li&gt;La postcondición de un destructor es que el objeto estará destruido
al salir del destructor.&lt;/li&gt;
  &lt;li&gt;La vida del objeto termina al momento que entramos en el
destructor, es decir, la postcondición se cumplirá de cualquier
modo. No podemos -en medio de un destructor- decir &lt;em&gt;“eh, ok,
esperen, este objeto no se puede destruir, cancelen todo, vayan
para atrás”&lt;/em&gt;. Esto no es posible, al salir del destructor, la
memoria ya será liberada.&lt;/li&gt;
  &lt;li&gt;Entonces, ¿por qué no tirar excepciones en un destructor? Porque no
existe posibilidad de reintento o cancelación de la operación. Una
vez que entramos al destructor el objeto será liberado de la
memoria de cualquier modo.&lt;/li&gt;
  &lt;li&gt;Podemos llegar a usar una función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b.close()&lt;/code&gt; en el caso que
necesitemos atrapar excepciones en la liberación de recursos. El
destructor podría simplemente llamar a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this-&amp;gt;close()&lt;/code&gt; y hacer un
&lt;em&gt;catch&lt;/em&gt; de todas las excepciones para evitar que se propaguen.&lt;/li&gt;
  &lt;li&gt;Él aclara que hubiera preferido destructores con
&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/noexcept_spec&quot;&gt;noexcept&lt;/a&gt;
en C++11: Un modificador de funciones que especifica que el
compilador debe chequear que al destructor realmente no se le
escapan excepciones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para divertirse un poco más con todo esto, recomiendo leer:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ítem 16 “Writing Exception-Safe Code” en &lt;em&gt;Exceptional C++&lt;/em&gt; de Herb
Sutter.&lt;/li&gt;
  &lt;li&gt;Ítem 51 “Destructors, deallocation, and swap never fail” en &lt;em&gt;C++ Coding
Standards&lt;/em&gt; de Herb Sutter y Andrei Alexandrescu.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Sobre el tiempo</title>
   <link href="https://davidcapello.com/blog/ideas/sobre-el-tiempo/"/>
   <updated>2012-08-02T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/sobre-el-tiempo</id>
   <content type="html">&lt;p&gt;Muchas veces decimos &lt;em&gt;“perdí el tiempo en tal cosa”&lt;/em&gt; o &lt;em&gt;“invertí el
tiempo en tal otra”&lt;/em&gt;. Estas expresiones dan a entender dos puntos: 1)
que el tiempo tiene un valor, y 2) que nuestra vida, a medida que
transcurre, va consumiendo ese tiempo, y vamos devaluándolo. Es como
que, si pasamos tiempo fuera de algo “constructivo” (a nivel
económico), le hacemos daño o quitamos valor a alguien -o a algo-
superior a nosotros.&lt;/p&gt;

&lt;p&gt;Esa es la visión comercial del tiempo, y es la visión que la sociedad
actual tiene acerca del tiempo. Creo que deberíamos comenzar a
“invertir” más tiempo en pensar sobre el tiempo mismo.&lt;/p&gt;

&lt;p&gt;Personalmente, sospecho que el tiempo no se pierde, ni se gana, ni se
invierte, ni desaparece. El tiempo simplemente pasa, y nosotros
estamos en algún lugar, sencillamente pasando el tiempo. No hay nada
ni nadie superior a quien le estemos fallando si usamos nuestro tiempo
en cosas que no son vistas como “productivas” por los ojos de la
sociedad actual.&lt;/p&gt;

&lt;p&gt;Ver una película, escuchar una música, estar tirado en la cama, usar
Internet, ver televisión, escuchar la radio, leer una novela, poesía,
jugar, o sentarse en la vereda, no es una pérdida de tiempo. Es una
“inversión” del tiempo en nosotros mismos, y ese tiempo simplemente
debe pasar, para llenarnos.&lt;/p&gt;

&lt;p&gt;Tal vez no nos damos cuenta que el tiempo es necesario que lo
pasemos. Que no existe inversión alguna, ni pérdida. Sólo es eso,
pasar el tiempo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>La gran unificación de la programación</title>
   <link href="https://davidcapello.com/blog/ideas/la-gran-unificacion-de-la-programacion/"/>
   <updated>2012-07-18T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/la-gran-unificacion-de-la-programacion</id>
   <content type="html">&lt;p&gt;Imaginemos un mundo donde no exista código duplicado, nada. Sólo un
gran repositorio con “pedazos de lógica” Eso significa que la más
insignificante porción de lógica, por ejemplo, calcular el mínimo
entre dos números, existe una única vez codificada en un lenguaje de
programación universal al cual todos podemos acceder. Ejemplo en
pseudo-código:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;importá &quot;el código para calcular un mínimo entre dos valores&quot;
         y dejalo en una función que se llame &quot;min&quot;
definí la variable a = min(3, 2)
devolvé a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Así nunca nadie debería codificar nunca jamás cómo se calcula el
mínimo de dos valores. Inclusive nuestro pequeño programa se podría
dejar en el repositorio como “el calculador del mínimo entre 3 y
2”. (Completamente inútil, pero podríamos dejarlo, e inclusive,
debería estar ahí, porque yo ya lo escribí aquí.)&lt;/p&gt;

&lt;p&gt;¿Cuál es el problema? Las interfaces. Por ejemplo ¿Qué requisito
necesita nuestro “código para calcular un mínimo”? ¿Usará el operador
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;&lt;/code&gt; para comparar los argumentos? ¿O el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;? ¿Y si usamos nuestro
propio tipo de dato? ¿Podemos calcular el mínimo entre dos archivos, o
documentos, o personas, o naranjas? ¿Qué devuelve &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;min&lt;/code&gt;, una copia de
los argumentos o una referencia? Si devuelve una copia ¿cómo crea la
copia? ¿qué es una referencia?&lt;/p&gt;

&lt;p&gt;Los templates de C++ resuelven muchas de estas preguntas (y los
“conceptos” intentaban ser esta especificación de esta interfaz). Pero
C++ sólo anda en C++. Lo que aquí me pongo a imaginar es un lenguaje
universal, que puede ser importado y convertido a cualquier otro
lenguaje y luego interpretado o compilado a lo que sea. Es decir, un
repositorio de pseudo-código para resolver cualquier tipo de
cuestiones.&lt;/p&gt;

&lt;p&gt;Ejemplos: Quiero un calculador de la sucesión de Fibonacci, PUM! ahí
lo tenes para Fortran. Quiero una implementación de un radio button
para Java, PAM! Ahí lo tenes. Quiero un Tetris andando con highscore y
todo en… sí, en C mandamelo, SALE CON FRITAS!&lt;/p&gt;

&lt;p&gt;¿Existirá algún día la cero duplicación de código?&lt;/p&gt;

&lt;p&gt;Publicado originalmente &lt;a href=&quot;https://plus.google.com/109465192499995663692/posts/GVGDyMjLu2o&quot;&gt;aquí&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>La utopía de Nietzsche</title>
   <link href="https://davidcapello.com/blog/ideas/la-utopia-de-nietzsche/"/>
   <updated>2012-07-07T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/la-utopia-de-nietzsche</id>
   <content type="html">&lt;p&gt;Hace ya unos años atrás leía el siguiente aforismo de Friedrich
Nietzsche de &lt;em&gt;Humano, demasiado humano&lt;/em&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;462.- Mí utopía.&lt;/strong&gt; En un mejor orden social, habrán de atribuirse
las tareas pesadas y los trabajos arduos de la vida a aquél que
menos sufra, es decir, al más insensible, e ir subiendo así
gradualmente hasta el hombre más sensible a las formas más nobles y
sublimes de dolor, a quien una vida aliviada al extremo no impedirá,
entonces, que siga sufriendo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un mundo donde todos sufren por igual.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tipos para todo</title>
   <link href="https://davidcapello.com/blog/cpp/tipos-para-todo/"/>
   <updated>2012-07-03T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/tipos-para-todo</id>
   <content type="html">&lt;p&gt;Consejos para desarrolladores: Si un programa tiene que manejar una
entidad, por más mínima que sea, no subestimes el poder que tiene
crear un tipo de dato para esa entidad. Por ejemplo: un DNI (Documento
Nacional de Identidad) se pueden representar con un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; o un
entero de 64 bits, pero tal vez sea mejor usar un tipo de dato propio
(ej: una clase); una coordenada X podría ser un entero, o realmente
una clase &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoordenadaX&lt;/code&gt; (o un simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typedef&lt;/code&gt; de C++ como para comenzar).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Ventajas?&lt;/strong&gt; En lenguajes de tipado estático, podemos obtener
muchísimas validaciones en tiempo de compilación. Por ejemplo,
validaciones del tipo “aquí espero un DNI, no espero cualquier
entero”; o validaciones de unidades como “aquí espero gramos, no un
double cualquiera”.&lt;/p&gt;

&lt;p&gt;No me extrañaría ver en un futuro que Java y C# adopten los
&lt;a href=&quot;http://es.wikipedia.org/wiki/C%2B%2B11#Literales_definidos_por_el_usario&quot;&gt;sufijos personalizables de C++11&lt;/a&gt;.
Estos sufijos permiten hacer más sencillo definir literales de nuestro propios
tipos. Ejemplos:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DNI algunDni = 14304890_dni;
CoordenadaX posicion = 32_x;
Width ancho = 320_width;
Gramos peso = 10_kg + 500_g;
Bits datosCrudos = 10010_bits;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sí, todas son posibles expresiones de C++11 definiendo los tipos de
datos correctos y sobrecargando el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&quot;&quot;&lt;/code&gt;.
(Vale la pena ver la implementación del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_bits&lt;/code&gt; en esta
&lt;a href=&quot;http://stackoverflow.com/a/7906630&quot;&gt;respuesta de StackOverflow&lt;/a&gt;.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tools for web development</title>
   <link href="https://davidcapello.com/blog/dev/tools-for-web-development/"/>
   <updated>2012-06-23T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/tools-for-web-development</id>
   <content type="html">&lt;p&gt;This is a set of tools, projects, libraries, frameworks, etc. to
create web applications that I recommend you to check out. I’ll be
modifying this list if I found more and more libraries. Feel free to
recommend one in the comments section below.&lt;/p&gt;

&lt;h3 id=&quot;application-logic-at-client-side&quot;&gt;Application logic at client side&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;: jQuery gives you an easy and portable
way to query for DOM elements, create AJAX requests, create
animation, etc. It’s like the &lt;em&gt;de facto&lt;/em&gt; framework to extend
JavaScript.  There are others like
&lt;a href=&quot;http://script.aculo.us/&quot;&gt;script.aculo.us&lt;/a&gt;,
&lt;a href=&quot;http://mootools.net/&quot;&gt;mootools&lt;/a&gt;, etc.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/wycats/handlebars.js&quot;&gt;Handlebars.js&lt;/a&gt;: Templating
engine at client side. You can render JSON objects to HTML.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;style-html-organization-and-ui-helpers&quot;&gt;Style, HTML organization, and UI helpers&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter Bootstrap&lt;/a&gt;: All your
website style should be based on this. Forget your way to layout HTML
elements and CSS style, this is the &lt;em&gt;right way&lt;/em&gt; to do it.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://lesscss.org/&quot;&gt;less&lt;/a&gt;: A dynamic stylesheet language. Useful
to avoid duplicating colors/styles all over a CSS file.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jqueryui.com/&quot;&gt;jQuery UI&lt;/a&gt;: UI widgets and extensions to
build really interactive pages with JavaScript and jQuery.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://layout.jquery-dev.net/&quot;&gt;jQuery UI Layout&lt;/a&gt;: A way to organize
your page like a desktop app with docking panes. &lt;a href=&quot;http://layout.jquery-dev.net/demos/example.html&quot;&gt;Example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://fancybox.net/&quot;&gt;fancybox&lt;/a&gt;: A library to show screenshots
with fancy transitions (depends on jQuery).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;data-visualization&quot;&gt;Data visualization&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mleibman/SlickGrid/wiki&quot;&gt;SlickGrid&lt;/a&gt;: A super
customizable open source JavaScript grid to display &lt;em&gt;a lot&lt;/em&gt; of
data. You’ll need JavaScript knowledge to customize this
grid, but it feels really good when you found a bug and you can fix
it (also you can send &lt;a href=&quot;https://github.com/mleibman/SlickGrid/pulls&quot;&gt;pull requests&lt;/a&gt; to the
author). &lt;a href=&quot;http://grooveshark.com/&quot;&gt;Grooveshark&lt;/a&gt; uses this grid.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dygraphs.com/&quot;&gt;dygraphs&lt;/a&gt;: Create zoomable charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;webfonts--icons&quot;&gt;WebFonts &amp;amp; Icons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.theleagueofmoveabletype.com/&quot;&gt;The League of Moveable Type&lt;/a&gt;:
Open web fonts.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://fortawesome.github.com/Font-Awesome/&quot;&gt;Font Awesome&lt;/a&gt;: A web
font where each glyph is an icon.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.codefear.com/graphics/20-free-black-white-icon-sets/&quot;&gt;Black &amp;amp; White Icons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Entrando a otro mundo</title>
   <link href="https://davidcapello.com/blog/music/entrando-a-otro-mundo/"/>
   <updated>2012-05-09T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/entrando-a-otro-mundo</id>
   <content type="html">&lt;iframe width=&quot;100%&quot; height=&quot;166&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; src=&quot;https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F91190926&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>Forward declarations de enumerados</title>
   <link href="https://davidcapello.com/blog/cpp/forward-declarations-de-enumerados/"/>
   <updated>2012-04-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/forward-declarations-de-enumerados</id>
   <content type="html">&lt;p&gt;Continuando las discusiones con los &lt;a href=&quot;https://plus.google.com/u/0/b/111182086636270314265/111182086636270314265/posts/hk7tonfPkFj&quot;&gt;forward declarations&lt;/a&gt;,
podemos destacar un pequeño tipo de dato que nunca tuvo esta capacidad,
por lo menos no hasta C++11: Los _enum_erados.&lt;/p&gt;

&lt;p&gt;Los &lt;em&gt;enum&lt;/em&gt; siempre fueron un problema en la definición de APIs.
Actualmente, si queremos usar un enumerado en una función o como
miembro de una clase, debemos tener su definición completa con
anterioridad, inclusive el listado de valores posibles que puede tomar
el enumerado.&lt;/p&gt;

&lt;p&gt;Esto es muy sencillo de ver en el siguiente ejemplo. Imaginemos que
nuestro programa se comunica con el usuario por medio de una GUI
(ventanas, botones, controles de todo tipo). Cada control puede
recibir mensajes desde el sistema operativo, por ejemplo, si el
usuario clickea un botón, tiene sentido que recibamos el mensaje
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BotonMousePresionado&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aquí un enumerado con el listado de posibles mensajes que podemos recibir
(imaginemos esto en un archivo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tipo_mensaje.h&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;enum TipoMensaje {
  AbrirVentana,
  CerrarVentana,
  BotonMousePresionado,
  TeclaPresionada
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En el caso de que declaremos una clase que utiliza el enumerado,
necesitamos de la definición de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TipoMensaje&lt;/code&gt; completa:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &quot;tipo_mensaje.h&quot;   // Necesitamos la definición del enumerado

class Mensaje {
  TipoMensaje mensaje;
public:
  // ...
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Inclusive aunque no utilicemos los valores posibles del enumerado, no
hay forma de desacoplarlo. Esto se debe a que según el estándar de C++,
la cantidad de memoria usada por un enumerado depende de la
implementación del compilador y del rango de valores permitidos del
enumerado. Ejemplo: Un compilador podría decidir usar un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char&lt;/code&gt; en
vez de un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; para representar nuestro &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TipoMensaje&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la desventaja?&lt;/strong&gt;&lt;br /&gt;
Debido a que el compilador decide, según reglas internas y los valores
posibles del &lt;em&gt;enum&lt;/em&gt;, qué tipo de dato usar para representarlo, cada
vez que agreguemos un nuevo valor al enumerado debemos recompilar
todos los archivos que lo estaban referenciando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo podemos solucionarlo?&lt;/strong&gt;&lt;br /&gt;
C++11 introduce el concepto de los “enumerados fuertemente tipados”
(strongly typed enumerations). Con lo cual podemos decidir qué
tamaño específico tiene el enumerado.&lt;/p&gt;

&lt;p&gt;Si conocemos con anterioridad cuántos valores queremos codificar en
nuestro &lt;em&gt;enum&lt;/em&gt;, podemos especificar la cantidad de memoria requerida
por el mismo. Podemos definir un enumerado que ocupe sólo 8 bits:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;enum TipoMensaje : char {
  AbrirVentana,
  CerrarVentana,
  BotonMousePresionado,
  TeclaPresionada
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y si necesitamos referenciarlo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;enum TipoMensaje : char;    // Forward declaration

class Mensaje {
  TipoMensaje mensaje;
public:
  // ...
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué se llaman “enumerados fuertemente tipados”?&lt;/strong&gt;&lt;br /&gt;
Ese es otro tema que lo dejo para un próximo post.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Referencias: &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf&quot;&gt;N2347&lt;/a&gt; (pdf)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Reformat XML on Emacs</title>
   <link href="https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/"/>
   <updated>2012-04-09T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/emacs/reformat-xml-on-emacs</id>
   <content type="html">&lt;p&gt;You can reformat XML code adding the following code in your .emacs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(require &apos;sgml-mode)

(defun reformat-xml ()
  (interactive)
  (save-excursion
    (sgml-pretty-print (point-min) (point-max))
    (indent-region (point-min) (point-max))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reformat-xml&lt;/code&gt; in your XML buffer then.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Paréntesis en una URL</title>
   <link href="https://davidcapello.com/blog/dev/parentesis-en-una-url/"/>
   <updated>2012-04-08T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/parentesis-en-una-url</id>
   <content type="html">&lt;p&gt;Ya van dos veces que tengo que buscar cómo se codifican los paréntesis
en una URL. Aquí dejo esto como futura referencia:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;El paréntesis de apertura ( se puede escribir como %28&lt;/li&gt;
  &lt;li&gt;El paréntesis de cierre ) se puede escribir %29&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplo: Un link a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://en.wikipedia.org/wiki/Tee_(command)&lt;/code&gt; se
puede escribir como &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://en.wikipedia.org/wiki/Tee_%28command%29&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Game concepts</title>
   <link href="https://davidcapello.com/blog/gamedev/game-concepts/"/>
   <updated>2012-04-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/gamedev/game-concepts</id>
   <content type="html">&lt;p&gt;These are several (maybe unimplementable) game concepts that I’ll be
releasing in my &lt;a href=&quot;http://twitter.com/davidcapello/&quot;&gt;Twitter account&lt;/a&gt;
and adding them here frequently:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Avoid to bite your tongue. &lt;a href=&quot;https://twitter.com/davidcapello/status/187705018114248704&quot;&gt;tweet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Social Network Tycoon, you’ve to create and maintain
your own social network, destroying the competition. &lt;a href=&quot;https://twitter.com/davidcapello/status/187894104837988352&quot;&gt;tweet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Prepare as many &lt;a href=&quot;http://en.wikipedia.org/wiki/Mate_%28beverage%29&quot;&gt;mates&lt;/a&gt; as you can before it became washed out. &lt;a href=&quot;https://twitter.com/davidcapello/status/188373968632291328&quot;&gt;tweet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Drink as much beer as you can without getting drunk. &lt;a href=&quot;https://twitter.com/davidcapello/status/188835537208094720&quot;&gt;tweet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;You are a book and you must find your writer… because you’ve a typo. &lt;a href=&quot;https://twitter.com/davidcapello/status/205112884160765952&quot;&gt;tweet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Una cosa por vez</title>
   <link href="https://davidcapello.com/blog/productividad/una-cosa-por-vez/"/>
   <updated>2012-04-04T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/productividad/una-cosa-por-vez</id>
   <content type="html">&lt;p&gt;Hoy leí el siguiente artículo: &lt;a href=&quot;http://blogs.hbr.org/schwartz/2012/03/the-magic-of-doing-one-thing-a.html&quot;&gt;The Magic of Doing One Thing at a Time&lt;/a&gt;
(&lt;em&gt;La Magia de Hacer Una Cosa a la Vez&lt;/em&gt;). Más allá de los consejos específicos
para un &lt;em&gt;manager&lt;/em&gt; o individuos en la empresa, quiero resumir los puntos
importantes en general para cualquier ser humano.&lt;/p&gt;

&lt;p&gt;Prácticamente, si te sentis abrumado por millones de tareas en el
trabajo e información que te llega de todos lados, podes tomar las
siguientes estrategias para aumentar tu productividad, o mejor dicho,
volverla a su estado natural antes de que este mundo enfermo llegara:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;No juegues a la multi-tarea. No hagas malabares con todo. Dedicate a
resolver una tarea por vez y bien.&lt;/li&gt;
  &lt;li&gt;Pequeños tiempos muertos también ayuda. No intentes “rellenar” esos
tiempos haciendo otras pequeñas tareas.&lt;/li&gt;
  &lt;li&gt;Si tenes un teléfono “inteligente”, apagalo el mayor tiempo posible
(o quemalo y comprate un celular normal).&lt;/li&gt;
  &lt;li&gt;No esperes respuesta inmediata de todos. Así tampoco interrumpís
el trabajo de los demás.&lt;/li&gt;
  &lt;li&gt;Hace la cosa más importante al inicio de la mañana, a la primera hora
(sin interrupciones ni distracciones).&lt;/li&gt;
&lt;/ol&gt;
</content>
 </entry>
 
 <entry>
   <title>Lenguaje</title>
   <link href="https://davidcapello.com/blog/meta/lenguaje/"/>
   <updated>2012-03-23T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/lenguaje</id>
   <content type="html">&lt;h3 id=&quot;cómo-elijo-que-una-página-este-en-inglés-o-español&quot;&gt;¿Cómo elijo que una página este en inglés o español?&lt;/h3&gt;

&lt;p&gt;Este sitio contiene páginas que están en español y otras que están en
inglés. Generalmente no podrá encontrar la misma página traducida en
ambos lenguajes. Y en esta etapa de mi vida, muy difícilmente me
dedicaré a traducir todo lo que escribo.&lt;/p&gt;

&lt;p&gt;Dependiendo de lo que quiero transmitir, una página estará en un
lenguaje u otro. Si quiero publicar una aplicación o un juego,
probablemente lo haga en inglés. Si en cambio quiero transmitir una
idea, lo haré en mi lengua materna, español.&lt;/p&gt;

&lt;h3 id=&quot;por-qué&quot;&gt;¿Por qué?&lt;/h3&gt;

&lt;p&gt;Prefiero no traducir nada. No soy tan bueno escribiendo inglés como me
gustaría y todavía tengo que aprender a escribir en español.&lt;/p&gt;

&lt;p&gt;Si vale la pena transmitir una idea compleja correctamente, utilizaré
español, en caso contrario, utilizaré inglés. Inclusive, le recomiendo
hacer lo mismo. Se disfruta más escribiendo y leyendo en la lengua de
uno antes que en la ajena, es más sencillo expresar ideas y es
probable que contenga &lt;em&gt;menos&lt;/em&gt; errores.&lt;/p&gt;

&lt;p&gt;Y como punto adicional: prefiero comunicarme y discutir con gente que
entienda mi lengua.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>iosfwd</title>
   <link href="https://davidcapello.com/blog/cpp/iosfwd/"/>
   <updated>2012-02-24T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/iosfwd</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
La librería estándar de C++ ofrece un archivo de cabecera de &lt;a href=&quot;https://plus.google.com/u/0/b/111182086636270314265/111182086636270314265/posts/hk7tonfPkFj&quot;&gt;forward declarations&lt;/a&gt; de las clases de entrada y salida a flujos de bytes (iostreams):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iosfwd&amp;gt;&lt;br /&gt;&lt;/pre&gt;De esta forma podemos utilizar los tipos ostream, istream, etc. sin necesidad de traer la definición de todas las clases de entrada y salida. Generalmente deberíamos utilizar el &lt;a href=&quot;http://stdcxx.apache.org/doc/stdlibref/iosfwd-h.html&quot;&gt;&amp;lt;iosfwd&amp;gt;&lt;/a&gt; en nuestro .h cuando no hagamos un mayor uso que sólo referenciarlas. Un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;﻿#ifndef EMPLEADO_IO_H&lt;br /&gt;﻿#define EMPLEADO_IO_H&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iosfwd&amp;gt; // forward declaration de ostream&lt;br /&gt;&lt;br /&gt;class Empleado;    // forward declaration de nuestro tipo&lt;br /&gt;&lt;br /&gt;// Aquí no necesitamos conocer el tamaño ni de Empleado,&lt;br /&gt;// ni de ostream, podemos compilar sólo con sus forward&lt;br /&gt;// declarations.&lt;br /&gt;void write_empleado_en_formato_binario(const Empleado&amp;amp;, ostream&amp;amp;);&lt;br /&gt;&lt;br /&gt;#endif&lt;/pre&gt;&lt;b&gt;Regla:&lt;/b&gt; Siempre intenta usar las &lt;i&gt;forward declarations&lt;/i&gt; antes que incluir los archivos de cabecera que definen las clases, los cuales suelen mostrar detalles de implementación que son propensos a cambiar. Siguiendo esta regla mejoraremos el tiempo de compilación y la cantidad de archivos a compilar al realizar una modificación en un .h.&lt;p&gt;Para más información, ver la sección 27.3 Forward declarations [iostream.forward] del &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf&quot;&gt;último borrador público&lt;/a&gt; del estándar de C++
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Año nuevo</title>
   <link href="https://davidcapello.com/blog/cpp/anio-nuevo/"/>
   <updated>2011-12-23T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/anio-nuevo</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
  Bueno, este año fue poco productivo en este blog. El próximo no prometo mucho más, pero espero mejorar. Dejo un par de links que agregué en la sidebar:&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://sourceforge.net/apps/mediawiki/predef/index.php?title=Main_Page&quot;&gt;Pre-defined C/C++ Compiler Macros&lt;/a&gt;: Si alguna vez tenemos que detectar la versión de un compilador o en qué plataformas estamos, estas macros pueden ayudarnos a escribir código portable.&lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp&quot;&gt;C++ Reference Wiki&lt;/a&gt;: Una wiki con referencia sobre C++ y C++11&lt;/ul&gt;Los próximos años pueden llegar a ser los mejores años de C++. Con &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; avanzando sobre &lt;a href=&quot;http://gcc.gnu.org/&quot;&gt;gcc&lt;/a&gt;, es probable que aparezcan herramientas muy importantes para ayudar a programar en C++. Aquí les dejo un video:&lt;p&gt;
	&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/mVbDzTM21BQ&quot; frameborder=&quot;0&quot; allowfullscreen&gt;
	&lt;/iframe&gt;
  &lt;p&gt;¡Feliz año nuevo!
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ecos de la nada</title>
   <link href="https://davidcapello.com/blog/music/ecos-de-la-nada/"/>
   <updated>2011-12-12T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/ecos-de-la-nada</id>
   <content type="html">&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Como el recuerdo melancólico
de un amor que nunca fue,
los ecos retumban.
Y el sonido percibido,
es un silencio atroz.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;iframe frameborder=&quot;0&quot; height=&quot;315&quot; width=&quot;420&quot; src=&quot;//www.youtube.com/embed/o3VDdjhc-WY&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>Una sociedad que no fue</title>
   <link href="https://davidcapello.com/blog/ideas/una-sociedad-que-no-fue/"/>
   <updated>2011-11-30T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/una-sociedad-que-no-fue</id>
   <content type="html">&lt;p&gt;No existe el dinero. No existen ricos, ni pobres. Todos trabajan,
aprenden y juegan. Todos ayudan a todos. Algunos trabajan en cosas que
les gusta. Otros trabajan obligados realizando tareas que nadie
desea. No existen los sueldos. Se comercia con tiempo. A peores
trabajos mayor el tiempo para aprender y jugar. Cualquiera puede
escribir, componer, leer, escuchar, o ver una película. Todos pueden
cumplir sus sueños, pero un tiempo lo tenes que donar.&lt;/p&gt;

&lt;p&gt;No existe la publicidad, ni dos productos que sirvan para el mismo
fin. Los bienes materiales sirven sólo para lo que fueron creados, con
el diseño que produzca el menor impacto ambiental. La comida es la
mejor para la salud. Se consume todo lo que se fabrica. Se fabrica
sólo lo que se necesita.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Código C++ moderno</title>
   <link href="https://davidcapello.com/blog/cpp/codigo-cpp-moderno/"/>
   <updated>2011-09-21T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/codigo-cpp-moderno</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Una excelente charla de Herb Sutter&amp;nbsp;(en inglés)&amp;nbsp;introduciendo algunas de las novedades del nuevo&amp;nbsp;estándar&amp;nbsp;C++11 y sobre cómo escribir código en C++ aprovechando todo el conocimiento acumulado en estos años (si nunca leíste &lt;a href=&quot;http://www.gotw.ca/publications/c++cs.htm&quot;&gt;C++ Coding Standards&lt;/a&gt; de Herb Sutter y Andrei Alexandrescu, compralo):&lt;br /&gt;&lt;blockquote&gt;&lt;a href=&quot;http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T&quot;&gt;http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T&lt;/a&gt;&lt;/blockquote&gt;Los puntos tratados que no podes dejar pasar por alto:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El nuevo significado de la palabra &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference&quot;&gt;auto&lt;/a&gt;&amp;nbsp;para inferir tipos automáticamente.&lt;/li&gt;&lt;li&gt;La nueva sintaxis de&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions&quot;&gt;lambdas&lt;/a&gt;&amp;nbsp;para definir functors en línea y usarlos en algoritmos estándares (ej: for_each()).&lt;/li&gt;&lt;li&gt;&lt;i&gt;Exception safety&lt;/i&gt; y &lt;i&gt;heap lifetime&lt;/i&gt; con&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#General-purpose_smart_pointers&quot;&gt;smart pointers&lt;/a&gt;, los cuales ya tenemos varios posts en este mismo blog sobre el concepto de smart pointers y &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;RAII&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Nuevos contenedores de tipo &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Hash_tables&quot;&gt;hash table&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors&quot;&gt;Move semantics&lt;/a&gt;&amp;nbsp;que evita la creación y destrucción de objetos temporales innecesarias (ej: al retornar por valor).&lt;/li&gt;&lt;li&gt;Varios pequeños nuevos coding standards de C++11: funciones begin()/end(), &lt;i&gt;override&lt;/i&gt; explícito, idioma pimpl con unique_ptr&amp;lt;&amp;gt;, etc.&lt;/li&gt;&lt;/ul&gt;En futuros posts voy a dedicar algo de tiempo en introducir estos temas y explicar por qué nacieron cada una de estas modificaciones en el nuevo estándar de C++.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>El Hombre De Múltiples Caras</title>
   <link href="https://davidcapello.com/blog/music/el-hombre-de-multiples-caras/"/>
   <updated>2011-09-12T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/el-hombre-de-multiples-caras</id>
   <content type="html">&lt;iframe width=&quot;100%&quot; height=&quot;166&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; src=&quot;https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F95319381&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>Change volume with mouse wheel over task bar</title>
   <link href="https://davidcapello.com/blog/tips/change-volume-with-mouse-wheel-over-task-bar/"/>
   <updated>2011-08-01T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/tips/change-volume-with-mouse-wheel-over-task-bar</id>
   <content type="html">&lt;p&gt;Yeah, you can change the volume just moving the mouse wheel over task
bar using &lt;a href=&quot;http://www.autohotkey.com/&quot;&gt;AutoHotkey&lt;/a&gt; and the following
little script:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/dacap/1119346.js&quot;&gt;&lt;/script&gt;

</content>
 </entry>
 
 <entry>
   <title>Assault Rigs y Herbie Hancock</title>
   <link href="https://davidcapello.com/blog/games/assault-rigs-y-herbie-hancock/"/>
   <updated>2011-07-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/games/assault-rigs-y-herbie-hancock</id>
   <content type="html">&lt;p&gt;Hace ya unos cuantos años atrás (tal vez más de 10), cuando junto con
mis hermanos adquirimos una PlayStation, la consola traía un CD de
demo &lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; con varios juegos. Entre esos había uno de tanques con una
música algo especial. Luego nunca más me acordé del nombre del juego,
y la músico quedó perdida en mi inconsciente.&lt;/p&gt;

&lt;p&gt;Da la casualidad que ayer escuché
&lt;a href=&quot;http://www.youtube.com/watch?v=Lqtki6I-VTY&quot;&gt;Hang Up Your Hang Ups de Herbie Hancock&lt;/a&gt;.
E inmediatamente recordé la música. Busqué el nombre del CD demo,
encontré el listado de juegos y ahí estaba, el
&lt;a href=&quot;http://en.wikipedia.org/wiki/Assault_Rigs&quot;&gt;Assault Rigs&lt;/a&gt;:&lt;/p&gt;

&lt;iframe width=&quot;425&quot; height=&quot;349&quot; src=&quot;//www.youtube.com/embed/L7dVLejDMwI&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;

&lt;p&gt;La lista de músicos de Assault Rigs:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Andrew Crowley&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.stuartduffield.com/Listen.html&quot;&gt;Stuart Duffield&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Matt_Furniss&quot;&gt;Matt Furniss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Buscar por “CD Sampler Pack Vol2” &lt;a href=&quot;http://www.vidgames.com/ps/software/demodisks.html&quot;&gt;aquí&lt;/a&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Víctima de la modernidad</title>
   <link href="https://davidcapello.com/blog/ideas/victima-de-la-modernidad/"/>
   <updated>2011-06-29T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/victima-de-la-modernidad</id>
   <content type="html">&lt;p&gt;&lt;img class=&quot;img-responsive&quot; src=&quot;nofaceviciousman.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Somos rehenes de un mundo que no hicimos. Sufrimos insomnio por una
pesadilla que no soñamos. Somos partícipes de una historia que nadie
recuerda. Somos guionistas de un papel protagónico que nadie
actúa. Somos engranajes en un plan de unos pocos cerebros
siniestros. Somos un eslabón de una cadena trunca. Somos el eco que ya
no se escucha. Somos la imagen de un ruido perdido.&lt;/p&gt;

&lt;p&gt;Somos víctimas de un mundo moderno que sólo fábrica para un futuro en
el que no estamos.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>One Leg</title>
   <link href="https://davidcapello.com/blog/music/one-leg/"/>
   <updated>2011-05-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/one-leg</id>
   <content type="html">&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/993322747&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&gt;&lt;/iframe&gt;
&lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&gt;&lt;a href=&quot;https://soundcloud.com/davidcapello&quot; title=&quot;David Capello&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&gt;David Capello&lt;/a&gt; · &lt;a href=&quot;https://soundcloud.com/davidcapello/one-leg&quot; title=&quot;One Leg&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&gt;One Leg&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Short music with a couple of guitars.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Chrome - Always on top</title>
   <link href="https://davidcapello.com/blog/tips/google-chrome-always-on-top/"/>
   <updated>2011-03-27T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/tips/google-chrome-always-on-top</id>
   <content type="html">&lt;p&gt;OK, Google Chrome needs an “Always on top” option for Windows (indeed
Windows needs that option for all applications).&lt;/p&gt;

&lt;p&gt;Installing &lt;a href=&quot;http://www.autohotkey.com/&quot;&gt;AutoHotKey&lt;/a&gt; and
&lt;a href=&quot;https://gist.github.com/raw/889748/30b2d013a07cc9601f7236467467caf50fc9eb74/AlwaysOnTop.ahk&quot;&gt;running this AutoHotKey script&lt;/a&gt;,
you will be able to put any window on top (with 80% of opacity)
pressing just WinKey+O key when you’ve the window active. Here is the
script just for reference:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/dacap/1470122.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#o::&lt;/code&gt; in the first line with other key if you want
(e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#g::&lt;/code&gt; will be WinKey+G key instead of WinKey+O)&lt;/li&gt;
  &lt;li&gt;You can change 204 with other level of opacity (0 is completely
transparent, 255 is completely opaque)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.google.com/support/forum/p/Chrome/thread?tid=70d20b6ecc8110ed&amp;amp;hl=en&quot;&gt;Request about “Always on top” in Google Chrome forums&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.labnol.org/software/tutorials/keep-window-always-on-top/5213/&quot;&gt;Always on top with AutoHotKey&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Slow Walk</title>
   <link href="https://davidcapello.com/blog/music/slow-walk/"/>
   <updated>2011-03-21T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/slow-walk</id>
   <content type="html">&lt;p&gt;Hace mucho que no cuelgo una música, vamos con algo simple:&lt;/p&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/993320686&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&gt;&lt;/iframe&gt;
&lt;div style=&quot;font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;&quot;&gt;&lt;a href=&quot;https://soundcloud.com/davidcapello&quot; title=&quot;David Capello&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&gt;David Capello&lt;/a&gt; · &lt;a href=&quot;https://soundcloud.com/davidcapello/slow-walk&quot; title=&quot;Slow Walk&quot; target=&quot;_blank&quot; style=&quot;color: #cccccc; text-decoration: none;&quot;&gt;Slow Walk&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Sucesión de 12 compases clásica de blues en mi tonalidad
preferida del piano (la más fácil), Do mayor. La improvisación del
punteo con escala pentatónica de Do mayor.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cola de prioridades (STL priority_queue)</title>
   <link href="https://davidcapello.com/blog/cpp/cola-de-prioridades-stl-priority-queue/"/>
   <updated>2011-03-08T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/cola-de-prioridades-stl-priority-queue</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
La cola de prioridades es una estructura de datos que se puede visualizar como una bolsa, donde podemos ir metiendo elementos uno atrás del otro, pero sólo los podemos retirar según un criterio de prioridad. Por ejemplo, en el caso de un ladrón obsesivo-compulsivo, podría robar un banco cargando bolsas de dinero sin ningún criterio, y al vaciarla podría retirar los billetes según su valor (primero los de $100, luego los de $50, etc.).&lt;br /&gt;&lt;br /&gt;Otro ejemplo, imaginemos que tenemos un barco:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;queue&amp;gt;&lt;br /&gt;#include &amp;lt;list&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Barco {&lt;br /&gt;public:&lt;br /&gt;  void subirPasajero(const Pasajero&amp; pasajero);&lt;br /&gt;  void abandonarBarco(list&amp;lt;Pasajero&amp;gt;&amp;amp; pasajerosEnOrden);&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;  priority_queue&amp;lt;Pasajero&amp;gt; pasajeros_;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La función subirPasajero() debe agregar un pasajero al barco, y abandonarBarco() debe sacar todos los pasajeros del barco y colocarlos (por orden de prioridad) en la lista que se recibe como argumento:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;void Barco::subirPasajero(const Pasajero&amp;amp; pasajero)&lt;br /&gt;{&lt;br /&gt;  pasajeros_.push(pasajero);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Barco::abandonarBarco(list&amp;lt;Pasajero&amp;gt;&amp;amp; pasajerosEnOrden)&lt;br /&gt;{&lt;br /&gt;  while (!pasajeros_.empty()) {&lt;br /&gt;    pasajerosEnOrden.push_back(pasajeros_.top());&lt;br /&gt;    pasajeros_.pop();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tenga en cuenta que la función miembro pop() de las colas en C++ (queue, priority_queue, etc.) no retornan el valor extraído. Esto es así para evitar crear copias de los objetos dentro de la cola. De este modo la función top() devuelve una referencia al elemento mismo que se encuentra en la cola, y pop() lo remueve sin devolver nada. Así nos evitamos de crear copias temporales de la instancia removida.&lt;br /&gt;&lt;br /&gt;Para poder usar la priority_queue sobre un tipo de dato propio (como Pasajero), debemos ofrecer una implementación del operator&amp;lt;() para comparar distintas instancias de nuestro tipo de dato (este operador se utiliza para saber qué elemento debe salir último de la cola, es decir, el menor elemento tiene menor prioridad):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;enum Prioridad { Capitan, Hombre, Mujer, Ninio };&lt;br /&gt;&lt;br /&gt;class Pasajero {&lt;br /&gt;public:&lt;br /&gt;  Pasajero(Prioridad p) : prioridad_(p) { }&lt;br /&gt;&lt;br /&gt;  bool operator&amp;lt;(const Pasajero&amp;amp; otro) const {&lt;br /&gt;    return prioridad_ &amp;lt; otro.prioridad_;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Prioridad prioridad() const { return prioridad_; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;  Prioridad prioridad_;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;De este modo, el capitán tiene prioridad 0 y es tomado en cuenta como el de menor prioridad para abandonar el barco. Los pasajeros que mayor prioridad tienen de abandonar el barco son las mujeres y los niños. En este caso podrían tener igual prioridad, no tendría mucho sentido salvar a todos los niños sin sus respectivas madres.&lt;br /&gt;&lt;br /&gt;Ahora podemos crear un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Barco titanic;&lt;br /&gt;  titanic.subirPasajero(Pasajero(Capitan));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Mujer));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Hombre));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Mujer));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Ninio));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Hombre));&lt;br /&gt;  titanic.subirPasajero(Pasajero(Ninio));&lt;br /&gt;  // ...&lt;br /&gt;&lt;br /&gt;  list&amp;lt;Pasajero&amp;gt; pasajeros;&lt;br /&gt;  titanic.abandonarBarco(pasajeros);&lt;br /&gt;  &lt;br /&gt;  for (list&amp;lt;Pasajero&amp;gt;::iterator it = pasajeros.begin(),&lt;br /&gt;         end = pasajeros.end(); it != end; ++it) {&lt;br /&gt;    cout &amp;lt;&amp;lt; it-&amp;gt;prioridad() &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;El anterior ejemplo imprime:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;3&lt;br /&gt;3&lt;br /&gt;2&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;0&lt;br /&gt;&lt;/pre&gt;Lo que significa que, sin importar el orden en el cual agregamos los pasajeros, primero extraemos los niños, luego las mujeres, los hombres, y finalmente el capitán.&lt;br /&gt;&lt;br /&gt;Más información:&lt;br /&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/stl/priority_queue/&quot;&gt;http://www.cplusplus.com/reference/stl/priority_queue/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Priority_queue&quot;&gt;http://en.wikipedia.org/wiki/Priority_queue&lt;/a&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ingenieros en Sistemas de Información</title>
   <link href="https://davidcapello.com/blog/dev/ingenieros-en-sistemas-de-informacion/"/>
   <updated>2011-03-06T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/ingenieros-en-sistemas-de-informacion</id>
   <content type="html">&lt;p&gt;La carrera de Ingeniería en Sistemas de Información está llena de
casos (&lt;em&gt;brain washers&lt;/em&gt;) donde te dicen una y otra vez que “el
ingeniero no debe programar”. OK, para poner las cosas claras: El
ingeniero en sistemas que no programó nunca, o no piensa programar
nunca, ni piensa tocar una línea de código, es en pocas palabras
alguien que no sirve absolutamente para nada.&lt;/p&gt;

&lt;p&gt;Puedo enumerar algunos caminos que un Ingeniero en Sistemas de
Información quisiera tomar para esquivar la programación: diseñador,
arquitecto, investigación, project manager, testing, calidad. Pero
igualmente no vale la pena ser exhaustivos, ya que todos tienen la
misma respuesta: Si nunca programaste, nunca vas a poder hacer otra
cosa bien.&lt;/p&gt;

&lt;p&gt;Por ejemplo, no concibo a la figura de un diseñador que nunca
programó. Siendo el diseñador alguien que “fabrica” las bases para los
programadores, ¿cómo puede entender alguien qué es bueno para los
programadores si nunca programó? Lo mismo se aplica a la arquitectura
del sistema que van a usar los programadores a lo largo de todo el
desarrollo. A un project manager que se encarga de manejar
programadores. A los testers que se encargan de probar código de
programadores. La calidad que intenta arreglar y optimizar todo el
proceso que deben seguir los programadores. En todo esto el punto
clave es: Si nunca fui programador ¿puedo comprenderlos y mejorar su
desarrollo o su forma de trabajo? La respuesta es no.&lt;/p&gt;

&lt;p&gt;El único fin de la Ingeniería en Sistema de Información es hacer un
sistema o mantener un sistema heredado, y la única forma de hacerlo es
comunicándose con la computadora programando. Por lo tanto, los
programadores son la pieza fundamental. Sin programación, no hay
sistema. En consecuencia, deberías comenzar a respetar a los
programadores.&lt;/p&gt;

&lt;p&gt;Consejo: Si estás estudiando Ingeniería en Sistemas de Información,
aprende a programar. Si no te gusta programar, no importa, el mundo
sigue andando con gente que estudió y trabaja de algo que no le gusta,
tal vez a costa del sufrimiento de otros.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Intros</title>
   <link href="https://davidcapello.com/blog/games/intros/"/>
   <updated>2010-12-30T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/games/intros</id>
   <content type="html">&lt;p&gt;La primera intro (u “opening”) que me sorprendió en mi vida fue la de
Tekken para arcade en una pantalla gigante. En el Bowling 10 de
Rosario para ser más precisos hace cientos de años atrás:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/kD1q2eY64o0&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Te ponía la piel de gallina.&lt;/p&gt;

&lt;p&gt;Después la intro de Tekken 2 para PlayStation que era para caerse de
la silla, con una breve introducción a cada personaje y una música
increíble. La veíamos por una vidriera y fue lo que nos decidió
comprar la PlayStation (en un televisor pasaban esto, y en otro la
cabeza de Mario 64, nos decidimos por la PlayStation):&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/lJDN7JxWO90&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Tekken 3 de Arcade:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/0mXK5ZqqffA&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Tekken 3 de PlayStation (nivel cinematográfico, aunque es notorio que
los modelos 3D y la animación todavía no estaban tan avanzadas para
ese entonces):&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/7qmU4wQqKQI&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Igualmente, la intro que más se gravo en mi cabeza es la de Twisted
Metal 2. Con menores recursos que las otras (animación 2D, imágenes
estáticas que se rotan y desplazan, como una animación de Flash) pero
con una voz de fondo espectacular, Welcome to Twisted Metal:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/9LlXGKTBbeM&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;También vale la pena ver los &lt;a href=&quot;http://www.youtube.com/watch?v=v0PWFrMZch8&quot;&gt;finales de Twisted Metal 2&lt;/a&gt;, no tienen desperdicio.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Follow</title>
   <link href="https://davidcapello.com/blog/ideas/follow/"/>
   <updated>2010-12-03T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/follow</id>
   <content type="html">&lt;p&gt;Una importante aclaración sobre el botón “Follow” (&lt;em&gt;Seguir&lt;/em&gt;) de
Twitter, principalmente para los políticos que lo usan: A veces, este
botón no significa algo bueno. Es decir, que un político tenga 100.000
seguidores no significa nada. El “Follow” no equivale a un “Lo voy a
seguir” en repuesta a “Síganme, no los voy a defraudar”. El “Follow”
significa “¡Síganlo, que no se escape!”.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Sueños</title>
   <link href="https://davidcapello.com/blog/ideas/suenios/"/>
   <updated>2010-11-17T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/suenios</id>
   <content type="html">&lt;p&gt;Nunca te vayas a dormir después de usar la computadora. La computadora
roba sueños. Si te preguntas por qué ya no sueñas más, es porque usas
la computadora antes de dormir. 30 o 60 minutos antes lee un cacho de
novela o libro de filosofía. No funciona si lees libros
técnicos.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Simulador Político</title>
   <link href="https://davidcapello.com/blog/ideas/simulador-politico/"/>
   <updated>2010-09-30T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/simulador-politico</id>
   <content type="html">&lt;p&gt;Así como existen simuladores de vuelo para entrenar pilotos, debería
existir un simulador para aspirantes a político. La idea sería
meterlos dentro de una máquina y hasta que no dejan de destruir
naciones, no se los saca al mundo real.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Iostream - Redireccionar clog para "loguear" en un archivo</title>
   <link href="https://davidcapello.com/blog/cpp/iostream-redireccionar-clog-para-loguear-en-un-archivo/"/>
   <updated>2010-09-18T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/iostream-redireccionar-clog-para-loguear-en-un-archivo</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
La &lt;a href=&quot;http://www.cplusplus.com/reference/iostream/&quot;&gt;iostream&lt;/a&gt; es la librería de entrada y salida de C++. Existen algunos &lt;a href=&quot;http://en.wikipedia.org/wiki/Standard_streams&quot;&gt;streams estándares&lt;/a&gt; de salida: std::cout, std::cerr y std::clog. El primero apunta a la consola, y los dos últimos... también. Las diferencias son estas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;cout apunta a la salida estándar STDOUT (texto de resultado esperado de un programa);&lt;br /&gt;&lt;li&gt;cerr y clog apuntan a STDERR (salida de errores y cualquier otra porquería).&lt;br /&gt;&lt;/ul&gt;Aunque a primera vista todo el texto se envía a la consola, uno puede redireccionar la salida a otros lados. Por ejemplo, imaginemos que tenemos el siguiente programa test.exe:&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;A\n&quot;;&lt;br /&gt;  cerr &amp;lt;&amp;lt; &quot;B\n&quot;;&lt;br /&gt;  clog &amp;lt;&amp;lt; &quot;C\n&quot;;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;Al ejecutarlo, obtenemos por pantalla las tres líneas:&lt;pre class=&quot;console&quot;&gt;test.exe [ENTER]&lt;br /&gt;A&lt;br /&gt;B&lt;br /&gt;C&lt;br /&gt;&lt;/pre&gt;Pero resulta interesante saber que podemos redireccionar el STDOUT a un archivo y el STDERR a otro. Ejemplo:&lt;pre class=&quot;console&quot;&gt;test.exe 1&gt;stdout.txt 2&gt;stderr.txt&lt;/pre&gt;¿Qué demonios es 1 y 2? Los archivos tienen un &lt;a href=&quot;http://en.wikipedia.org/wiki/File_descriptor&quot;&gt;descriptor que los identifica&lt;/a&gt;, 1 es para la STDOUT, y 2 para STDERR. El signo mayor (&amp;gt;) significa que &quot;quiero redireccionar toda la salida de texto que vaya para este descriptor a este archivo&quot;. En el anterior ejemplo logramos obtener dos archivos distintos, stdout.txt que contiene una línea (A), y stderr.txt que contiene dos líneas (B y C).&lt;p&gt;Generalmente, los &lt;a href=&quot;http://en.wikipedia.org/wiki/Server_log&quot;&gt;logs&lt;/a&gt; van a un archivo, no a la pantalla. Aunque por defecto clog mande todo a STDERR, resulta útil redireccionar este stream a un archivo propio (por ejemplo, test.log). De esta forma, podemos hacer uso de clog para &quot;loguear&quot; todo lo que nuestro programa hace.&lt;p&gt;&lt;b&gt;¿Cómo se redirecciona clog?&lt;/b&gt; Básicamente los streams de C++ tienen un &lt;a href=&quot;http://www.cplusplus.com/reference/iostream/streambuf/&quot;&gt;streambuf&lt;/a&gt; asociado, y éste es el realmente encargado de leer y escribir datos (en la pantalla, en un archivo, en un string en memoria, etc.). Por lo tanto, si creamos un fstream y le colocamos su propio streambuf a clog, podemos usar clog como un &quot;alias&quot; del fstream original (clog va a estar compartiendo el mismo streambuf que el fstream). El código resultante es bastante sencillo:&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  // Creamos un archivo de salida para logging.&lt;br /&gt;  ofstream test_log;&lt;br /&gt;  test_log.open(&quot;test.log&quot;);&lt;br /&gt;&lt;br /&gt;  // Obtenemos el streambuf actual de clog (esto&lt;br /&gt;  // lo usaremos luego para restaurar el streambuf&lt;br /&gt;  // a su valor original, por si las moscas).&lt;br /&gt;  streambuf* old_rdbuf = clog.rdbuf();&lt;br /&gt;&lt;br /&gt;  // Reemplazamos el streambuf de clog con el del archivo.&lt;br /&gt;  // Ahora ambos streams utilizarán el mismo streambuf (es&lt;br /&gt;  // decir, escriben en el archivo test.log).&lt;br /&gt;  clog.rdbuf(test_log.rdbuf());&lt;br /&gt;&lt;br /&gt;  // Hacemos lo mismo que el ejemplo original.&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;A\n&quot;;&lt;br /&gt;  cerr &amp;lt;&amp;lt; &quot;B\n&quot;;&lt;br /&gt;  clog &amp;lt;&amp;lt; &quot;C\n&quot;;&lt;br /&gt;  &lt;br /&gt;  // Restauramos el viejo streambuf de clog.&lt;br /&gt;  clog.rdbuf(old_rdbuf);&lt;br /&gt;&lt;br /&gt;  // Cerramos el archivo.&lt;br /&gt;  test_log.close();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;Y listo, ahora podemos hacer lo mismo que antes:&lt;pre class=&quot;console&quot;&gt;test.exe 1&gt;stdout.txt 2&gt;stderr.txt&lt;/pre&gt;Con lo cual obtenemos tres archivos:&lt;ul&gt;&lt;li&gt;stdout.txt con la línea A.&lt;br /&gt;&lt;li&gt;stderr.txt con la línea B.&lt;br /&gt;&lt;li&gt;test.log con la línea C.&lt;br /&gt;&lt;/ul&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Compartidor</title>
   <link href="https://davidcapello.com/blog/ideas/compartidor/"/>
   <updated>2010-09-15T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/compartidor</id>
   <content type="html">&lt;p&gt;Detrás del éxito de las redes sociales como Facebook o Twitter, se
esconde uno de los sentimientos más primitivos del ser humano: El
compartir algo que nos gusta. Lamentablemente, en vez de contemplar y
aprovechar al máximo nuestras propias vivencias y emociones,
intentamos rellenar el alma de las demás personas. Así podemos
identificar a un nuevo ser que emerge de la Internet con total
majestuosidad: el compartidor.&lt;/p&gt;

&lt;p&gt;El compartidor no es sólo el tipo que comparte, es el tipo que en su
interior, muy en lo profundo de su ser, cree que todo lo que ve,
escucha, huele y siente, puede ser transmitido a otros. Potenciado a
base de redes sociales, el sentimiento crece en un éxtasis total al
ser compartido lo antes posible con todos los amigos. Con la telefonía
móvil a su favor, destruye sus sentimientos al mismo tiempo que teclea
su próximo mensaje a compartir.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fuerza de gravedad</title>
   <link href="https://davidcapello.com/blog/dev/fuerza-de-gravedad/"/>
   <updated>2010-09-07T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/fuerza-de-gravedad</id>
   <content type="html">&lt;p&gt;El desarrollo de páginas web, y la evolución del universo de la
Internet, tuvo una gran fuerza en su contra que hizo, entre otras
cosas, que una cantidad inimaginable de personas alrededor del mundo
no puedan plasmar sus ideas y creatividad sobre uno de los soportes
más ricos conocidos hoy en día: el hipertexto y la multimedia (dos
palabras prehistóricas). Dicha fuerza se la conoce como Internet
Explorer.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Miembros virtuales</title>
   <link href="https://davidcapello.com/blog/cpp/miembros-virtuales/"/>
   <updated>2010-08-30T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/miembros-virtuales</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Una &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_function&quot;&gt;función miembro virtual&lt;/a&gt; tiene la característica de poder ser sobrecargada por subclases para agregar un comportamiento propio. Pero existen dos lugares en donde las funciones virtuales toman un comportamiento especial: en los constructores y los destructores.&lt;br /&gt;&lt;br /&gt;Veamos el siguiente ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() {                     // El lugar es creado&lt;br /&gt;    creacion();                 // Llamamos a la función virtual&lt;br /&gt;  }&lt;br /&gt;  virtual ~Lugar() {            // El lugar es destruido&lt;br /&gt;    destruccion();              // Llamamos a la función virtual&lt;br /&gt;  }&lt;br /&gt;protected:&lt;br /&gt;  virtual void creacion()    { }&lt;br /&gt;  virtual void destruccion() { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;protected:&lt;br /&gt;  void creacion()    { cout &amp;lt;&amp;lt; &quot;Big Bang\n&quot;; }&lt;br /&gt;  void destruccion() { cout &amp;lt;&amp;lt; &quot;Big Crunch\n&quot;; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god;  // ¿Qué imprime este programa?&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;La idea de todo método virtual es poder proporcionar puntos de extensión a las clases derivadas. En este caso, ¿&lt;i&gt;Lugar::creacion&lt;/i&gt; funciona como punto de extensión para clases derivadas? La respuesta es: no. El anterior programa no imprime nada.&lt;/p&gt;&lt;p&gt;Aunque creamos una instancia de &lt;i&gt;Universo&lt;/i&gt;, ni el método &lt;i&gt;Universo::creacion&lt;/i&gt; ni &lt;i&gt;Universo::destruccion&lt;/i&gt; se llamaron. ¿A qué se debe esto? Imaginemos que al crear un &lt;i&gt;Universo&lt;/i&gt;, primero debemos crear un &lt;i&gt;Lugar&lt;/i&gt; en su totalidad, para luego comenzar a crear el universo. Es por eso que si llamamos a &lt;i&gt;creacion&lt;/i&gt; mientras estamos construyendo el &lt;i&gt;Lugar&lt;/i&gt;, no podemos alcanzar el método &lt;i&gt;Universo::creacion&lt;/i&gt; ya que el &lt;i&gt;Universo&lt;/i&gt; todavía no comenzó a ser construido (no tiene un &lt;i&gt;Lugar&lt;/i&gt; completamente construido donde existir).&lt;/p&gt;&lt;p&gt;La secuencia correcta es:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Alojamos un cacho de memoria suficiente como para que entre el universo.&lt;br /&gt;Algo así como hacer un: &lt;i&gt;this = malloc(sizeof(Universo))&lt;/i&gt; en C.&lt;br /&gt;&lt;li&gt;Construimos el &lt;i&gt;Lugar&lt;/i&gt; usando la memoria recién obtenida como puntero &lt;i&gt;this&lt;/i&gt;.&lt;br /&gt;&lt;li&gt;Luego construimos el &lt;i&gt;Universo&lt;/i&gt;.&lt;br /&gt;&lt;li&gt;Y recién ahí somos capaces de llamar a &lt;i&gt;Universo::creacion&lt;/i&gt; y asegurarnos que estaremos usando el método especializado de la subclase.&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;&lt;b&gt;¿Puedo llamar a &lt;i&gt;creacion&lt;/i&gt; dentro del constructor de &lt;i&gt;Universo&lt;/i&gt;?&lt;/b&gt; La respuesta es sí, todo es posible. ¿Es correcto? Mmmhh, depende, si alguien hace una subclase de &lt;i&gt;Universo&lt;/i&gt; y sobreescribe &lt;i&gt;creacion&lt;/i&gt;, nuevamente estará en el mismo problema que estamos mostrando aquí.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Por qué en el destructor de &lt;i&gt;Lugar&lt;/i&gt; no llama a &lt;i&gt;Universo::destruccion&lt;/i&gt;?&lt;/b&gt; Porque el &lt;i&gt;Universo&lt;/i&gt; ya está destruido (¿cruncheado?) para cuando llegamos al destructor del &lt;i&gt;Lugar&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Cómo lo soluciono?&lt;/b&gt; Usar puntos de extensión en los constructores y destructores presentan más problemas que ventajas. La solución es no usarlos. Solución (obvia):&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() { }&lt;br /&gt;  virtual ~Lugar() { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;public:&lt;br /&gt;  Universo()  { cout &amp;lt;&amp;lt; &quot;Big Bang\n&quot;; }&lt;br /&gt;  ~Universo() { cout &amp;lt;&amp;lt; &quot;Big Crunch\n&quot;; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;En un próximo post voy a dar un ejemplo más complejo donde esto no sirve.&lt;/p&gt;&lt;p&gt;&lt;b&gt;¿Y qué sucede si llamo una función miembro abstracta en el constructor o destructor?&lt;/b&gt; Es el desastre total. Completamente ilegal. Imposible. Una violación absoluta a la razón y el sentido común. Imagine este código:&lt;/p&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Lugar {&lt;br /&gt;public:&lt;br /&gt;  Lugar() { creacion(); }        // Ja llamo a creacion()&lt;br /&gt;protected:&lt;br /&gt;  virtual void creacion() = 0;   // Jaja y no lo defino ;)&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Universo : public Lugar {&lt;br /&gt;protected:&lt;br /&gt;  void creacion() { }            // Jajaja sólo puede llamarme a mí!&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Universo i_am_god_x2;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Al compilar este código con gcc obtenemos un warning porque estamos llamando un método abstractor en el constructor, y un error de enlace al crear el ejecutable ya que &lt;i&gt;Lugar::creacion&lt;/i&gt; no está definido:&lt;/p&gt;&lt;pre class=&quot;console&quot;&gt;test.cpp: In constructor &apos;Lugar::Lugar()&apos;:&lt;br /&gt;test.cpp:7:22: warning: abstract virtual &apos;virtual void Lugar::creacion()&apos; called from constructor&lt;br /&gt;C:\temp\ccstr9Hr.o:test.cpp:(.text$_ZN5LugarC2Ev[Lugar::Lugar()]+0x16): undefined reference to `Lugar::creacion()&apos;&lt;br /&gt;collect2: ld returned 1 exit status&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Aunque dijimos explícitamente que Lugar::creacion() es abstracto (=0), eso no significa que no debamos definirlo en este caso tan particular.&lt;/p&gt;&lt;p&gt;Referencias:&lt;br&gt;Sutter, Herb &amp; Alexandrescu, Andrei (2004). Item 49: Avoid calling virtual functions in constructors and destructors. &lt;em&gt;C++ Coding Standards: 101 Rules, Guidelines, and Best Practices.&lt;/em&gt; Boston, MA: Addison-Wesley Professional, (ISBN 0321113586).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Ridículo</title>
   <link href="https://davidcapello.com/blog/dev/ridiculo/"/>
   <updated>2010-08-22T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/ridiculo</id>
   <content type="html">&lt;p&gt;A veces la gente pide cosas completamente imposibles.
&lt;a href=&quot;http://code.google.com/p/chromium/issues/detail?id=51583&quot;&gt;Esta issue&lt;/a&gt;
de Chromium me hizo reír. El tipo tenía problemas descargando archivos
con su versión de Chrome, reporta la issue, pero al mismo tiempo dice:
“But please don’t ask me to change another version”…&lt;/p&gt;

&lt;p&gt;O sea ¿Tenes un problema con el software que usas pero no querés ni
hacer el mínimo esfuerzo de actualizarlo?  ¿¡Inclusive si eso
significa hacer un simple doble-click?!&lt;/p&gt;

&lt;p&gt;Las respuestas a la issue son geniales.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TODO (a hacer)</title>
   <link href="https://davidcapello.com/blog/ideas/todo-a-hacer/"/>
   <updated>2010-08-05T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/todo-a-hacer</id>
   <content type="html">&lt;p&gt;Supongo que todos (los geeks) suelen tener un txt con una lista de
“cosas a hacer” (un “to do”). Hoy me di cuenta que, con justa razón,
tengo las tareas “a hacer” a un paso de la papelera.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;img-responsive&quot; border=&quot;0&quot; src=&quot;DoNotDo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;¿Será que nunca termino de hacer todo lo que me gustaría hacer?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Botones</title>
   <link href="https://davidcapello.com/blog/dev/botones/"/>
   <updated>2010-08-03T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/botones</id>
   <content type="html">&lt;p&gt;Veamos los siguientes requerimientos. Tenemos tres clases de
botones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Button_%28computing%29&quot;&gt;Button&lt;/a&gt;: El botón
común que al presionarlo ejecuta un comando (OK, Cancel, Yes, No,
Close, Kill Process,
etc.)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Check_box&quot;&gt;Check-box&lt;/a&gt;: Una caja para
poner un tilde.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Radio_button&quot;&gt;Radio-button&lt;/a&gt;: Un
conjunto de botones redondos para seleccionar una opción entre
varias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada clase de botón puede verse y actuar como otra clase al mismo
tiempo. Por ejemplo: un check-box puede verse como un button pero
actuar como check-box, o tres buttons pueden actuar como radio-buttons
pero verse como buttons.&lt;/p&gt;

&lt;p&gt;Además, existen algunas propiedades específicas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Los botones que se ven como buttons pueden tener cuatro valores que
indican la redondez de cada una de las cuatro esquinas. Recuerde que
un check-box o un radio-button puede lucir como un
button.&lt;/li&gt;
  &lt;li&gt;El comportamiento de los radio-buttons necesita de
un grupo que los reuna (por ejemplo, un ID que indica que varios
radio-buttons pertenecen al mismo grupo). Recuerde que un button o
un check-box puede actuar como un
radio-button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img class=&quot;img-responsive&quot; border=&quot;0&quot; src=&quot;Buttons.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;¿Cómo resolvería este problema con objetos?  Esto es un excelente
candidato para aplicar &lt;a href=&quot;http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller&quot;&gt;MVC&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Chistes</title>
   <link href="https://davidcapello.com/blog/ideas/chistes/"/>
   <updated>2010-07-31T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/chistes</id>
   <content type="html">&lt;p&gt;Los eventos de la vida no son aleatorios. Son una hermosa y perfecta
sucesión de chistes que se van desencadenando a medida que
crecemos.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Blogs</title>
   <link href="https://davidcapello.com/blog/ideas/blogs/"/>
   <updated>2010-07-31T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/blogs</id>
   <content type="html">&lt;p&gt;En el futuro, los diarios, las páginas web, los blogs, los microblogs,
SMS y todo medio de comunicación escrito, será reemplazado por una
alternativa más económica y efectiva: El yoctoblogging. Todo podrá ser
dicho con monosílabos: soy, yo, fui, bien, sí, pis, más, mal, gas,
¿vos?, ¿y?…&lt;/p&gt;

&lt;p&gt;El tiempo libre será tan poco que sólo tendremos lo suficiente como
para escribir (y leer) este tipo de mensajes.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tentación</title>
   <link href="https://davidcapello.com/blog/ideas/tentacion/"/>
   <updated>2010-07-27T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/tentacion</id>
   <content type="html">&lt;p&gt;&lt;img class=&quot;img-responsive&quot; border=&quot;0&quot; src=&quot;GoogleChrome.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A veces siento que me mira y me habla… y escucho &lt;em&gt;“vení, haceme
click, dale ;) … tengo un montón de cosas para ofrecerte”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Al final, siempre me defrauda.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Apuntes y creatividad</title>
   <link href="https://davidcapello.com/blog/ideas/apuntes-y-creatividad/"/>
   <updated>2010-07-27T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/apuntes-y-creatividad</id>
   <content type="html">&lt;p&gt;Consejo: Si vas a enseñar una materia en la facultad o un curso, ¿por
qué no agregarle un poco de creatividad al asunto? En vez de usar los
mismos ejemplos del libro de referencia, a veces es bueno inventar
otros (inclusive, evitar usar una escaneada del libro puede ser una
buena idea).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Interfaces gráficas interesantes para diseñar</title>
   <link href="https://davidcapello.com/blog/dev/interfaces-graficas-interesantes-para-diseniar/"/>
   <updated>2010-07-26T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/interfaces-graficas-interesantes-para-diseniar</id>
   <content type="html">&lt;p&gt;Esta es una lista de interfaces gráficas interesantes para
resolver:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Una interfaz gráfica que pueda ser usada inmediatamente por
cualquiera que nunca haya visto una computadora.&lt;/li&gt;
  &lt;li&gt;Un lenguaje de scripting que me permita hacer &lt;em&gt;cualquier cosa&lt;/em&gt; en
el sistema operativo, sin necesidad de escribir una línea de
código. Por ejemplo, una interfaz para configurar una red de pipes
y filtros, donde por las tuberías puede pasar cualquier tipo de
dato (texto, datos binarios crudos, imágenes, audio, logs,
planillas de excel, bases de dato, páginas web, mails, código
fuente, etc.) y los filtros los pueden transformar en cualquier
cosa.&lt;/li&gt;
  &lt;li&gt;Una interfaz que permita hacer control de versiones con Git con
varios repositorios remotos de forma totalmente gráfica, sólo con
el mouse. Comandos complejos como rebase podrían ser un simple drag
and drop. Debería poder tener una visión de cada repositorio como
una pequeña computadora a la que le puedo hacer pull y push (por
branch). Etc.&lt;/li&gt;
  &lt;li&gt;Un editor de texto como Microsoft Word o OpenOffice.org Writer que
produzca documentos de tan buena calidad como LaTeX.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sólo ideas. ¿Para proyectos open source? ¿para proyectos comerciales?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Alcance</title>
   <link href="https://davidcapello.com/blog/scifi/alcance/"/>
   <updated>2010-07-26T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/scifi/alcance</id>
   <content type="html">&lt;p&gt;Estaba comiendo en un bar. Levanto la vista y miro el televisor. Un
tipo pidiendo limosna a un periodista. El periodista lo mira y le
dice: “Señor, yo estoy para mostrarle al mundo sus miserias”. El tipo
pega la vuelta y sigue comiendo basura. Yo sigo comiendo. Un pibe se
acerca y me pide limosna. Lo miro, le doy una moneda, y pienso: “Que
poco puedo cambiar este mundo”. Sigo comiendo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cuentos</title>
   <link href="https://davidcapello.com/blog/scifi/cuentos/"/>
   <updated>2010-07-25T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/scifi/cuentos</id>
   <content type="html">&lt;p&gt;Un día un tipo se levantó de la cama y se puso a escribir un
cuento. Para la noche ya lo había terminado. El cuento era tan bueno
que no podía creerlo. Lo leyó una y otra vez, era increíble.&lt;/p&gt;

&lt;p&gt;Nunca más vieron al tipo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Con el cerebro</title>
   <link href="https://davidcapello.com/blog/ideas/con-el-cerebro/"/>
   <updated>2010-07-25T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/ideas/con-el-cerebro</id>
   <content type="html">&lt;p&gt;Llegará el día que programaremos con el cerebro. Los atajos de teclado
no servirán de nada. Simplemente miro una ubicación, pienso en qué
quiero escribir y… BAM! ahí van apareciendo las letras por arte de
magia.&lt;/p&gt;

&lt;p&gt;Eso es un editor de texto.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Descargar MinGW con gcc 4.5 automáticamente</title>
   <link href="https://davidcapello.com/blog/cpp/descargar-mingw-con-gcc-4-5-automaticamente/"/>
   <updated>2010-06-06T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/descargar-mingw-con-gcc-4-5-automaticamente</id>
   <content type="html">&lt;p&gt;Este post se podría llamar:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;¿Cómo instalar MinGW? &lt;br /&gt;
¿Cómo instalar y usar gcc 4.5 en Windows? &lt;br /&gt;
¿Cómo compilar programas de C o C++ en Windows? &lt;br /&gt;
O también, ¿puedo portar MinGW en un pendrive?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cualquiera de los casos se responde con el siguiente archivo:
&lt;a href=&quot;https://github.com/dacap/mingw-downloader#readme&quot;&gt;MinGW-Downloader.zip&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Los pasos a seguir son los siguientes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Cree una carpeta donde descomprimir &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MinGW-Downloader.zip&lt;/code&gt; (por
ejemplo, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers&lt;/code&gt;, o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\GNU&lt;/code&gt;, lo importante es que la
carpeta no contenga espacios!)&lt;/li&gt;
  &lt;li&gt;Descomprima &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MinGW-Downloader.zip&lt;/code&gt; en esa carpeta&lt;/li&gt;
  &lt;li&gt;Ejecute el archivo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5-Downloader.bat&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Espere…&lt;/li&gt;
  &lt;li&gt;Una vez finalizado deberá ver algunos mensajes en la pantalla
diciéndole si tuvo éxito (SUCCESS), inclusive el script intenta
compilar un programa en C y otro en C++.&lt;/li&gt;
  &lt;li&gt;Listo, ya tiene MinGW con gcc 4.5 disponible en su máquina.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Puede usar el script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run-cmd-with-MinGW-4.5.bat&lt;/code&gt; para ejecutar la
línea de comandos de Windows y tener el compilador disponible (gcc,
g++, etc.) en la variable PATH. Lo importante es que el proceso de
descarga no modifica ninguna variable de entorno suya (PATH), por lo
tanto, podría borrar la carpeta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers&lt;/code&gt; y empezar desde cero
siempre que así lo desee.&lt;/p&gt;

&lt;p&gt;Puede mover la carpeta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5&lt;/code&gt; a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\MinGW-4.5&lt;/code&gt; y borrar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers\MinGW-Downloader&lt;/code&gt;
completamente. Si quiere tener el compilador disponible desde
cualquier aplicación (por ejemplo, desde un editor de texto o IDE),
podría agregar la ruta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\MinGW-4.5\bin&lt;/code&gt; a su PATH.&lt;/p&gt;

&lt;p&gt;Cabe destacar que la carpeta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MinGW-4.5&lt;/code&gt;
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Compilers\MinGW-Downloader\MinGW-4.5&lt;/code&gt;) y el archivo
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run-cmd-with-MinGW-4.5.bat&lt;/code&gt; los puede mover donde usted desee (por
ejemplo, llevarlos en un pen drive), sólo tenga en cuenta que para
hacer esto los dos tienen que estar en el mismo directorio
(e.j. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\MinGW-4.5&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Run-cmd-with-MinGW-4.5.bat&lt;/code&gt;).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Shared Pointers de C++0x</title>
   <link href="https://davidcapello.com/blog/cpp/shared-pointers-de-cpp0x/"/>
   <updated>2010-05-29T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/shared-pointers-de-cpp0x</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
En C usted puede hacer esto:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&lt;br /&gt;struct Persona { };&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Persona* a = malloc(sizeof(Persona));&lt;br /&gt;  free(a);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Un ejemplo equivalente en C++:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Persona { };&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Persona* a = new Persona();&lt;br /&gt;  delete a;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por cada &lt;b&gt;malloc&lt;/b&gt; existe un &lt;b&gt;free&lt;/b&gt; (al menos que use reallocs), y por cada &lt;b&gt;new&lt;/b&gt; existe un &lt;b&gt;delete&lt;/b&gt; (y por cada new[] un delete[]).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Existe una forma por la cual C++ se &quot;entere&quot; que ya no quiero usar un puntero?&lt;/b&gt; La respuesta es: No, no existe. C++ no tiene un &lt;a href=&quot;http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&quot;&gt;garbage collector&lt;/a&gt;. Pero existen &lt;a href=&quot;http://cmasomenos.blogspot.com/2009/11/punteros-por-ambito-scoped-pointers.html&quot;&gt;clases que pueden ayudarnos&lt;/a&gt;, como el viejo y tan poco querido &lt;a href=&quot;http://cmasomenos.blogspot.com/2008/06/excepciones-raii-y-autoptr.html&quot;&gt;auto_ptr&lt;/a&gt;, o los mejorados &lt;a href=&quot;http://www.google.com/search?q=unique_ptr+Class&amp;btnI=1&quot;&gt;unique_ptr&lt;/a&gt;, &lt;a href=&quot;http://www.google.com/search?q=shared_ptr+Class&amp;btnI=1&quot;&gt;shared_ptr&lt;/a&gt; y &lt;a href=&quot;http://www.google.com/search?q=weak_ptr+Class&amp;btnI=1&quot;&gt;weak_ptr&lt;/a&gt; del nuevo estándar de C++0x (o el &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B_Technical_Report_1#Smart_pointers&quot;&gt;TR1&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Un &lt;em&gt;shared pointer&lt;/em&gt; es una clase que se encarga de guardar un puntero a un objeto (o tipo de dato), y cuenta la cantidad de referencias que se están haciendo a dicho objeto (es decir, la cantidad de shared pointers que apuntan al mismo objeto). El último shared pointer que se destruya (cuando las referencias llegan a cero), será el encargado de borrar el objeto apuntado (mediante un simple delete).&lt;br /&gt;&lt;br /&gt;Un ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;  // Aquí debería estar shared_ptr&amp;lt;&amp;gt; (GCC 4.4)&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class Persona {&lt;br /&gt;  int n;&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;  Persona(int n) : n(n) {&lt;br /&gt;    cout &amp;lt;&amp;lt; &quot;Nace la persona &quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ~Persona() { &lt;br /&gt;    cout &amp;lt;&amp;lt; &quot;Muere la persona &quot; &amp;lt;&amp;lt; n &amp;lt;&amp;lt; &quot;\n&quot;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static shared_ptr&amp;lt;Persona&amp;gt; Crear(int n) { &lt;br /&gt;    return shared_ptr&amp;lt;Persona&amp;gt;(new Persona(n));&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; a(new Persona(1));&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; b = Persona::Crear(2);&lt;br /&gt;  shared_ptr&amp;lt;Persona&amp;gt; c;&lt;br /&gt;&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;--- Aquí ambas personas existen ---\n&quot;;&lt;br /&gt;&lt;br /&gt;  c = a; // Aquí c apunta a la persona 1&lt;br /&gt;  b = c; // Ahora b apuntará a la persona 1 (la persona 2 muere porque&lt;br /&gt;         // ya no existen referencias a ella)&lt;br /&gt;&lt;br /&gt;  cout &amp;lt;&amp;lt; &quot;--- Aquí la persona 2 ya no existe ---\n&quot;;&lt;br /&gt;  &lt;br /&gt;  return 0;&lt;br /&gt;}        // Aquí muere la persona 1 (a, b, c apuntaban a ella)&lt;br /&gt;&lt;/pre&gt;La salida del anterior programa es esta:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;Nace la persona 1&lt;br /&gt;Nace la persona 2&lt;br /&gt;--- Aquí ambas personas existen ---&lt;br /&gt;Muere la persona 2&lt;br /&gt;--- Aquí la persona 2 ya no existe ---&lt;br /&gt;Muere la persona 1&lt;br /&gt;&lt;/pre&gt;Como puede ver, en el anterior programa se llama sólo dos veces a &quot;new Persona&quot; y dos veces al destructor ~Persona. No debemos preocuparnos por usar &quot;delete&quot;, el shared_ptr&amp;lt;&amp;gt; hace todo por nosotros.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Cómo hago para que la clase shared_ptr funcione en VS2008 SP1 Express?&lt;/b&gt; Debe definir _HAS_TR1 antes de incluir el archivo &amp;lt;memory&amp;gt;. Ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#ifdef _MSC_VER      // Si estamos usando el compilador de Microsoft&lt;br /&gt;  #define _HAS_TR1 1 // Esto hará que se incluyan las clases del TR1 (std::tr1)&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;memory&amp;gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;#ifdef _MSC_VER&lt;br /&gt;  using namespace std::tr1; // para tener shared_ptr&amp;lt;&amp;gt; disponible&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;// Resto del ejemplo...&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>C++0x Final Committee Draft (FCD)</title>
   <link href="https://davidcapello.com/blog/cpp/cpp0x-final-committee-draft-fcd/"/>
   <updated>2010-03-31T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/cpp0x-final-committee-draft-fcd</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Ya está disponible el documento N3092, &lt;em&gt;Programming Languages — C++, Final Committee Draft&lt;/em&gt;. Este documento es el que más podría corresponder al nuevo estándar ISO de C++ (lo que viene de acá a uno o dos años pueden ser correcciones menores):&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf&quot;&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Más información &lt;a href=&quot;http://herbsutter.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/&quot;&gt;acá&lt;/a&gt;.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Improving your applications by statistics</title>
   <link href="https://davidcapello.com/blog/dev/improving-your-applications-by-statistics/"/>
   <updated>2010-03-03T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/dev/improving-your-applications-by-statistics</id>
   <content type="html">&lt;p&gt;If you developed an application and published it in a website, you can
use things like google-analytics data to adjust your
application. E.g. If everybody is accessing your website with 32-bits,
24-bits and 16-bits screen resolutions, you can discard all
considerations about 8-bits modes in your application.&lt;/p&gt;

&lt;p&gt;Things you should add to your application:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A way to get usage data from your users. E.g. where they do click,
how they call commands (menus, keyboard, toolbars, ribbons,
etc.). In this way you could focus improvement in the more common
methods to run commands.&lt;/li&gt;
  &lt;li&gt;A way to count how many times a command was used. Maybe there are
commands that are rarely used, these commands could be more deeper
in menus hierarchies and without keyboard shortcut.&lt;/li&gt;
  &lt;li&gt;A way to known systems where your application is
running. E.g. operating system, version, screen resolution,
etc. Improve usability in the most used platform.&lt;/li&gt;
  &lt;li&gt;A way to known how many computers are running a specific version of
your application. If a version is not used anymore, you can stop
supporting it (E.g. Adding patches for a version that nobody
uses).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this must be done carefully, with proper check-boxes like “Do you
want to send anonymous data about your usage to improve customer
experience?” in installers, splash screens, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.eclipse.org/epp/usagedata/&quot;&gt;There are some frameworks&lt;/a&gt; to
do this kind of work. Anyway you basically need:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An HTTP server to accept packages from users (e.g. through POST
requests). Each request should be processed by a script (in PHP,
ASP, etc.) which should convert the received package into database
model.&lt;/li&gt;
  &lt;li&gt;A way to differentiate users (you could SHA1 some string like “local
user name + pc host name + app name version”). Here I don’t know if
the IP could be a good way idea (NAT problems, etc.).&lt;/li&gt;
  &lt;li&gt;A way to make HTTP requests from your application (firewall + proxy
problems) of all collected usage data of the user (identified by the
SHA1).&lt;/li&gt;
  &lt;li&gt;A mini-program to process all the database and print some useful
reports.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Emacs: How to open the current buffer with associated application?</title>
   <link href="https://davidcapello.com/blog/emacs/emacs-how-to-open-the-current-buffer-with-associated-application/"/>
   <updated>2010-03-02T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/emacs/emacs-how-to-open-the-current-buffer-with-associated-application</id>
   <content type="html">&lt;p&gt;The following function tries to run the application associated with
the current buffer file type (e.g. if you use this function in an
.html file, the file will be opened with your default web browser):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(defun open-current-file-with-associated-app ()
  (interactive)
  (shell-command (concat &quot;cmd /c \&quot;start &quot; (buffer-file-name) &quot;\&quot;&quot;)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Emacs: How to locate the current buffer in Windows Explorer?</title>
   <link href="https://davidcapello.com/blog/emacs/emacs-how-to-locate-the-current-buffer-in-windows-explorer/"/>
   <updated>2010-03-02T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/emacs/emacs-how-to-locate-the-current-buffer-in-windows-explorer</id>
   <content type="html">&lt;p&gt;You can use the following function to open the Windows Explorer in the directory of the current buffer:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(defun locate-current-file-in-explorer ()
  (interactive)
  (cond
   ;; In buffers with file name
   ((buffer-file-name)
    (shell-command (concat &quot;start explorer /e,/select,\&quot;&quot; (replace-regexp-in-string &quot;/&quot; &quot;\\\\&quot; (buffer-file-name)) &quot;\&quot;&quot;)))
   ;; In dired mode
   ((eq major-mode &apos;dired-mode)
    (shell-command (concat &quot;start explorer /e,\&quot;&quot; (replace-regexp-in-string &quot;/&quot; &quot;\\\\&quot; (dired-current-directory)) &quot;\&quot;&quot;)))
   ;; In eshell mode
   ((eq major-mode &apos;eshell-mode)
    (shell-command (concat &quot;start explorer /e,\&quot;&quot; (replace-regexp-in-string &quot;/&quot; &quot;\\\\&quot; (eshell/pwd)) &quot;\&quot;&quot;)))
   ;; Use default-directory as last resource
   (t
    (shell-command (concat &quot;start explorer /e,\&quot;&quot; (replace-regexp-in-string &quot;/&quot; &quot;\\\\&quot; default-directory) &quot;\&quot;&quot;)))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How it works?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you are visiting a buffer associated to a file (with
buffer-file-name), the Windows Explorer is opened to focus the file
in its directory.&lt;/li&gt;
  &lt;li&gt;If you are in dired mode (browsing a directory inside Emacs with
dired-mode), it will open that directory in Windows Explorer.&lt;/li&gt;
  &lt;li&gt;If you are in eshell-mode, the current working directory will be
opened in Windows Explorer.&lt;/li&gt;
  &lt;li&gt;As last chance it will open the Windows Explorer in the default
directory (where you start emacs). E.g. This can happen if you use
this function in &lt;em&gt;scratch&lt;/em&gt; buffer (which is a buffer without an
associated file).&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>STL string, parseando un número de versión</title>
   <link href="https://davidcapello.com/blog/cpp/stl-string-parseando-un-numero-de-version/"/>
   <updated>2010-01-27T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/stl-string-parseando-un-numero-de-version</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
En esta ocasión vamos a ver cómo usar la clase &lt;em&gt;std::string&lt;/em&gt; para convertir una cadena de caracteres (como &quot;1.2.3&quot;) en una clase &quot;Version&quot; que tenga una interfaz simple de utilizar (por ejemplo, que permita comparar versiones).&lt;br /&gt;&lt;br /&gt;Los pasos son simples:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;tenemos como entrada una cadena de caracteres,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;dividimos la cadena según el caracter &apos;.&apos; (punto),&lt;br /&gt;&lt;/li&gt;&lt;li&gt;convertimos cada parte a entero,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;guardamos cada número entero de forma ordenada en un vector.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;El punto 2 es en el cual nos vamos a enfocar más. &lt;em&gt;El código mostrado aquí es a modo de ejemplo, y está lejos de ser el más óptimo.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Antes de comenzar ¿Podemos usar &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstring/strcmp/&quot;&gt;strcmp&lt;/a&gt; para comparar dos versiones?&lt;/b&gt; No, no podemos. Ejemplo: strcmp(&quot;1.9&quot;, &quot;1.10&quot;) &amp;gt; 0, cuando en realidad la versión 1.9 es menor a 1.10.&lt;br /&gt;&lt;br /&gt;Imaginemos que tenemos una cadena: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string ver = &quot;1.10.2.3&quot;;&lt;br /&gt;&lt;/pre&gt;La clase &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/&quot;&gt;std::string&lt;/a&gt; tiene la función miembro &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/find/&quot;&gt;find&lt;/a&gt;, la cual podemos usar para buscar casi cualquier cosa dentro de la cadena. ¿Qué debemos buscar? Los puntos, sabiendo donde está cada punto, podemos ir recortando la cadena en sus distintas partes (&quot;1&quot;, &quot;10&quot;, &quot;2&quot;, y &quot;3&quot;). Buscamos la ubicación del primer punto: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;size_t i = ver.find(&apos;.&apos;);&lt;br /&gt;&lt;br /&gt;if (i != std::string::npos)&lt;br /&gt;  std::printf(&quot;El punto fue encontrado en la posición %d\n&quot;, i);&lt;br /&gt;else&lt;br /&gt;  std::printf(&quot;No hay punto en la cadena\n&quot;);&lt;br /&gt;&lt;/pre&gt;Ejecutando el código anterior, deberíamos obtener el mensaje: &lt;br /&gt;&lt;pre&gt;El punto fue encontrado en la posición 1&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Qué es &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstring/size_t/&quot;&gt;size_t&lt;/a&gt;?&lt;/b&gt; Es como el tipo &quot;unsigned int&quot;, el tipo de dato retornado por el operador &lt;a href=&quot;http://www.cppreference.com/wiki/keywords/sizeof&quot;&gt;sizeof()&lt;/a&gt; y utilizado como índice en las funciones de std::string.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Qué es &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/npos/&quot;&gt;std::string::npos&lt;/a&gt;?&lt;/b&gt; Es el máximo valor posible de un &lt;em&gt;size_t&lt;/em&gt; y se utiliza para indicar (en este caso) que la función &lt;em&gt;find&lt;/em&gt; falló (no encontró el punto).&lt;br /&gt;&lt;br /&gt;Una vez que tenemos la posición del punto, podemos obtener la porción de texto que contiene la primer cifra, para eso usamos la función miembro &lt;a href=&quot;http://www.cplusplus.com/reference/string/string/substr/&quot;&gt;substr&lt;/a&gt;: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string primer_cifra = ver.substr(0, i);&lt;br /&gt;&lt;/pre&gt;Esto significa: &lt;em&gt;che vos, función substr, devolveme el pedazo de cadena de caracteres que va desde el índice 0, y tiene una longitud de i-caracteres.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;El proceso puede ser repetido tantas veces como queramos para seguir obteniendo cifras. Por ejemplo, para la siguiente cifra debemos buscar (find) el siguiente punto, pero comenzando desde el que encontramos hace un rato: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;i++;     // ir a la posición siguiente del punto &apos;.&apos;&lt;br /&gt;size_t j = ver.find(&apos;.&apos;, i);&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;¿Qué es (o hace) el segundo argumento de find?&lt;/b&gt; Le indica a la función desde donde debe comenzar a buscar. La primera vez que usamos find este argumento no se especificó, porque por omisión toma el valor 0, es decir, buscar desde el inicio de la cadena.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Por qué i++?&lt;/b&gt; Porque si comenzáramos a buscar un punto desde &lt;em&gt;i&lt;/em&gt;, nos devolvería la misma posición &lt;em&gt;i&lt;/em&gt; (porque justamente, en &lt;em&gt;i&lt;/em&gt;, está el primer punto que encontramos). Entonces debemos avanzar una posición.&lt;br /&gt;&lt;br /&gt;Ahora, debemos recortar la segunda cifra: &lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::string segunda_cifra = ver.substr(i, j-i);&lt;br /&gt;&lt;/pre&gt;La segunda cifra, comienza desde &lt;em&gt;i&lt;/em&gt; y tiene una longitud igual a &lt;em&gt;j-i&lt;/em&gt;. Para comprender esto, vea la siguiente figura:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;155&quot; src=&quot;std_string_indices.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;De esta forma, &lt;em&gt;ver.substr(i, j-i)&lt;/em&gt; nos devuelve la cadena &quot;10&quot;. La versión completa del algoritmo puede quedar algo así:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;vector&amp;gt;  // Por std::vector&lt;br /&gt;#include &amp;lt;string&amp;gt;  // Por std::string&lt;br /&gt;#include &amp;lt;cstdlib&amp;gt; // Por std::strtol&lt;br /&gt;#include &amp;lt;cstdio&amp;gt;  // Por std::printf&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  std::string ver = &quot;1.10.2.3&quot;;&lt;br /&gt;&lt;br /&gt;  // Vector con cada cifra.&lt;br /&gt;  // Luego del procesamiento esto debería ser = { 1, 10, 2, 3 }&lt;br /&gt;  std::vector&amp;lt;int&amp;gt; cifras;&lt;br /&gt;&lt;br /&gt;  size_t i = 0;   // Comenzamos desde i=0&lt;br /&gt;  size_t j = 0;&lt;br /&gt;&lt;br /&gt;  // Repetir hasta no llegar al final de la cadena&lt;br /&gt;  while (j != std::string::npos) {&lt;br /&gt;    // Buscar próximo punto&lt;br /&gt;    j = ver.find(&apos;.&apos;, i);&lt;br /&gt;&lt;br /&gt;    std::string cifra;&lt;br /&gt;&lt;br /&gt;    // Si se encontró un punto&lt;br /&gt;    if (j != std::string::npos) {&lt;br /&gt;      // Recortamos desde i hasta j&lt;br /&gt;      cifra = ver.substr(i, j-i);&lt;br /&gt;&lt;br /&gt;      // El nuevo comienzo para buscar puntos será &quot;j+1&quot;&lt;br /&gt;      i = j+1;&lt;br /&gt;    }&lt;br /&gt;    // Si no se encontró un punto&lt;br /&gt;    else {&lt;br /&gt;      // Recortamos desde &quot;i&quot; hasta el final de la cadena&lt;br /&gt;      cifra = ver.substr(i);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Obtener el valor entero de la cifra&lt;br /&gt;    int cifra_int = std::strtol(cifra.c_str(), NULL, 10);&lt;br /&gt;&lt;br /&gt;    // Agregar la cifra al vector&lt;br /&gt;    cifras.push_back(cifra_int);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  for (size_t i=0; i&amp;lt;cifras.size(); ++i)&lt;br /&gt;    printf(&quot;cifras[%d] = %d\n&quot;, i, cifras[i]);&lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;La salida del anterior programa es:&lt;br /&gt;&lt;pre&gt;cifras[0] = 1&lt;br /&gt;cifras[1] = 10&lt;br /&gt;cifras[2] = 2&lt;br /&gt;cifras[3] = 3&lt;br /&gt;&lt;/pre&gt;Con este código, podríamos implementar una clase &quot;Version&quot; con la siguiente interfaz:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Version&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;  Version(const char*);&lt;br /&gt;  Version(const std::string&amp;amp;);&lt;br /&gt;&lt;br /&gt;  bool operator==(const Version&amp;amp; u) const;&lt;br /&gt;  bool operator&amp;lt;(const Version&amp;amp; u) const;&lt;br /&gt;  // ...&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;En un próximo post voy a colocar una posible implementación de la clase &quot;Version&quot;.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Punteros por ámbito (scoped pointers)</title>
   <link href="https://davidcapello.com/blog/cpp/punteros-por-ambito-scoped-pointers/"/>
   <updated>2009-11-06T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/punteros-por-ambito-scoped-pointers</id>
   <content type="html">&lt;p&gt;C++ no tiene un
&lt;a href=&quot;http://es.wikipedia.org/wiki/Recolector_de_basura&quot;&gt;recolector de basura&lt;/a&gt;,
&lt;a href=&quot;http://www.research.att.com/~bs/C++0xFAQ.html#gc-abi&quot;&gt;aunque C++0x le va tomando el gustito&lt;/a&gt;,
tenemos algunas opciones para liberarnos de liberar memoria, valga la
redundancia.&lt;/p&gt;

&lt;p&gt;Imaginemos un código como el siguiente:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;

using namespace std;

class A {
public:
  A()         { printf(&quot;A\n&quot;);    }
  ~A()        { printf(&quot;~A\n&quot;);   }
  void hola() { printf(&quot;hola\n&quot;); }
};

int main()
{
  A* a = new A;
  a-&amp;gt;hola();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El anterior programa, por más minimalista que
parezca, tiene un &lt;a href=&quot;http://en.wikipedia.org/wiki/Memory_leak&quot;&gt;memory leak&lt;/a&gt;.
Aunque los &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_%28computer_science%29&quot;&gt;recursos&lt;/a&gt;
suelen ser liberados por el mismo sistema operativo al finalizar el
programa, si el proceso se ejecuta por mucho tiempo (e.j. un servicio
que se ejecuta por días, semanas o meses dentro de un servidor), los
recursos se van agotando poco a poco hasta que la computadora queda
hecha una &lt;a href=&quot;http://es.wikipedia.org/wiki/Pasa&quot;&gt;pasa&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para arreglar el leak, deberíamos escribir:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int main()
{
  A* a = new A;
  a-&amp;gt;hola();
  delete a;      // Ahora sí liberamos la memoria
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo hacemos para liberar memoria sin llamar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt; nosotros mismos?&lt;/strong&gt;
Podemos crear una clase utilitaria que haga el trabajo por nosotros en
su destructor. Por ejemplo, en el siguiente código veremos que el
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt; es llamado en el destructor de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class PunteroA {
  A* ptr;
public:
  PunteroA(A* p) { ptr = p; }
  ~PunteroA()    { delete ptr; }  // en el destructor borramos &apos;ptr&apos;
};

int main()
{
  PunteroA a(new A);
  a-&amp;gt;hola();          // error, &quot;a&quot; no es un puntero ni sobrecarga operator-&amp;gt;
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El anterior programa nos dará un error de compilación ya que el tipo
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt; no soporta el operador flecha. Debemos agregarlo en la
definición de la clase &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class PunteroA {
  A* ptr;
public:
  PunteroA(A* p)  { ptr = p; }
  ~PunteroA()     { delete ptr; }
  A* operator-&amp;gt;() { return ptr; } // operador flecha para acceder al puntero
};

int main()
{
  PunteroA a(new A);
  a-&amp;gt;hola();        // ahora sí, PunteroA::operator-&amp;gt;() nos devuelve
                    // el verdadero puntero A* y A::hola() finalmente
                    // es llamado
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo obtengo el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A*&lt;/code&gt; desde un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt;?&lt;/strong&gt; Debemos definir el operador de conversión hacia &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A*&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class PunteroA {
  A* ptr;
public:
  PunteroA(A* p)  { ptr = p; }
  ~PunteroA()     { delete ptr; }
  A* operator-&amp;gt;() { return ptr; }
  operator A*()   { return ptr; } // operador para castear a A*
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Así podemos usar un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt; en funciones que reciban un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A*&lt;/code&gt;. Ejemplo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void func(A* a) { ... }

int main()
{
  PunteroA a(new A);
  func(a);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Generalizando:&lt;/strong&gt; Podemos generalizar nuestro &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PunteroA&lt;/code&gt; para cualquier tipo de dato:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template&amp;lt;class T&amp;gt;
class ScopedPointer {
  T* ptr;
public:
  ScopedPointer(T* p) { ptr = p; }
  ~ScopedPointer()    { delete ptr; }

  operator T*()       { return ptr; }
  T* operator-&amp;gt;()     { return ptr; }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Así podemos usar el mismo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ScopedPointer&lt;/code&gt; para liberar instancias de cualquier clase:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int main()
{
  ScopedPointer&amp;lt;A&amp;gt; a(new A);
  ScopedPointer&amp;lt;B&amp;gt; b(new B);
  a-&amp;gt;hola();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;¿Y si quiero liberar otro tipo de recurso?&lt;/strong&gt; Si el recurso no es
memoria, y es liberado con otra función en vez de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt;, podemos
generalizar nuestro &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ScopedPointer&lt;/code&gt; con un nuevo parámetro de template
llamado &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Destroyer&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct DefaultDestroyer {
  template&amp;lt;class T&amp;gt;
  static void free(T* ptr) { delete ptr; }
};

template&amp;lt;class T, class Destroyer = DefaultDestroyer&amp;gt;
class ScopedPointer {
  T* ptr;
public:
  ScopedPointer(T* p) { ptr = p; }
  ~ScopedPointer()    { Destroyer::free(ptr); }

  operator T*()       { return ptr; }
  T* operator-&amp;gt;()     { return ptr; }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En este caso, el destructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~ScopedPointer&lt;/code&gt; llama a la función
estática &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Destroyer::free&lt;/code&gt;. Esta función básicamente puede hacer lo que
nosotros queramos. Podría ser útil para liberar ficheros o cualquier
otro tipo de recurso:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct FileDestroyer {
  static void free(FILE* ptr) { fclose(ptr); }
};

int main()
{
  ScopedPointer&amp;lt;FILE, FileDestroyer&amp;gt; file(fopen(&quot;hola.txt&quot;, &quot;rt&quot;));
  char buf[256];
  fread(buf, 1, 256, file);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;¿No existen punteros de este tipo ya implementados?&lt;/strong&gt;
&lt;a href=&quot;http://www.boost.org/&quot;&gt;Boost&lt;/a&gt; tiene su propio &lt;a href=&quot;http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/scoped_ptr.htm&quot;&gt;scoped_ptr&lt;/a&gt;.
También existen punteros más avanzados que cuentan referencias, como los &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B0x#General-purpose_smart_pointers&quot;&gt;smart pointers&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Interfaces vs. Conceptos</title>
   <link href="https://davidcapello.com/blog/cpp/interfaces-vs-conceptos/"/>
   <updated>2009-10-18T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/interfaces-vs-conceptos</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
¿Qué son los conceptos? Vamos a ver con un simple ejemplo, cómo podemos hacer una equivalencia entre las conocidas &lt;a href=&quot;http://en.wikipedia.org/wiki/Interface_(computer_science)&quot;&gt;interfaces&lt;/a&gt; y los &lt;a href=&quot;http://en.wikipedia.org/wiki/Concept_(generic_programming)&quot;&gt;conceptos&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Imaginen esta &quot;interfaz&quot; (clase abstracta):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class IPortero {&lt;br /&gt;public:&lt;br /&gt;  virtual IPortero() { }&lt;br /&gt;  virtual void ir_a_piso(int piso) = 0;&lt;br /&gt;  virtual int piso_destino() = 0;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Tenemos otra clase Ascensor que podemos &quot;personalizar&quot; con nuestro propio portero, así nuestra implementación de portero puede hacer &lt;a href=&quot;http://es.wikipedia.org/wiki/Ascensor#Algoritmos_de_Maniobras&quot;&gt;lo que se le de la gana&lt;/a&gt;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class Ascensor {&lt;br /&gt;  IPortero* m_portero;&lt;br /&gt;public:&lt;br /&gt;  Ascensor(IPortero* portero) {&lt;br /&gt;    m_portero = portero;&lt;br /&gt;  }&lt;br /&gt;  void apretaron_boton_en_piso(int piso) {&lt;br /&gt;    m_portero-&gt;ir_a_piso(piso);&lt;br /&gt;    mover_ascensor(m_portero-&gt;piso_destino());&lt;br /&gt;  }&lt;br /&gt;  void mover_ascensor(int piso) { ... }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Con programación genérica, podemos reformular la interfaz convirtiéndola en un &quot;concepto&quot; y la clase Ascensor en una clase plantilla:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;template&amp;lt;class TipoPortero&amp;gt;&lt;br /&gt;class Ascensor {&lt;br /&gt;  TipoPortero m_portero;&lt;br /&gt;public:&lt;br /&gt;  Ascensor() { }&lt;br /&gt;  void apretaron_boton_en_piso(int piso) {&lt;br /&gt;    m_portero.ir_a_piso(piso);&lt;br /&gt;    mover_ascensor(m_portero.piso_destino());&lt;br /&gt;  }&lt;br /&gt;  void mover_ascensor(int piso) { ... }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;La pregunta es, &lt;em&gt;¿qué demonios es TipoPortero?&lt;/em&gt;. La respuesta es sencilla: TipoPortero puede ser cualquier tipo de dato que cumpla los siguientes requisitos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tenga un constructor por omisión (que se pueda construir un nuevo TipoPortero sin argumentos, o sea, &lt;em&gt;TipoPortero()&lt;/em&gt;).&lt;br /&gt;&lt;li&gt;Tenga una función miembro &lt;em&gt;TipoPortero::ir_a_piso(int)&lt;/em&gt;, la cual recibe un &quot;int&quot; (o cualquier tipo de dato que se pueda construir desde un &quot;int&quot; implícitamente).&lt;br /&gt;&lt;li&gt;Y otra función miembro &lt;em&gt;TipoPortero::piso_destino()&lt;/em&gt; que devuelve un entero.&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;¿Cómo especificamos la &quot;interfaz&quot; o los &quot;requerimientos&quot; de un concepto?&lt;/b&gt; Sencillamente no se puede, &lt;a href=&quot;http://cmasomenos.blogspot.com/2009/07/c0x-no-va-tener-conceptos.html&quot;&gt;C++0x iba a soportar esto&lt;/a&gt;, pero ya no. Hoy en día la mejor respuesta es usar algunos comentarios en la clase Ascensor que especifiquen qué espera en sus parámetros de template. En este aspecto se podría decir que IPortero es mejor porque especifica explícitamente lo que el portero tiene que hacer (funciones a implementar, etc.).&lt;p&gt;&lt;b&gt;¿Qué ventaja tiene el concepto con respecto a las interfaces?&lt;/b&gt; La clase genérica Ascensor ahora tiene el mismo portero adentro suyo (no un puntero a la interfaz). Las llamadas a las funciones miembro &lt;em&gt;ir_a_piso&lt;/em&gt; y &lt;em&gt;piso_destino&lt;/em&gt; son llamadas directas (no tienen el &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_method_table#Efficiency&quot;&gt;overhead de una llamada a una función virtual&lt;/a&gt;).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Clases que "desaparecen" luego de compilar</title>
   <link href="https://davidcapello.com/blog/cpp/clases-que-desaparecen-luego-de-compilar/"/>
   <updated>2009-10-17T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/clases-que-desaparecen-luego-de-compilar</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
La magia de C++ es que, una vez compilado el código, algunas clases pueden desaparecer por completo (principalmente las que se usan en &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt;). O sea, aunque las clases abstraen al programador de los detalles de implementación, al final, el código termina siendo tan óptimo como si la clase no fuera utilizada en un principio.&lt;br /&gt;&lt;br /&gt;Un ejemplo. Teniendo la siguiente clase Acumulador:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;cstdio&amp;gt;&lt;br /&gt;&lt;br /&gt;class Acumulador {&lt;br /&gt;  int v;&lt;br /&gt;public:&lt;br /&gt;  Acumulador()         { v = 0;                   }&lt;br /&gt;  ~Acumulador()        { std::printf(&quot;%d\n&quot;, v);  }&lt;br /&gt;  void acumular(int x) { v += x;                  }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Un código como el siguiente:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;  Acumulador acum;&lt;br /&gt;  acum.acumular(2);&lt;br /&gt;  acum.acumular(4);&lt;br /&gt;  acum.acumular(10);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Al compilarlo (optimizándolo), el código equivale a exactamente esto:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;  int v = 0;&lt;br /&gt;  v += 2;&lt;br /&gt;  v += 4;&lt;br /&gt;  v += 10;&lt;br /&gt;  std::printf(&quot;%d\n&quot;, v);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;La clase Acumulador ya no existe. Obtenemos el código más óptimo posible: sin llamadas a la función &quot;acumular&quot;, ni ningún byte extra de memoria (Acumulador ocupa lo mismo de memoria que ocupa un &quot;int&quot;).&lt;br /&gt;&lt;br /&gt;Este ejemplo no ayuda a ver grandes ventajas, pero si el constructor y el destructor hacen tareas complicadas, y las funciones miembros también, el resultado puede llevarnos a dos puntos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nos abstrae de la complejidad de la implementación (e.j. &lt;em&gt;para qué quiero saber cómo se acumula si sólo quiero acumular&lt;/em&gt;)&lt;br /&gt;&lt;li&gt;Obtenemos código tan óptimo como si no hubiéramos usado la abstracción (e.j. &lt;em&gt;las operaciones se acercan al hardware tanto como sea posible&lt;/em&gt;).&lt;br /&gt;&lt;/ul&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>SourceForge habla de Allegro Sprite Editor</title>
   <link href="https://davidcapello.com/blog/meta/sourceforge-habla-de-allegro-sprite-editor/"/>
   <updated>2009-10-13T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/sourceforge-habla-de-allegro-sprite-editor</id>
   <content type="html">&lt;p&gt;Hoy salió
&lt;a href=&quot;https://sourceforge.net/community/allegro-con-spirito-a-graphics-editor-for-sprites/&quot;&gt;un artículo&lt;/a&gt;
sobre &lt;a href=&quot;http://www.aseprite.org/&quot;&gt;Allegro Sprite Editor&lt;/a&gt; en la SourceForge Community.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Las viejas home pages</title>
   <link href="https://davidcapello.com/blog/meta/las-viejas-home-pages/"/>
   <updated>2009-10-07T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/meta/las-viejas-home-pages</id>
   <content type="html">&lt;p&gt;&lt;em&gt;(Una nota que nadie nunca leerá)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Viendo &lt;a href=&quot;http://davidcapello.com&quot;&gt;mi página&lt;/a&gt; hoy en día, siento que ya es
una reliquia. Hace muchísimo que las páginas personales dejaron de
existir como eran antes. Ahora son todos blogs, feeds, artículos,
noticias, etc. Las viejas páginas personales (con secciones, site-map,
etc.) ya son una antigüedad.&lt;/p&gt;

&lt;p&gt;A lo largo de los años fui quitando más y más texto de mi página,
hasta dejarla pelada completamente. Hoy en día son sólo links,
apuntando a otros sitios para bajarse cosas útiles (¿?). Algún que
otro párrafo explicando algo, pero inclusive sospecho que esos
párrafos nunca serán leídos.&lt;/p&gt;

&lt;p&gt;En fin, las viejas páginas personales fueron devoradas por la
“fast-food” de la información en Internet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Wave</title>
   <link href="https://davidcapello.com/blog/tech/google-wave/"/>
   <updated>2009-09-19T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/tech/google-wave</id>
   <content type="html">&lt;p&gt;Una de las mejores cosas que vi:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://wave.google.com/&quot;&gt;http://wave.google.com/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Google_Wave&quot;&gt;http://en.wikipedia.org/wiki/Google_Wave&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;http://code.google.com/intl/es-AR/apis/wave/&lt;/del&gt; &lt;a href=&quot;http://incubator.apache.org/wave/&quot;&gt;http://incubator.apache.org/wave/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Editado 2012-04-05&lt;/strong&gt;: Me causa gracia hoy en día como uno de los
mejores proyectos que pensé ver, fue cerrado.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Modernización de Emacs</title>
   <link href="https://davidcapello.com/blog/emacs/modernizacion-de-emacs/"/>
   <updated>2009-08-26T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/emacs/modernizacion-de-emacs</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://xahlee.org/emacs/modernization.html&quot;&gt;Un artículo&lt;/a&gt; de Xah Lee
que habla sobre cómo mejorar Emacs. Por fin alguien que piensa en la
usabilidad en el software libre.&lt;/p&gt;

&lt;p&gt;Y su proyecto para llevarlo a cabo: &lt;a href=&quot;http://www.ergoemacs.org/&quot;&gt;ErgoEmacs&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Lo que quieras hacer</title>
   <link href="https://davidcapello.com/blog/music/lo-que-quieras-hacer/"/>
   <updated>2009-07-23T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/lo-que-quieras-hacer</id>
   <content type="html">&lt;p&gt;Tema &lt;em&gt;Lo que quieras hacer&lt;/em&gt; de &lt;em&gt;Riff&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Te dicen que nunca hiciste algo bien,
que no fuiste lo que debías ser;
no saben que acaso no quisiste ser,
como ellos decían estaba bien.

Según pasa el tiempo te das cuenta que
todo fue distinto a lo que iba a ser,
sólo queda ahora seguir adelante,
seguir adelante y no retroceder.

Tuya, es toda tu vida
para hacer lo que tu quieras hacer,
tuya, y no sólo mía
porque yo ya no te puedo ni ver.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/fKoSMBg3WeM&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>C++0x no va a tener "conceptos"</title>
   <link href="https://davidcapello.com/blog/cpp/cpp0x-no-va-a-tener-conceptos/"/>
   <updated>2009-07-23T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/cpp0x-no-va-a-tener-conceptos</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
En la última reunión del &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/&quot;&gt;ISO C++ Standards Committe&lt;/a&gt;e decidieron quitar los &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Concepts_%28C%2B%2B0x%29&quot;&gt;conceptos&lt;/a&gt;&quot; del próximo estándar de &lt;a href=&quot;http://en.wikipedia.org/wiki/C%2B%2B0x&quot;&gt;C++&lt;/a&gt; (que en realidad, en vez de C++0x va a ser C++1x y chirola). &lt;a href=&quot;http://www.ddj.com/architect/218600111&quot;&gt;Un artículo de Bjarne Stroustrup&lt;/a&gt; habla al respecto:&lt;br /&gt;&lt;blockquote&gt;[...] Básicamente, los &quot;conceptos&quot; tenían como meta hacer de la programación genérica algo más accesible a la mayoría de los programadores, pero esa meta ha sido para mí (Stroustrup) seriamente comprometida: En vez de hacer la programación genérica más accesible, los &quot;conceptos&quot; se fueron convirtiendo en otra herramienta más en las manos de los expertos (únicamente).&lt;br /&gt;[...]&lt;br /&gt;Para resumir y de alguna forma simplificar, he afirmado que:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Los &quot;conceptos&quot; como están actualmente definidos son muy difíciles de utilizar, lo que los llevará al desuso, dando la posibilidad a un desuso de los &lt;em&gt;templates&lt;/em&gt; mismos y a la adopción completa de C++0x.&lt;/li&gt;&lt;li&gt;Un pequeño conjunto de simplificaciones [&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2906.pdf&quot;&gt;BS2009&lt;/a&gt;] pueden dejar a los &quot;conceptos&quot; lo suficientemente aceptables como para salir acorde a las fechas planificadas para C++0x o con sólo un retraso menor.&lt;br /&gt;&lt;/ul&gt;[...] &lt;/blockquote&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>STL vector en vez de los clásicos buffers de C</title>
   <link href="https://davidcapello.com/blog/cpp/stl-vector-en-vez-de-los-clasicos-buffers-de-c/"/>
   <updated>2009-07-12T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/stl-vector-en-vez-de-los-clasicos-buffers-de-c</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Algunas veces tenemos que crear buffers temporales. Por ejemplo, la función &lt;a href=&quot;http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/&quot;&gt;sprintf&lt;/a&gt; necesita de un buffer para poder dejar la cadena resultante. Ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char buf[256];&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Si queremos mantener el buffer en heap:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char* buf = malloc(256);&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;free(buf);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En C++ podríamos hacer uso de los operadores new[]/delete[]:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;char* buf = new char[256];&lt;br /&gt;sprintf(buf, &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;buf&quot;...&lt;br /&gt;delete[] buf;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pero es aconsejable evitar la creación de arreglos con new[], y en su lugar hacer uso de &lt;a href=&quot;http://www.cplusplus.com/reference/stl/vector/&quot;&gt;std::vector&lt;/a&gt;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;std::vector&amp;lt;char&amp;gt; buf(256);&lt;br /&gt;sprintf(&amp;amp;buf[0], &quot;%d&quot;, 12345);&lt;br /&gt;// usar &quot;&amp;amp;buf[0]&quot; en vez de &quot;buf&quot;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El resultado: tenemos un buffer en el heap que se libera automáticamente (~std::vector) al salir del ámbito de la función que lo utiliza.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Conscientemente, todo todo, lo podrás lograr</title>
   <link href="https://davidcapello.com/blog/music/conscientemente-todo-todo-lo-podras-lograr/"/>
   <updated>2009-04-06T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/music/conscientemente-todo-todo-lo-podras-lograr</id>
   <content type="html">&lt;p&gt;Tema &lt;em&gt;Conscientemente, todo todo, lo podrás lograr&lt;/em&gt; de &lt;em&gt;Billy Bond y La Pesada Del Rock and Roll&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;En tu mente, en tu mente vivirán.
Los deseos, los deseos de cambiar.
Concientemente todo todo lo podrás lograr.

No te quedes, no te quedes muy atrás.
Si no sigues, no tendrás con quien hablar.
Concientemente todo, todo lo podrás lograr.

Vamos chicos, vamos chicos a cambiar.
Vamos loco, vamos loco a cambiar.
Concientemente todo todo lo podrás lograr.

No te quedes siempre en el mismo lugar.
Vamos chico, vamos loco a cambiar.
Concientemente, todo todo, lo podrás lograr.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/bZYQLUkNJ9Q&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>STL for each</title>
   <link href="https://davidcapello.com/blog/cpp/stl-for-each/"/>
   <updated>2009-03-21T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/stl-for-each</id>
   <content type="html">&lt;p&gt;Para recorrer un arreglo de C, podemos utilizar punteros.  Comenzamos
apuntando al primer elemento y frenamos una vez procesado el último
elemento:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main()
{
  int array[] = { 5, 3, 4, 9, 1 };
  int array_size = sizeof(array) / sizeof(int); // cantidad de elementos de &quot;array&quot;
  int *array_begin = array;                     // comienzo del array
  int *array_end = array+array_size;            // final del array (+un elemento)
  int *it;                                      // el iterator

  for (it = array_begin;  it != array_end;  ++it) {
    printf(&quot;%d\n&quot;, *it);
  }
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hay que tener en cuenta que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array_end&lt;/code&gt; es igual a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;array[5]&lt;/code&gt;. Sabiendo que sólo podemos acceder a los elementos desde
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array[0]&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array[4]&lt;/code&gt;, decimos que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array[5]&lt;/code&gt; está más allá del
último elemento del arreglo, es decir, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;array[5]&lt;/code&gt; es la posición de
memoria que ya no es parte del mismo arreglo (de ahí &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it != array_end&lt;/code&gt;
significa “mientras nos encontremos dentro del arreglo”).&lt;/p&gt;

&lt;p&gt;¿Cómo recorrer un
&lt;a href=&quot;http://www.sgi.com/tech/stl/Container.html&quot;&gt;contenedor&lt;/a&gt; de la STL? La
idea es similar, sólo que en vez de usar punteros utilizamos
iteradores, y observe como la sintaxis del &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; es exactamente la
misma. (Nota: en este caso utilizamos un
&lt;a href=&quot;http://www.sgi.com/tech/stl/Vector.html&quot;&gt;vector&lt;/a&gt;.)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int main()
{
  vector&amp;lt;int&amp;gt; array;
  array.push_back(5);
  array.push_back(3);
  array.push_back(4);
  array.push_back(9);
  array.push_back(1);

  vector&amp;lt;int&amp;gt;::iterator it;

  for (it = array.begin();  it != array.end();  ++it) {
    cout &amp;lt;&amp;lt; *it &amp;lt;&amp;lt; endl;
  }
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Cómo recorrer un contenedor STL con el algoritmo &lt;a href=&quot;http://www.sgi.com/tech/stl/for_each.html&quot;&gt;for_each&lt;/a&gt;?
(Nota: Lo siguiente también se puede hacer con &lt;a href=&quot;http://www.sgi.com/tech/stl/copy.html&quot;&gt;copy&lt;/a&gt; y
&lt;a href=&quot;http://www.sgi.com/tech/stl/ostream_iterator.html&quot;&gt;ostream_iterator&lt;/a&gt;.)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

void print_element(int a) { cout &amp;lt;&amp;lt; *it &amp;lt;&amp;lt; endl; }

int main()
{
  vector&amp;lt;int&amp;gt; array;
  array.push_back(5);
  array.push_back(3);
  array.push_back(4);
  array.push_back(9);
  array.push_back(1);

  for_each(array.begin(), array.end(), print_element);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;La función pasada como tercer parámetro a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for_each&lt;/code&gt; es llamada por cada elemento del arreglo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template&amp;lt;typename InputIterator, typename Function&amp;gt;
Function for_each(InputIterator first, InputIterator last, Function f)
{
  for (; first != last; ++first)
    f(*first);
  return f;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;¿Por qué &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for_each&lt;/code&gt; devuelve la función? Principalmente porque la
función &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; podría no ser una función! Podría ser un
&lt;a href=&quot;http://www.sgi.com/tech/stl/functors.html&quot;&gt;functor&lt;/a&gt; (objeto función),
es decir, una instancia de una clase que tiene sobrecargado el
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt; (llamada a función). Pero este tema se merece su
propio post.&lt;/p&gt;

&lt;p&gt;¿Se puede usar el algoritmo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for_each&lt;/code&gt; para los arreglos de C? Sí.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

void print_element(int a) { printf(&quot;%d\n&quot;, a); }

int main()
{
  int array[] = { 5, 3, 4, 9, 1 };
  int array_size = sizeof(array) / sizeof(int); // cantidad de elementos de &quot;array&quot;
  int *array_begin = array;                     // comienzo del array
  int *array_end = array+array_size;            // final del array (un elemento más)

  for_each(array_begin, array_end, print_element);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>STL generate</title>
   <link href="https://davidcapello.com/blog/cpp/stl-generate/"/>
   <updated>2008-12-08T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/stl-generate</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Si usted tiene una función que genera números/valores/instancias (ej: un generador de números aleatorios, o identificadores) puede usar el algoritmo &lt;a href=&quot;http://www.cplusplus.com/reference/algorithm/generate.html&quot;&gt;generate&lt;/a&gt; de la &lt;a href=&quot;http://www.sgi.com/tech/stl/&quot;&gt;STL&lt;/a&gt; para crear una secuencia de objetos. Por ejemplo, para generar 100 números (pseudo)aleatorios de 0 a 1:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;&lt;br /&gt;double uniform_random()&lt;br /&gt;{&lt;br /&gt;  return (rand() % 10001) / 10000.0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  std::vector&amp;lt;double&amp;gt; v(100);&lt;br /&gt;  std::generate(v.begin(), v.end(), uniform_random);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
El algoritmo &lt;em&gt;generate&lt;/em&gt; recibe dos iteradores (inicio y fin), y llama a la función especificada para cada una de las posiciones que recorre:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;template&amp;lt;typename ForwardIterator, typename Generator&amp;gt;&lt;br /&gt;void generate(ForwardIterator first, ForwardIterator last,&lt;br /&gt;              Generator gen)&lt;br /&gt;{&lt;br /&gt;  for (; first != last; ++first)&lt;br /&gt;    *first = gen();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
Los algoritmos de la STL son genéricos porque utilizan la &lt;a href=&quot;http://en.wikipedia.org/wiki/Pointer_(computing)#C_and_C.2B.2B&quot;&gt;aritmética de punteros&lt;/a&gt;. Los iteradores sobrecargan los operadores para poder ser utilizados como punteros. Así un algoritmo puede ser utilizado con los contenedores de la STL (&lt;a href=&quot;http://www.sgi.com/tech/stl/Vector.html&quot;&gt;vector&lt;/a&gt;) o con los viejos y tan queridos arreglos (y punteros) de C:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;&lt;br /&gt;double uniform_random()&lt;br /&gt;{&lt;br /&gt;  return (rand() % 10001) / 10000.0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  double v[100];&lt;br /&gt;  std::generate(v, v+100, uniform_random);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>¿Preincrementar o postincrementar?</title>
   <link href="https://davidcapello.com/blog/cpp/preincrementar-o-postincrementar/"/>
   <updated>2008-08-19T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/preincrementar-o-postincrementar</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Hace mucho que quería escribir un post tan inútil como este. La duda que siempre me pasaba por la cabeza era la siguiente: ¿Será exactamente el mismo código ensamblador el que genera el compilador cuando utilizamos el preincremento o el postincremento (sin utilizar el valor de retorno)? Tenía la seguridad de que así debía ser (una optimización tan básica no podía ser dejada de lado), pero me faltaban las pruebas (en ensamblador) para verificarlo.&lt;br /&gt;&lt;br /&gt;Recordando un poco, el preincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int a = 0;&lt;br /&gt;int b = ++a;&lt;br /&gt;&lt;/pre&gt;hace &lt;i&gt;a=1&lt;/i&gt; y &lt;i&gt;b=1&lt;/i&gt;, mientras que el postincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int a = 0;&lt;br /&gt;int b = a++;&lt;br /&gt;&lt;/pre&gt;hace &lt;i&gt;a=1&lt;/i&gt; y &lt;i&gt;b=0&lt;/i&gt;, esto significa que &lt;i&gt;b&lt;/i&gt; obtuvo el valor de &lt;i&gt;a&lt;/i&gt; anterior al incremento.&lt;br /&gt;&lt;br /&gt;Aquí &lt;i&gt;estamos utilizando&lt;/i&gt; el valor de retorno del operador incremento. El código ensamblador &lt;i&gt;es distinto&lt;/i&gt; para cada caso. Vamos a echarle una mirada (antes le recomiendo ver &lt;a href=&quot;http://www.unixwiz.net/techtips/win32-callconv-asm.html&quot;&gt;este excelente artículo&lt;/a&gt; para comprender más sobre el stack y las convenciones de llamadas). En el preincremento el código ensamblador (generado por GCC 3.4.5 para i386) es:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;subl  $8, %esp          // reservamos 8 bytes en el &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt; (para variables locales)&lt;br /&gt;movl  $0, -4(%ebp)      // a   = 0&lt;br /&gt;leal  -4(%ebp), %eax    // eax = &amp;amp;a&lt;br /&gt;incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;movl  -4(%ebp), %eax    // eax = a&lt;br /&gt;movl  %eax, -8(%ebp)    // b   = eax&lt;br /&gt;&lt;/pre&gt;En el postincremento&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;subl  $8, %esp          // reservamos 8 bytes en el stack&lt;br /&gt;movl  $0, -4(%ebp)      // a   = 0&lt;br /&gt;movl  -4(%ebp), %edx    // edx = a&lt;br /&gt;leal  -4(%ebp), %eax    // eax = &amp;amp;a&lt;br /&gt;incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;movl  %edx, -8(%ebp)    // b   = edx&lt;/pre&gt;donde se ve que el registro edx se utiliza para guardar el valor que tenía &lt;i&gt;a&lt;/i&gt; antes del incremento para luego asignárselo a &lt;i&gt;b&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Pero la pregunta original es, ¿qué pasa si &lt;b&gt;no&lt;/b&gt; usamos el valor de retorno? ¿el código de ++i o i++ es igual? Debería serlo, y de hecho, lo es. Pero como veremos más abajo, esto sólo se cumple si utilizamos tipos de datos &lt;i&gt;built-in&lt;/i&gt; (int, double, long, etc.). Miremos el siguiente código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;void func() { }&lt;br /&gt;void pre () { for (int c=0; c&amp;lt;8; ++c) { func(); } }&lt;br /&gt;void post() { for (int c=0; c&amp;lt;8; c++) { func(); } }&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  pre();&lt;br /&gt;  post();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Básico, un &lt;i&gt;for&lt;/i&gt; pero con las dos variantes posible de incremento. El código generado para ambos casos (tanto para la función &lt;i&gt;pre&lt;/i&gt; como &lt;i&gt;post&lt;/i&gt;) es el siguiente:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;  pushl %ebp              // guardar el viejo puntero a la base del stack&lt;br /&gt;  movl  %esp, %ebp        // establecer la nueva base del stack&lt;br /&gt;  subl  $4, %esp          // guardar 4 bytes en el stack (para variables locales)&lt;br /&gt;  movl  $0, -4(%ebp)      // c = 0&lt;br /&gt;L3:&lt;br /&gt;  cmpl  $7, -4(%ebp)&lt;br /&gt;  jg    L2                // si c &amp;gt; 7 entonces ir a L2&lt;br /&gt;  call  _func             // llamar a la función func()&lt;br /&gt;  leal  -4(%ebp), %eax    // eax = &amp;amp;c&lt;br /&gt;  incl  (%eax)            // *eax= (*eax) + 1&lt;br /&gt;  jmp   L3                // repetir yendo a L3&lt;br /&gt;L2:&lt;br /&gt;  leave                   // restaurar la base del stack (popl %ebp)&lt;br /&gt;  ret                     // retornar al punto de llamada&lt;br /&gt;&lt;/pre&gt;Realmente es indiferente usar cualquiera de los dos tipos de incremento, salvo, en los tipos definidos por el usuario.  C++ ofrece un soporte para tipos de usuario igual a los built-in (bueno, no del todo, pero &lt;a href=&quot;http://www.artima.com/cppsource/cpp0xP.html&quot;&gt;lo están solucionando&lt;/a&gt;). Nos da la posibilidad de sobrecargar los operadores de nuestros propios tipos (clases). Por ejemplo:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;class tipo {&lt;br /&gt;  int x;&lt;br /&gt;public:&lt;br /&gt;  tipo(int y) : x(y) { }&lt;br /&gt;  tipo(const tipo&amp;amp; y) : x(y.x) { }&lt;br /&gt;  // preincremento&lt;br /&gt;  tipo&amp;amp; operator++() {&lt;br /&gt;    ++x;&lt;br /&gt;    return *this;&lt;br /&gt;  }&lt;br /&gt;  // postincremento&lt;br /&gt;  tipo operator++(int) {&lt;br /&gt;    tipo tmp(*this);&lt;br /&gt;    ++x;&lt;br /&gt;    return tmp;&lt;br /&gt;  }&lt;br /&gt;  bool operator&amp;lt;(int y) const { return x &amp;lt; y; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void func() { }&lt;br /&gt;void pre()  { for (tipo c=0; c&amp;lt;8; ++c) { func(); } }&lt;br /&gt;void post() { for (tipo c=0; c&amp;lt;8; c++) { func(); } }&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  post();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;No colocaré el código ensamblador por desbordar belleza, pero el código generado en este caso es distinto: cada incremento llama a la función correspondiente a su operador. Esto es debido a que ambas implementaciones varían considerablemente. Por ejemplo, el postincremento necesita de una instancia extra de &lt;i&gt;tipo&lt;/i&gt; para poder devolver el anterior valor de &lt;i&gt;this&lt;/i&gt;, en cambio, el preincremento devuelve una referencia al mismo &lt;i&gt;this&lt;/i&gt; (sin necesidad de hacer una copia).&lt;br /&gt;&lt;br /&gt;Como dato curioso, algo interesante ocurre al utilizar las optimizaciones del GCC. Si compilamos este último programa con el parámetro -O3, vamos a ver que todas las funciones correspondientes a la clase &lt;i&gt;tipo&lt;/i&gt; desaparecen, y todo el código resultantes es &lt;i&gt;inline&lt;/i&gt;, dando como resultado un código tan óptimo como si hubiéramos utilizado un &lt;i&gt;int&lt;/i&gt; en vez de nuestra clase &lt;i&gt;tipo&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Cómo obtengo el código ensamblador desde un archivo C/C++?&lt;/b&gt;&lt;br /&gt;Con el compilador &lt;i&gt;gcc&lt;/i&gt;, hay que utilizar el parámetro -S: &lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;g++ -S -o archivo.s -c archivo.cpp&lt;br /&gt;&lt;/pre&gt;En &lt;i&gt;archivo.s&lt;/i&gt; queda el código ensamblador (sintaxis &lt;a href=&quot;http://www.google.com.ar/search?q=AT%26T+Assembly+Syntax&quot;&gt;AT&amp;amp;T&lt;/a&gt;).
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Excepciones, RAII y auto_ptr</title>
   <link href="https://davidcapello.com/blog/cpp/excepciones-raii-y-auto-ptr/"/>
   <updated>2008-06-24T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/excepciones-raii-y-auto-ptr</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Una de las mejores formas de realizar un control de errores es por medio de excepciones. Lamentablemente, si no se toman las precauciones adecuadas, se pueden obtener &lt;a href=&quot;http://en.wikipedia.org/wiki/Handle_leak&quot;&gt;leaks&lt;/a&gt; de algunos recursos. Por ejemplo, imagine el siguiente caso:&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;char *ptr = new char[256];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double *matrix = new double[100000*100000]; // 74 Gigabytes&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (const std::bad_alloc&amp;amp; e) {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::cout &amp;lt;&amp;lt; &quot;No hay memoria suficiente&quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Aquí, con el segundo &lt;em&gt;new&lt;/em&gt; una excepción &lt;em&gt;bad_alloc&lt;/em&gt; es lanzada. El problema es que la memoria asignada con el primer &lt;em&gt;new&lt;/em&gt; nadie la libera. Esto es un &lt;a href=&quot;http://en.wikipedia.org/wiki/Memory_leak&quot;&gt;memory leak&lt;/a&gt;. Una opción para solucionarlo es mediante un bloque &lt;a href=&quot;http://www.research.att.com/~bs/bs_faq2.html#finally&quot;&gt;finally&lt;/a&gt; &quot;a la Java&quot;:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;char *ptr = NULL;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double *matrix = NULL;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;ptr = new char[256];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;matrix = new double[100000*100000];&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (...) { // finally&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;if (matrix) delete matrix;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;if (ptr) delete ptr;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Claro que esto no hace al manejo de errores una tarea transparente.&lt;br /&gt;&lt;br /&gt;En C++ se puede utilizar la técnica &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;RAII&lt;/a&gt; (la adquisición de recursos está en la inicialización), lo que ayuda a evitar &lt;em&gt;leaks&lt;/em&gt;. La idea básica detrás de esto es que los constructores obtengan recursos, y los destructores los liberen. Al ocurrir una excepción, se van llamando los destructores de los objetos creados.&lt;br /&gt;&lt;br /&gt;Para solucionar nuestro problema, podemos utilizar la clase &lt;em&gt;auto_ptr&lt;/em&gt; que se encuentra en &amp;lt;memory&amp;gt;. Un &lt;em&gt;auto_ptr&lt;/em&gt; guarda un puntero que es liberado automáticamente en el destructor.&lt;pre class=&quot;prettyprint&quot;&gt;int main()&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;try {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;char&amp;gt; ptr(new char[256]);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;double&amp;gt; matrix(new double[100000*100000]);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ...&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;} catch (const std::bad_alloc&amp;amp; e) {&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::cout &amp;lt;&amp;lt; &quot;No hay memoria suficiente&quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Los &lt;em&gt;delete&lt;/em&gt;s no son necesarios. Al salir del &lt;a href=&quot;http://en.wikipedia.org/wiki/Scope_%28programming%29&quot;&gt;ámbito&lt;/a&gt; del bloque &lt;em&gt;try&lt;/em&gt;, ya sea normalmente o por excepción, se llamará al destructor de los &lt;em&gt;auto_ptr&lt;/em&gt;s creados, así no se incurre en ningún tipo de &lt;em&gt;leak&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Advertencia&lt;/b&gt;: Los &lt;em&gt;auto_ptr&lt;/em&gt; deben ser utilizados sabiendo cuál es su verdadero funcionamiento: La copia de un &lt;em&gt;auto_ptr&lt;/em&gt; a otro no los deja equivalentes. La última copia se queda con el puntero, los demás lo van perdiendo, y el &lt;em&gt;delete&lt;/em&gt; lo invoca el último &lt;em&gt;auto_ptr&lt;/em&gt; destruido. Por ejemplo:&lt;pre class=&quot;prettyprint&quot;&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;Persona&amp;gt; otra_persona;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;std::auto_ptr&amp;lt;Persona&amp;gt; una_persona(new Persona);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;otra_persona = una_persona;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;// ahora &quot;una_persona&quot; apunta a NULL&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;}&lt;br /&gt;} // aquí la persona es destruida&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Pregunta&lt;/b&gt;: ¿Por qué no usar objetos alojados en el &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack&quot;&gt;stack&lt;/a&gt; en vez del &lt;a href=&quot;http://en.wikipedia.org/wiki/Dynamic_memory_allocation&quot;&gt;heap&lt;/a&gt; para evitar los &lt;em&gt;leaks&lt;/em&gt;? Porque el &lt;em&gt;stack&lt;/em&gt; es mucho más pequeño. Por ejemplo, el siguiente código provoca un &lt;a href=&quot;http://en.wikipedia.org/wiki/SIGSEGV&quot;&gt;SIGSEGV&lt;/a&gt; ya que el arreglo no entra en el &lt;em&gt;stack&lt;/em&gt;:&lt;pre class=&quot;prettyprint&quot;&gt;double matrix[1000000];&lt;/pre&gt;Pero sí entra en el &lt;em&gt;heap&lt;/em&gt;:&lt;pre class=&quot;prettyprint&quot;&gt;double *matrix = new double[1000000]; // 7.6 Megabytes&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Compilando archivos</title>
   <link href="https://davidcapello.com/blog/cpp/compilando-archivos/"/>
   <updated>2008-05-10T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/compilando-archivos</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
Suponiendo que conoce qué es un archivo de &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_fuente&quot;&gt;código fuente&lt;/a&gt;, &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_objeto&quot;&gt;código objeto&lt;/a&gt;, un &lt;a href=&quot;http://es.wikipedia.org/wiki/Ejecutable&quot;&gt;ejecutable&lt;/a&gt; &lt;a href=&quot;http://es.wikipedia.org/wiki/EXE&quot;&gt;&lt;b&gt;.exe&lt;/b&gt;&lt;/a&gt;, y el &lt;a href=&quot;http://es.wikipedia.org/wiki/C%C3%B3digo_m%C3%A1quina&quot;&gt;código máquina&lt;/a&gt;; voy a pasar a explicar algunos comandos del &lt;a href=&quot;http://es.wikipedia.org/wiki/GCC&quot;&gt;GCC&lt;/a&gt; para compilar.&lt;br /&gt;&lt;br /&gt;Retomando la idea del &lt;a href=&quot;http://cmasomenos.blogspot.com/2008/03/medir-el-tiempo-de-una-rutina.html&quot;&gt;anterior post&lt;/a&gt;, imagínese que creamos un archivo &lt;a href=&quot;http://davidcapello.googlepages.com/timemark.h&quot;&gt;timemark.h&lt;/a&gt; para darle un poco de portabilidad a todo este asunto de medir el desempeño de una rutina. Las declaraciones de timemark.h pueden ser usadas para crear un pequeño programa &lt;a href=&quot;http://davidcapello.googlepages.com/ejemplo1.c&quot;&gt;ejemplo1.c&lt;/a&gt; que sea independiente de la plataforma (por lo menos entre Windows y GNU/Linux).&lt;br /&gt;&lt;br /&gt;Vamos a probar algunas operaciones sobre la línea de comandos para ver cómo compilar este archivo. Inicialmente, la opción más sencilla es utilizar directamente &quot;gcc ejemplo1.c&quot;, esto nos da como resultado el archivo &quot;a.exe&quot; o &quot;a.out&quot;. Veamos (teniendo &lt;em&gt;timemark.h&lt;/em&gt; y &lt;em&gt;ejemplo1.c&lt;/em&gt; en un directorio &lt;em&gt;C:\ejemplo1&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc ejemplo1.c&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x31): undefined reference to `get_timemark&apos;&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x3c): undefined reference to `get_timemark&apos;&lt;br /&gt;C:/Temp/ccMjdaaa.o:ejemplo1.c:(.text+0x4e): undefined reference to `timemark_diff&apos;&lt;br /&gt;collect2: ld returned 1 exit status&lt;br /&gt;&lt;/pre&gt;Como podrá ver, recibimos un error por las funciones no definidas &lt;em&gt;get_timermark&lt;/em&gt; y &lt;em&gt;timemark_diff&lt;/em&gt;. Esto se debe a que utilizando solamente &quot;gcc ejemplo1.c&quot;, se intenta enlazar el código de ese único archivo en el ejecutable. Tenemos algunas opciones intermedias antes de crear el .exe final. Por ejemplo, podemos crear un archivo que contenga el código objeto ya compilado (pero únicamente del archivo en cuestión &lt;em&gt;ejemplo1.c&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o ejemplo1.o -c ejemplo1.c&lt;br /&gt;&lt;/pre&gt;Así obtenemos el &lt;em&gt;ejemplo1.o&lt;/em&gt; (código objeto). En este caso no recibimos errores ya que &lt;em&gt;ejemplo1.o&lt;/em&gt; hace referencias a las funciones &lt;em&gt;get_timermark&lt;/em&gt; y &lt;em&gt;timemark_diff&lt;/em&gt;, pero no necesita su implementación específica. Cuando creamos el ejecutable final (&lt;em&gt;.exe&lt;/em&gt;) es cuando realmente necesitamos el código de todas las funciones invocadas.&lt;br /&gt;&lt;br /&gt;El archivo que falta es &lt;a href=&quot;http://davidcapello.googlepages.com/timemark.c&quot;&gt;timemark.c&lt;/a&gt;. Del mismo modo, podemos compilarlo con el comando:&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o timemark.o -c timemark.c&lt;br /&gt;&lt;/pre&gt;Ahora resta unir ambos archivos objetos en un único ejecutable, con un único punto de acceso (&lt;em&gt;main&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;C:\ejemplo1&amp;gt;gcc -o ejemplo.exe ejemplo1.o timemark.o&lt;br /&gt;&lt;/pre&gt;Y listo. Por ahora, lo aprendido son estos dos comandos:&lt;br /&gt;&lt;pre class=&quot;source-code&quot;&gt;gcc -o archivo.o -c archivo.c&lt;br /&gt;gcc -o archivo.exe archivo1.o archivo2.o archivo3.o ...&lt;br /&gt;&lt;/pre&gt;El primero compila el código fuente para generar un archivo objeto, y el segundo comando reune (enlaza, &lt;em&gt;linkea&lt;/em&gt;) el grupo de archivos objetos en un ejecutable único.&lt;br /&gt;&lt;br /&gt;De todas formas, es bastante tedioso escribir estos comandos cada vez que queremos compilar. Para resolver el problema podemos utilizar los llamados Makefiles. Claro, lo más interesante queda para un futuro post.
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Medir el tiempo de una rutina</title>
   <link href="https://davidcapello.com/blog/cpp/medir-el-tiempo-de-una-rutina/"/>
   <updated>2008-03-01T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/medir-el-tiempo-de-una-rutina</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
¿Alguna vez se preocupó por la velocidad con la que corre su programa? ¿No? Entonces usted es un candidato perfecto para jugar al &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_%28board_game%29&quot;&gt;Java&lt;/a&gt;. En caso contrario, voy a explicarle un pequeño código que utilizaremos en próximas entregas para medir el tiempo de ejecución de determinadas rutinas.&lt;br /&gt;&lt;br /&gt;Ya lo dijo &lt;a href=&quot;http://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/&quot;&gt;alguien&lt;/a&gt;: &quot;La optimización prematura es la raíz de todos los males&quot;. No hay nada más cierto, aunque también es verdad que hacer algo simple de la peor forma posible, es la causa de &lt;a href=&quot;http://www.urbandictionary.com/define.php?term=pain+in+the+ass&quot;&gt;otros grandes males&lt;/a&gt;. Con esto quiero decir que debería intentar hacer las cosas de la forma más simple y más óptima que usted conozca (dándole mayor importancia a la simplicidad del código); luego se preocupa por &quot;darle velocidad&quot; a la rutina que provoca el cuello de botella (en próximos posts veremos cómo usar &lt;em&gt;gprof&lt;/em&gt; para detectarlo).&lt;br /&gt;&lt;br /&gt;La forma de calcular el tiempo de CPU que toma una función es muy simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;tomamos el valor del reloj antes de realizar la llamada (&lt;em&gt;t_ini&lt;/em&gt;),&lt;/li&gt;&lt;li&gt;llamamos a la rutina en cuestión, y&lt;/li&gt;&lt;li&gt;tomamos nuevamente el valor del reloj (&lt;em&gt;t_fin&lt;/em&gt;).&lt;/li&gt;&lt;/ul&gt;La diferencia entre &lt;em&gt;t_fin - t_ini&lt;/em&gt; nos da el total de tiempo que tomó: 1) hacer la llamada a la rutina, 2) que esta haga su trabajo, 3) que devuelva el resultado.&lt;br /&gt;&lt;br /&gt;Ahora hay algunos pequeños detalles de implementación. Por ejemplo, ¿qué función usar para tomar el tiempo del reloj? Y más importante, ¿qué precisión obtenemos con dicha función?&lt;br /&gt;&lt;br /&gt;Para tomar el tiempo podemos usar la rutina &lt;a href=&quot;http://www.cplusplus.com/clock&quot;&gt;clock()&lt;/a&gt;, que devuelve el tiempo &lt;em&gt;aproximado&lt;/em&gt; de CPU que transcurrió desde que nuestro programa fue iniciado, dicho tiempo representado en un valor de tipo &lt;a href=&quot;http://www.cplusplus.com/clock_t&quot;&gt;clock_t&lt;/a&gt;: un valor entero que indica una cantidad de &quot;tics&quot; de reloj.&lt;br /&gt;&lt;br /&gt;La precisión que tenemos con dicha rutina es de &lt;a href=&quot;http://www.cplusplus.com/CLOCKS_PER_SEC&quot;&gt;CLOCKS_PER_SEC&lt;/a&gt; (tics de reloj por segundo), lo que significa que por cada segundo que pasa, la función &lt;em&gt;clock()&lt;/em&gt; nos devolverá CLOCKS_PER_SEC unidades más que el valor anterior. En MinGW, CLOCKS_PER_SEC es igual a 1000, pero es mejor no fiarse de esto, ya que en otras plataformas dicho valor varía. Inclusive, según POSIX, la constante CLOCKS_PER_SEC debería ser 1000000.&lt;br /&gt;&lt;br /&gt;Veamos algo de código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;clock_t t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;t_ini = clock();&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;t_fin = clock();&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = (double)(t_fin - t_ini) / CLOCKS_PER_SEC;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milisegundos\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Con esto podemos medir cuántos milisegundos demoró &lt;em&gt;&quot;hacer algo&quot;&lt;/em&gt;. Todo parece muy bonito hasta que nos damos cuenta de dos grandes problemas:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Tomar una medida única y aislada es igual que tomar un número completamente aleatorio y mostrarlo (no es una &lt;a href=&quot;http://es.wikipedia.org/wiki/Muestra_estad%C3%ADstica&quot;&gt;muestra representativa&lt;/a&gt;). Es mejor repetir las mediciones unas cuantas veces (y hablo del orden de las 100, o 100000, o 1e32 veces), y luego sacar un promedio de todo.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;La función &lt;span style=&quot;font-style: italic;&quot;&gt;clock()&lt;/span&gt; no llega a tener una precisión  ni de 10 milisegundos (aunque CLOCS_PER_SEC sea 1000 o más).&lt;/li&gt;&lt;/ol&gt;Una vez dicho esto, el código de arriba no sirve ni para &lt;a href=&quot;http://es.wikipedia.org/wiki/Papel_higi%C3%A9nico&quot;&gt;limpiarse&lt;/a&gt; los &lt;a href=&quot;http://es.wikipedia.org/wiki/Traste&quot;&gt;trastes&lt;/a&gt;... Así que tenemos que buscar una función con mayor precisión, y además, promediar varias muestras.&lt;br /&gt;&lt;br /&gt;Existen otras alternativas como la función &lt;a href=&quot;http://www.freebsd.org/cgi/man.cgi?query=gettimeofday&quot;&gt;gettimeofday&lt;/a&gt;, pero bajo Windows sufre del mismo problema de precisión que &lt;em&gt;clock()&lt;/em&gt;. Igualmente en Linux funciona perfectamente, así que vale la pena tener en cuenta este código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/* retorna &quot;a - b&quot; en segundos */&lt;br /&gt;double timeval_diff(struct timeval *a, struct timeval *b)&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;(double)(a-&amp;gt;tv_sec + (double)a-&amp;gt;tv_usec/1000000) -&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;(double)(b-&amp;gt;tv_sec + (double)b-&amp;gt;tv_usec/1000000);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;struct timeval t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;gettimeofday(&amp;amp;t_ini, NULL);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;gettimeofday(&amp;amp;t_fin, NULL);&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = timeval_diff(&amp;amp;t_fin, &amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milliseconds\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Como puede ver la estructura &lt;em&gt;timeval&lt;/em&gt; contiene dos campos, segundos y microsegundos transcurridos (tv_sec y tv_usec respectivamente), por lo tanto ofrece una precisión de microsegundos. De todas formas, como decía esto en Windows no sirve y la razón es sencilla, en la misma &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms725496%28VS.85%29.aspx&quot;&gt;MSDN&lt;/a&gt; explican que el temporizador del sistema corre aproximadamente a unos 10 milisegundos, por lo tanto, cualquier función que lo utilice nos estará dando la misma asquerosa precisión (inclusive al utilizar &lt;a href=&quot;http://www.google.com.ar/search?q=GetSystemTimeAsFileTime+msdn&quot;&gt;GetSystemTimeAsFileTime&lt;/a&gt; y &lt;a href=&quot;http://www.google.com.ar/search?q=FILETIME+msdn&quot;&gt;FILETIME&lt;/a&gt;). Por lo tanto la solución es utilizar lo que se conoce en el mundo de Windows como el &quot;contador de rendimiento de alta resolución&quot; (&lt;em&gt;high-resolution performance counter&lt;/em&gt;):&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/* retorna &quot;a - b&quot; en segundos */&lt;br /&gt;double performancecounter_diff(LARGE_INTEGER *a, LARGE_INTEGER *b)&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;LARGE_INTEGER freq;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceFrequency(&amp;amp;freq);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return (double)(a-&amp;gt;QuadPart - b-&amp;gt;QuadPart) / (double)freq.QuadPart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;LARGE_INTEGER t_ini, t_fin;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;double secs;&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceCounter(&amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;/* ...hacer algo... */&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;QueryPerformanceCounter(&amp;amp;t_fin);&lt;br /&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;secs = performancecounter_diff(&amp;amp;t_fin, &amp;amp;t_ini);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;printf(&quot;%.16g milliseconds\n&quot;, secs * 1000.0);&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;/pre&gt;En este caso, imagine que &lt;a href=&quot;http://www.google.com.ar/search?q=QueryPerformanceCounter+msdn&quot;&gt;QueryPerformanceCounter&lt;/a&gt; es como &lt;em&gt;clock()&lt;/em&gt; y &lt;a href=&quot;http://www.google.com.ar/search?q=QueryPerformanceFrequency+msdn&quot;&gt;QueryPerformanceFrequency&lt;/a&gt; es como CLOCKS_PER_SEC. Es decir, la primera función nos da el valor del contador, y la segunda su frecuencia (en ciclos por segundo, &lt;a href=&quot;http://en.wikipedia.org/wiki/Hertz&quot;&gt;hertz&lt;/a&gt;). Cabe aclarar que un &lt;a href=&quot;http://www.google.com.ar/search?q=LARGE_INTEGER+msdn&quot;&gt;LARGE_INTEGER&lt;/a&gt; es una forma de representar un entero de 64 bits por medio de una unión (&lt;em&gt;union&lt;/em&gt;).&lt;br /&gt;&lt;br /&gt;Como tarea al lector, si es que existe alguno, le queda hacer una versión &quot;portable&quot; (entre Windows y Linux) para medir el rendimiento (con unos cuantos &lt;em&gt;#ifdef WIN32&lt;/em&gt; y &lt;em&gt;#endif&lt;/em&gt; sería suficiente).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;18 de Marzo del 2008&lt;/span&gt;: acá transcribo una macro que me pasó el amigo Carlos Becker para medir el tiempo de una rutina en Linux mediante &lt;a href=&quot;http://www.tin.org/bin/man.cgi?section=3&amp;topic=clock_gettime&quot;&gt;clock_gettime&lt;/a&gt;:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;#define TIME_THIS(X)                                         \
  {                                                          \
    struct timespec ts1, ts2;                                \
    clock_gettime( CLOCK_REALTIME, &amp;amp;ts1 );                   \
    X;                                                       \
    clock_gettime( CLOCK_REALTIME, &amp;amp;ts2 );                   \
    printf( #X &quot; demora: %f\n&quot;,                              \
      (float) ( 1.0*(1.0*ts2.tv_nsec - ts1.tv_nsec*1.0)*1e-9 \
      + 1.0*ts2.tv_sec - 1.0*ts1.tv_sec ) );                 \
  }

/* podemos usarla así */
{
  double x, y, z;
  x = 2.0;
  y = 4.0;
  TIME_THIS(z = sqrt(x*x + y*y));
}
&lt;/pre&gt;Lo que da como resultado:
&lt;pre class=&quot;prettyprint&quot;&gt;z = sqrt(x*x + y*y) demora: 0.015164
&lt;/pre&gt;
&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Conseguir un compilador</title>
   <link href="https://davidcapello.com/blog/cpp/conseguir-un-compilador/"/>
   <updated>2008-02-17T00:00:00+00:00</updated>
   <id>https://davidcapello.com/blog/cpp/conseguir-un-compilador</id>
   <content type="html">&lt;div class=&apos;post&apos;&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Editado 21 de mayo 2011&lt;/b&gt;: Este post se encuentra aquí sólo a fines históricos, ahora usted puede usar el &lt;a href=&quot;http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst&quot;&gt;instalador automático de MinGW&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;b&gt;Editado 9 de septiembre 2010&lt;/b&gt;: Aunque este post contiene información útil de cómo instalar MinGW con gcc 3.4, tal vez prefiera antes probar este &lt;a href=&quot;http://cmasomenos.blogspot.com/2010/06/descargar-mingw-con-gcc-45.html&quot;&gt;nuevo post sobre cómo descargar MinGW con gcc 4.5 de forma automática&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;En este blog vamos a hablar sobre los lenguajes de programación C y C++, y cómo usar software GNU para hacer aplicaciones. También voy a tratar de investigar algo de ensamblador.&lt;br /&gt;&lt;p&gt;De todas formas, para evitar hacer un primer post completamente inútil &quot;de presentación&quot;, voy a pasar a explicarles cómo pueden instalar un compilador gratuito en Windows desde cero, y hacer un pequeño programa &lt;span style=&quot;font-style: italic;&quot;&gt;&quot;Hola Mundo&quot;&lt;/span&gt; sin pensar mucho (eso sí, van a tener que leer un poco). El proceso para Linux es más sencillo, ya que el compilador suele venir instalado por defecto en la mayoría de las distribuciones.&lt;br /&gt;&lt;p&gt;Primero, algunas definiciones importantes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.mingw.org/&quot; style=&quot;font-weight: bold;&quot;&gt;MinGW&lt;/a&gt;: Un conjunto de programas y bibliotecas que permiten crear aplicaciones para Windows.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://gcc.gnu.org/&quot; style=&quot;font-weight: bold;&quot;&gt;GCC&lt;/a&gt;: El compilador. Transforma código escrito en C/C++ a un archivo ejecutable (.exe). En realidad hace miles de maravillas más, pero por ahora nos vamos a quedar con esta definición.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;MSYS&lt;/span&gt;: Es un conjunto mínimo de programas para poder ejecutar scripts &lt;span style=&quot;font-style: italic;&quot;&gt;&quot;a la&quot;&lt;/span&gt; Unix. Además incluye una terminal que emula un pequeño entorno GNU/Linux.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/emacs/&quot; style=&quot;font-weight: bold;&quot;&gt;Emacs&lt;/a&gt;: La madre de los editores de texto. Alguna vez dije que era una porquería o muy complicado, y que conviene usar editores como el &lt;a href=&quot;http://sourceforge.net/projects/rhide&quot;&gt;RHIDE&lt;/a&gt; o &lt;a href=&quot;http://setedit.sourceforge.net/&quot;&gt;Setedit&lt;/a&gt;. Bueno, la cosa es que con &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;un poco&lt;/span&gt;&quot; de práctica uno comprende el poder de esta herramienta.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;make&lt;/span&gt;: Un programa que puede compilar muchos archivos y linkearlos en un ejecutable de forma automatizada (siempre y cuando le escribamos un archivo con las órdenes adecuadas). Generalmente los programadores están acostumbrados a utilizar un &lt;a href=&quot;http://es.wikipedia.org/wiki/Entorno_de_desarrollo_integrado&quot;&gt;IDE&lt;/a&gt; (como el &lt;a href=&quot;http://www.bloodshed.net/devcpp.html&quot;&gt;DevC++&lt;/a&gt;) que maneje el proyecto, calcule las dependencias entre archivos, compile todo lo necesario, linkee, ejecute y depure. Si bien esto es cómodo, espero poder enseñarles a automatizar la compilación y liberarlos de un determinado IDE para compilar los programas.&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;cmd.exe&lt;/span&gt;: Es la línea de comandos de Windows. Si nunca lo utilizó, es hora que se ponga a usarlo. Para iniciar la línea de comandos debe ir al menú &quot;Inicio/Ejecutar...&quot; e introducir &quot;cmd&quot;. ¿Cómo se usa? Bueno, &lt;a href=&quot;http://www.google.com.ar/search?q=introduccion+al+shell+de+comandos+cmd.exe&quot;&gt;empiece a buscar...&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Ahora nos dedicaremos a instalar el MinGW, para eso debe comenzar a bajarse los siguientes archivos (si no sabe &lt;a href=&quot;http://www.7-zip.org/&quot;&gt;cómo descomprimir un archivo .tar.gz...&lt;/a&gt;):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/mingw-runtime-3.13.tar.gz?download&quot;&gt;mingw-runtime-3.13.tar.gz&lt;/a&gt;: Los archivos de cabecera y bibliotecas estándares (stdio.h, math.h, libc, libm, etc.)    &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/w32api-3.10.tar.gz?download&quot;&gt;w32api-3.10.tar.gz&lt;/a&gt;: Archivos de cabecera del API de Win32&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz?download&quot;&gt;gcc-core-3.4.5-20060117-1.tar.gz&lt;/a&gt;: El preprocesador de C y el compilador de C&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz?download&quot;&gt;gcc-g++-3.4.5-20060117-1.tar.gz&lt;/a&gt;: El compilador de C++ y los archivos de cabecera de C++&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/binutils-2.17.50-20060824-1.tar.gz?download&quot;&gt;binutils-2.17.50-20060824-1.tar.gz&lt;/a&gt;: Varios programas utilitarios que sirve para diferentes propósitos (ej: quitar símbolos de depuración con &lt;span style=&quot;font-style: italic;&quot;&gt;strip&lt;/span&gt;, convertir direcciones a líneas de código fuente con &lt;span style=&quot;font-style: italic;&quot;&gt;addr2line&lt;/span&gt;, procesar la información de &lt;a href=&quot;http://en.wikipedia.org/wiki/Performance_analysis&quot;&gt;rendimiento&lt;/a&gt; con &lt;span style=&quot;font-style: italic;&quot;&gt;gprof&lt;/span&gt;, crear librerías con &lt;span style=&quot;font-style: italic;&quot;&gt;ar&lt;/span&gt;, compilar los archivos de recursos de Windows con &lt;span style=&quot;font-style: italic;&quot;&gt;windres&lt;/span&gt;, etc.).&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/mingw32-make-3.81-2.tar.gz?download&quot;&gt;mingw32-make-3.81-2.tar.gz&lt;/a&gt;: La utilidad &lt;span style=&quot;font-style: italic;&quot;&gt;make&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://downloads.sourceforge.net/mingw/gdb-5.2.1-1.exe?download&quot;&gt;gdb-5.2.1-1.exe&lt;/a&gt;: El depurador de código&lt;/li&gt;&lt;/ul&gt;Una vez que consiga todos estos archivos, debe crear una carpeta C:\MinGW (le recomiendo esa ubicación) y descomprimir todo ahí mismo. Para instalar el depurador (gdb) deberá ejecutar el instalador, seguir los pasos, y colocar como carpeta de instalación &quot;C:\MinGW&quot;.&lt;br /&gt;&lt;p&gt;Una vez instalado todo, usted ya está en condiciones para compilar código en C o C++. Antes verifique que en dicha carpeta tiene una estructura de directorios como la siguiente:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;C:\MinGW&lt;br /&gt;  bin\&lt;br /&gt;  doc\&lt;br /&gt;  include\&lt;br /&gt;  info\&lt;br /&gt;  lib\&lt;br /&gt;  libexec\&lt;br /&gt;  man\&lt;br /&gt;  mingw32\&lt;br /&gt;&lt;/pre&gt;Si así es, significa que todo salió bien (bueno, tampoco descomprimir unos archivos es algo tan complicado).&lt;br /&gt;&lt;p&gt;Para estar seguros que el compilador funcione, vamos a crear el programa de prueba por excelencia, el &quot;Hola Mundo&quot;. Abra el bloc de notas (Inicio/Ejecutar/notepad) y escriba en un archivo el siguiente código:&lt;br /&gt;&lt;pre class=&quot;prettyprint&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;  printf(&quot;Hola Mundo\n&quot;);&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Guarde el archivo como &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;C:\MinGW\hola.c&lt;/span&gt;&quot;. Ahora abra la línea de comandos &lt;span style=&quot;font-weight: bold;&quot;&gt;cmd.exe&lt;/span&gt;, y ahí mismo ejecute los siguientes comandos:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;cd C:\MinGW&lt;br /&gt;set PATH=C:\MinGW\bin;%PATH%&lt;br /&gt;gcc hola.c&lt;br /&gt;&lt;/pre&gt;Verá que el archivo &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;a.exe&lt;/span&gt;&quot; se crea en el directorio C:\MinGW. Si ejecuta el programa &lt;span style=&quot;font-weight: bold;&quot;&gt;a.exe&lt;/span&gt; visualizará en la salida de la consola el mensaje más estúpido jamás escrito: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;Hola Mundo&lt;/span&gt;&quot;&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;C:\MinGW&amp;gt;a.exe&lt;br /&gt;Hola Mundo&lt;br /&gt;&lt;/pre&gt;A continuación le paso a explicar qué hicimos en esta ráfaga de pasos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&quot;cd C:\MinGW&quot; es para ubicarnos en el directorio donde se encuentra el archivo o proyecto que queremos compilar (si no sabía esto, es porque todavía no estuvo buscando cómo usar cmd.exe...).&lt;/li&gt;&lt;li&gt;&quot;set PATH=C:\MinGW\bin;%PATH%&quot; es un conjunto de varias cosas: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;PATH&lt;/span&gt;&quot; es una variable de entorno que indica cuáles son los directorios donde podemos encontrar archivos ejecutables (archivos ejecutables como &lt;span style=&quot;font-style: italic;&quot;&gt;gcc.exe&lt;/span&gt;, &lt;span style=&quot;font-style: italic;&quot;&gt;cpp.exe&lt;/span&gt;, etc.); &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;set&lt;/span&gt;&quot; es un comando del shell para cambiar el valor de una variable de entorno; y &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;%PATH%&lt;/span&gt;&quot; devuelve el valor de dicha variable de entorno. Por lo tanto, lo único que estamos haciendo aquí es agregar una nueva ruta (C:\MinGW\bin) a PATH para que el shell encuentre los archivos ejecutables que a nosotros nos interesa (el preprocesador, compilador, etc.). Si desea ver dónde busca el shell los archivos ejecutables actualmente, puede usar el siguiente comando: &quot;&lt;span style=&quot;font-style: italic;&quot;&gt;echo %PATH%&lt;/span&gt;&quot;&lt;/li&gt;&lt;li&gt;&quot;gcc hola.c&quot; compila el programa &quot;hola.c&quot; y deja el resultado (&lt;span style=&quot;font-style: italic;&quot;&gt;linkea&lt;/span&gt; o &lt;span style=&quot;font-style: italic;&quot;&gt;linkedita&lt;/span&gt;) en un archivo llamado &quot;a.exe&quot; (o &quot;a.out&quot; en Linux). En otros posts veremos cómo podemos especificar un nombre distinto a este archivo de salida.&lt;/li&gt;&lt;/ul&gt;De todo lo visto, lo más molesto es la configuración de la variable de entorno, es decir, si pensamos compilar varias veces, cada vez que abramos un shell (cmd.exe) deberemos hacer un &quot;set PATH=C:\MinGW\bin;%PATH%&quot;. Para evitar este paso tenemos dos opciones:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Si tiene accesos de Administrador, puede hacer click derecho sobre &quot;Mi PC&quot;, &quot;Propiedades&quot;, &quot;Opciones Avanzadas&quot;, &quot;Variables de Entorno&quot; y modificar la variable PATH agregándole el valor &quot;C:\MinGW\bin&quot; (recuerde no tocar las demás rutas, además de agregar un &quot;;&quot; para separar las distintas rutas entre sí).&lt;/li&gt;&lt;li&gt;En otro caso, puede crearse un archivo de comandos por lotes mi-mingw.bat para iniciar el shell adecuadamente con el PATH ya configurado. Por ejemplo, un mi-mingw.bat posible podría ser:&lt;br /&gt;&lt;pre class=&quot;console&quot;&gt;set PATH=C:\MinGW\bin;%PATH%&lt;br /&gt;start cmd.exe&lt;br /&gt;&lt;/pre&gt;Este archivo podemos dejarlo en el Escritorio y cada vez que tengamos ganas de compilar, con un simple doble click ya podemos empezar. Inclusive, en vez de iniciar &quot;start cmd.exe&quot; podríamos iniciar algún IDE o editor de texto como Emacs. Pero eso para otro post.&lt;/li&gt;&lt;/ol&gt;Bueno, por hoy me cansé. Cualquier problema o pregunta que tengan, los comentarios están abiertos (y bien moderados :)
&lt;/div&gt;
</content>
 </entry>
 

</feed>
