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

<channel>
	<title>BeOSmAn&#039;s Blooog &#187; Lenguajes</title>
	<atom:link href="http://beosman.org/archivo/category/lenguajes/feed" rel="self" type="application/rss+xml" />
	<link>http://beosman.org</link>
	<description>Breaking with the past to build the future</description>
	<lastBuildDate>Wed, 08 Feb 2012 20:42:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>C#</title>
		<link>http://beosman.org/archivo/2011/informatica/c-sharp.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/c-sharp.html#comments</comments>
		<pubDate>Thu, 01 Dec 2011 18:54:20 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=5299</guid>
		<description><![CDATA[Por necesidades del servicio voy a empezar a programar en C#, así que me he leído un par de manuales y he practicado un poco con ello. Y, la verdad, no me ha convencido demasiado. Así que, por petición popular (si por una persona se le puede llamar &#8220;popular&#8221;), estas son algunas de las conclusiones [...]]]></description>
			<content:encoded><![CDATA[<p>Por <em>necesidades del servicio</em> voy a empezar a programar en <a href="http://es.wikipedia.org/wiki/C_Sharp">C#</a>, así que me he leído un par de manuales y he practicado un poco con ello. Y, la verdad, <a href="https://twitter.com/#!/beoxman/status/139403030180274177">no me ha convencido demasiado</a>. Así que, por <a href="https://twitter.com/#!/albfernandez/status/139419504382967808">petición popular</a> (si por una persona se le puede llamar <em>&#8220;popular&#8221;</em>), estas son algunas de las conclusiones que he sacado, aunque si eres muy fan de C# quizás no deberías seguir leyendo <img src='http://beosman.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> :</p>
<h3>Declaración de tipos</h3>
<p>Extrañamemente se usan formas diferentes para declarar lo mismo. Porque declarar una variable o un nuevo tipo de dato debería ser consistente. Por ejemplo, para declarar una variable se usa <code>&lt;tipo de dato&gt; <strong>&lt;identificador&gt;</strong>;</code>. En cambio, para declarar un alias de un tipo de dato (no hay nuevos tipos) se usa <code>using <strong>&lt;identificador&gt;</strong> = &lt;tipo de dato&gt;;</code>. Y, ya para rematar, para declarar un <code><a href="">delegate</a></code> se usa <code>delegate &lt;valor devuelto&gt; <strong>&lt;identificador&gt;</strong> (&lt;parámetros&gt;);</code>.</p>
<p>¿No sería más sencillo y consistente tener una sintaxis común? Por ejemplo: <code>&lt;tipo de dato&gt; &lt;descripción&gt; <strong>&lt;identificador&gt;</strong>;</code>, con lo que la declaración quedaría:</p>
<pre>
// Variable:
int i;

// Tipo de dato:
typedef int MyInt;

// Usando 'using' (sin introducir ninguna palabra reservada adicional):
using int as MyInt;

// Delegate:
delegate void(int) MyDelegate;
</pre>
<p>Con esto la sintaxis siempre es consistente. Tenemos a la izquierda los tipos y a la derecha, siempre, el nombre tanto de la variable como del tipo nuevo como del delegate (que no deja de ser un tipo nuevo).</p>
<h3>Nuevos tipos de datos</h3>
<p>En C#, al igual que en C++, no se pueden declarar nuevos tipos de datos. Sí, en serio. Lo que estáis pensando ahora mismo es que con typedef sí se puede&#8230; pues no. En realidad es un alias del tipo básico. En C++, este código:</p>
<pre>
typedef int myint_t;
void overloaded_function(int value);
void overloaded_function(myint_t value);  // Error de compilación.
</pre>
<p>Daría error de compilación porque las dos funciones son iguales. <code>myint_t</code> no es un tipo de datos nuevo, sino un alias de <code>int</code>. En C# ocurre lo mismo, sólo que en lugar de declarar los <em>nuevos</em> tipos con <code>typedef</code> (que no tiene esa palabra reservada) se usa <code>using</code>:</p>
<pre>
using myint_t = int;

class Main {
  void overloaded_funcion(int value) {...}
  void overloaded_funcion(myint_t value) {...}  // Error de compilación.
}
</pre>
<p>También se puede hacer alguna triquiñuela, como hacer una clase <code>MyInt</code> que herede de <code>System.Int32</code>. Pero ya habría que implementar ciertas cosas para que funcionase.</p>
<h3>Los métodos y su tipo de acceso</h3>
<p>Es bastante enrevesado el uso de <code>virtual</code>, <code>override</code> y <code>new</code> para controlar el polimorfismo de las clases. Por ejemplo, en el código:</p>
<pre>
class A {
	public virtual void Who() { Console.WriteLine("A"); }
}

class B : A {
	public override void Who() { Console.WriteLine("B"); }
}

class C : B {
	public new virtual void Who() { Console.WriteLine("C"); }
}

class D : C {
	public override void Who() { Console.WriteLine("D"); }
}

C c = new D();
c.Who();	// Escribe "D"; lógico ¿no?

A a = new D();
a.Who();	// ¡Escribe "B"! ¿Dónde está la lógica de funciones virtuales aquí?
</pre>
<p>Es obligatorio que en todos los métodos que se podrán sobreescribir en clases derivadas se ponga <code>virtual</code>; que en todos los métodos que sobreescriben se ponga <code>override</code>; y que si un método oculta a otro se ponga <code>new</code>.</p>
<p>¿No sería más sencillo que todos los métodos fuesen virtuales por defecto (porque cuando haces clases, lo más probable es que las vayas a heredar)? ¿No sería más lógico que cuando declaras un método con el mismo nombre en la clase base, automáticamente se sobreescriba el de la base y, en caso de querer llamar al método de la base, uses <code>super</code>, <code>base</code> o similar?</p>
<p>Por cierto, decidme un caso <strong>real</strong> donde se use esta funcionalidad.</p>
<h3>El problema de la clase base frágil</h3>
<p>En <a href="http://ssw.jku.at/Teaching/Lectures/CSharp/Tutorial/Part2.pdf">este manual se menciona el problema de la clase base frágil</a>, que habla de que en Java podría suceder esto, teniendo en principio estas clases:</p>
<pre>
class BaseClass {
	public void CleanUp() {
		System.out.println("BaseClass.CleanUp()");
	}
}

class DerivedClass extends BaseClass {
	public void Delete() {
		System.out.println("DerivedClass.Delete()");
	}
	public void CleanUp() {
		Delete();
	}
}

public class Test {
	public static void main(String[] args) {
		BaseClass k = new DerivedClass();
		k.CleanUp();
	}
}
</pre>
<p>La salida de este programa sería:</p>
<p class="terminal">
$ javac Test.java &#038;&#038; java Test<br />
DerivedClass.Delete();<br />
$
</p>
<p>Si luego implementamos el método <code>Delete()</code> en la clase base de esta forma:</p>
<pre>
class BaseClass {
	public void CleanUp() {
		System.out.println("BaseClass.CleanUp()");
	}
	public void Delete() {
		System.out.println("Delete all the world!");
	}
}
</pre>
<p>Según el manual, ¡podríamos borrar el mundo!</p>
<p>Esto sería un verdadero problema&#8230; si existiese. Pero es muy fácil comprobar que no se produce. La salida con la clase modificada es la misma que sin ella. Sólo usando <code>super.Delete()</code> se podría borrar el mundo.</p>
<h3>Ámbito global o local</h3>
<p>En C#, si una clase oculta un espacio de nombres, para acceder a dicho espacio introduce una nueva palabra que no está reservada, pero que hay que recordar: <code>global</code>. Por ejemplo:</p>
<pre>
class Main {

  public class System {}

  static void Main(string[] args) {
    System.Console.WriteLine("¡Hola mundo!");  // Error: la clase 'System' oculta
                                               // el espacio de nombres 'System'.
    global::System.Console.WriteLine("Esto sí funciona.");
  }
}
</pre>
<p>¿No sería más sencillo, en lugar de introducir otro identificador nuevo, usar sólo el operador <code>::</code>, como hace C++ o, incluso, usar el operador <code>.</code>?</p>
<h3>Comportamientos extraños de las variables</h3>
<p>Resulta que si declaras una variable de tipo <code>delegate</code>, esta se comporta como una <strong>lista</strong> de delegates que se llaman todos seguidos:</p>
<pre>

class Test {
	void Notify1(string text) {
		System.Console.WriteLine("Hello " + text);
	}
	void Notfiy2(string text) {
		System.Console.WriteLine("Goodbye " + text);
	}
}

Test test = new Test();

delegate void Notifier(string text);

Notifier notifier;
notifier = new Notifier(test.Notify1);
notifier += new Notifier(test.Notify2);

notifier("Manolito");

// La salida será:
// Hello Manolito
// Goodbye Manolito
</pre>
<p>¿Nos aclaramos? ¿<code>Notifier</code> es una variable o es una lista de variables? Y si todos los <code>delegate</code>s asignados devuelven algún valor, sólo se devuelve el último ejecutado. ¿Y el resto?</p>
<h3>Recorriendo listas</h3>
<p>C# añade el <code>foreach</code>, que no es más que lo que se conoce como <em><a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a></em> para el bucle <code>for</code> de toda la vida evitando que el programador use variables índice:</p>
<pre>

string[] stringArray = new string[] { /* Inicialización */ };

foreach(var s in stringArray) {
  System.Console.WriteLn(s);
}
</pre>
<p>Pero no estoy criticando ese <em>syntactic sugar</em>, todo lo contrario, eso me parece muy bien. Cuanto menos código se escriba y haga más cosas, mejor.</p>
<p>Lo que ya no me parece tan bien es que en ese bucle <code>foreach</code> sólo se tenga acceso a los valores de la lista a recorrer y no se tenga acceso al índice de dicha lista. Sí, simplemente a la famosa <code>i</code> que se omite para que el programador escriba menos código.</p>
<p>Y por culpa de esto, en caso de necesitarla, pues tienes que declararla fuera e incrementarla manualmente. Vamos, con en un bucle <code>for</code>.</p>
<h3>Anidamiento</h3>
<p>No se permiten métodos anidados, es decir, declaración e implementación de métodos dentro de otros métodos. Sí, venga, vale, se puede “solucionar” mediante el uso de <code>delegates</code>, pero eso no es permitir métodos anidados, eso es una chapuza.</p>
<p>Y además, ya para rematar, tampoco se permite declarar estructuras ni clases dentro de métodos. Como está orientado a objetos, pues toda declaración adicional tiene que ir dentro de la clase.</p>
<p><strong>Actualización 2011-12-05</strong>: C y C++ tampoco permiten métodos anidados <a href="http://beosman.org/archivo/2011/informatica/c-sharp.html#comment-22891">como me indican en un comentario</a>. Esto lo puse porque yo los he usado para resolver algún problema, sólo que no recuerdo ni el lenguaje ni el proyecto en el que lo hice. ¿Pascal quizás?</p>
<h3>Atributos</h3>
<p>Los atributos del lenguaje también son otra cosa que está muy bien dentro de un lenguaje. Permiten extender la funcionalidad del compilador, por ejemplo, para hacer compilación condicional, controlar entre diferentes versiones o arquitecturas, marcar elementos como obsoletos… pero, me pregunto, ¿por qué la sintaxis no es coherente con el resto del lenguaje y hay que añadir triquiñuelas del estilo <code>[Conditional("Debug")]</code> al código?</p>
<h3>Conclusión</h3>
<p>Después de despotricar un poco toca una pequeña conclusión:</p>
<p>Si Microsoft tuvo la oportunidad de crear un nuevo lenguaje de programación desde cero, para ellos solos, sin que nadie se pueda meter, sin que nadie le diera lecciones, con la posibilidad de innovar, de mejorar lo que había hasta el momento ¿por qué lo ha hecho tan retorcido e incoherente? Porque sí, en serio, es retorcido. Hasta C++ —que mira que a <a href="http://es.wikipedia.org/wiki/Bjarne_Stroustrup">Bjarne Stroustrup</a> se le fue la olla cuando lo diseñó— es más consistente y coherente que C#. C# parece un batiburrilo de Java, C++ y alguna funcionalidad adicional como los <code>delegates</code> que más que ser un lenguaje nuevo es lo mismo de siempre con otro nombre. Y propietario, claro.</p>
<p>Y, bueno, de la compilación a código intermedio en lugar de a código máquina directamente ya no hablamos. Eso es una decisión que han tomado pero que tampoco es que importe demasiado. Recordemos que esta generación de código es una de las fases de compilación que se puede cambiar sin afectar a la sintaxis.</p>
<p>Concluyendo, a mi, personalmente, no me convence en absoluto. Pero claro, si quieres hacer un proyecto decente para sistemas Windows, no queda otra que hacerlo en C# o pelearte con los punteros en C++.</p>
<p>O usar <a href="http://es.wikipedia.org/wiki/Pascal_(lenguaje_de_programaci%C3%B3n)">Pascal</a> <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .</p>
<p class="postdata">
<abbr title="Postdata">P.D.</abbr>: Yo, en realidad, soy más del <a href="http://www.d-programming-language.org">lenguaje de programación D</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/c-sharp.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Representar un número en binario en C++</title>
		<link>http://beosman.org/archivo/2011/informatica/representar-un-numero-en-binario-en-cpp.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/representar-un-numero-en-binario-en-cpp.html#comments</comments>
		<pubDate>Wed, 16 Nov 2011 19:01:20 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=5247</guid>
		<description><![CDATA[Puede que alguna vez en tu vida como desarrollador de software te veas en la necesidad de representar números en su forma binaria. Hay infinidad de algoritmos para ello, por eso no me voy a enrollar mucho. Aquí te muestro tres en C++: La forma sencilla e intuitiva template &#60;typename T&#62; char* ValueToBits(T value) { [...]]]></description>
			<content:encoded><![CDATA[<p>Puede que alguna vez en tu vida como desarrollador de software te veas en la necesidad de representar números en su forma binaria. Hay infinidad de algoritmos para ello, por eso no me voy a enrollar mucho. Aquí te muestro tres en <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a>:</p>
<h3>La forma sencilla e intuitiva</h3>
<pre>
template &lt;typename T&gt;
char*
ValueToBits(T value) {
	int length = sizeof(T)*8;
	char* result = new char[length];
	result[length] = '\0';
	for(int i = 0; i &lt; length; i++) {
		result[length-1-i] = (value &#038; (1 &lt;&lt; i) ? '1' : '0');
	}
	return result;
}
</pre>
<p>Este algoritmo es fácilmente adaptable a <a href="http://es.wikipedia.org/wiki/C_(lenguaje_de_programaci%C3%B3n)">C estándar</a>. Basta con quitar la plantilla, sobrecargar esta función con más versiones, una por cada tipo de dato que se quiera convertir, y usar <code><a href="http://en.wikipedia.org/wiki/C_dynamic_memory_allocation">malloc()</a></code> en lugar de <code>new</code>. Y, por supuesto, no hay que olvidarse de liberar la memoria del valor devuelto, o bien con <code>delete[]</code> si usas <code>new</code>, o bien con <code>free()</code> si usas <code>malloc()</code>.</p>
<h3>Usando <code>std::string</code>s</h3>
<p>Este algoritmo es similar al anterior pero usando <code>std::string</code>s, con lo que evitamos el uso de <code>char*</code> y la reserva manual de memoria.</p>
<pre>
#include &lt;string&gt;

using std::string;

template &lt;typename T&gt;
const string
ValueToBits(T value) {
	string result;
	for(int i = 0; i &lt; sizeof(T)*8; i++) {
		result = (value &#038; (1 &lt;&lt; i) ? "1" : "0") + result;
	}
	return result;
}
</pre>
<h3>La forma elegante</h3>
<p>Y ya que estamos en C++, ¿por qué no usar toda la potencia que nos proporciona la <abbr title="Standard Template Library" lang="en"><a href="http://en.wikipedia.org/wiki/Standard_Template_Library">STL</a></abbr>?</p>
<pre>
#include &lt;bitset&gt;

using std::bitset;

template &lt;typename T&gt;
const string
ValueToBits(T value) {
	return bitset&lt;sizeof(T)*8&gt;(value).to_string();
}
</pre>
<p>No me digáis que esta forma no es <strong>muy</strong> elegante <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/representar-un-numero-en-binario-en-cpp.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El género</title>
		<link>http://beosman.org/archivo/2011/citas/el-genero.html</link>
		<comments>http://beosman.org/archivo/2011/citas/el-genero.html#comments</comments>
		<pubDate>Fri, 02 Sep 2011 13:04:08 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Citas y frases]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=4903</guid>
		<description><![CDATA[El uso de circunloquios para reflejar que se refiere a &#8220;ellos y ellas&#8221; solo tiene sentido si tu mente es tan simple como para pensar que podría estar refiriéndome a &#8220;ellos&#8221; y no a &#8220;ellas&#8221;. En un comentario de Menéame sobre la noticia de que por fin se usa el sentido común para el género [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
El uso de circunloquios para reflejar que se refiere a <em>&#8220;ellos y ellas&#8221;</em> solo tiene sentido si tu mente es tan simple como para pensar que podría estar refiriéndome a <em>&#8220;ellos&#8221;</em> y no a <em>&#8220;ellas&#8221;</em>.
</p></blockquote>
<p class="alignright">
En un <a href="http://www.meneame.net/story/impone-masculino-generico/0003">comentario de Menéame</a> sobre la noticia de que <a href="http://www.meneame.net/story/impone-masculino-generico">por fin se usa el sentido común para el género en el lenguaje</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/citas/el-genero.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Llamadas encadenadas en C++</title>
		<link>http://beosman.org/archivo/2011/informatica/llamadas-encadenadas-en-c.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/llamadas-encadenadas-en-c.html#comments</comments>
		<pubDate>Wed, 24 Aug 2011 17:36:38 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=4772</guid>
		<description><![CDATA[Esta entrada llevaba tiempo en el tintero, por eso de tener algo de tiempo libre en vacaciones para dedicarlo a leer y elucubrar soluciones. Por ejemplo, aquí tenemos una prueba de concepto para tener la misma funcionalidad que el operador &#60;&#60; de C++ pero usando llamadas encadenas. Y hace (casi) lo mismo: puede enviar a [...]]]></description>
			<content:encoded><![CDATA[<p>Esta entrada llevaba tiempo en el tintero, por eso de tener algo de tiempo libre en vacaciones para dedicarlo a leer y elucubrar soluciones.</p>
<p>Por ejemplo, aquí tenemos una prueba de concepto para tener la misma funcionalidad que el operador <code>&lt;&lt;</code> de <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a> pero usando llamadas encadenas. Y hace (casi) lo mismo: puede enviar a la <a href="http://es.wikipedia.org/wiki/Salida_est%C3%A1ndar">salida estándar</a> cualquier tipo de variable, incluyendo cadenas, <a href="http://es.wikipedia.org/wiki/N%C3%BAmero_entero">números enteros</a>, <a href="http://es.wikipedia.org/wiki/N%C3%BAmero_real">números reales</a> y <a href="http://es.wikipedia.org/wiki/Booleano">booleanos</a>, sólo que con un formato de llamada diferente.</p>
<p>La implementación de la clase base, pudiendo extenderla lo que se quiera, es la siguiente:</p>
<div class="source">
<p><span class="directive">#include</span> &lt;iostream&gt;<br />
<span class="directive">#include</span> &lt;string&gt;<br />
<span class="directive">#include</span> &lt;sstream&gt;<br />
&nbsp;</p>
<p><span class="keyword">using</span> std::cout;<br />
<span class="keyword">using</span> std::endl;<br />
<span class="keyword">using</span> std::flush;<br />
<span class="keyword">using</span> std::string;<br />
<span class="keyword">using</span> std::stringstream;<br />
&nbsp;</p>
<p><span class="keyword">class</span> Stdout {<br />
  <span class="keyword">private</span>:<br />
    stringstream _buffer;<br />
  <span class="keyword">public</span>:<br />
    Stdout() : _buffer() {}<br />
    ~Stdout() {}<br />
    <span class="keyword">void</span> clear() {<br />
      _buffer.str(<span class="string">&quot;&quot;</span>);<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const char</span> c) {<br />
      string s;<br />
      s += c;<br />
      _buffer &lt;&lt; s;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const char</span>* text) {<br />
      _buffer &lt;&lt; text;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const</span> string text) {<br />
      _buffer &lt;&lt; text;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const int</span> i) {<br />
      _buffer &lt;&lt; i;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const float</span> f) {<br />
      _buffer &lt;&lt; f;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const double</span> d) {<br />
      _buffer &lt;&lt; d;<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    Stdout&#038; <span class="keyword">operator</span> () (<span class="keyword">const bool</span> b) {<br />
      _buffer &lt;&lt; (b ? <span class="string">&quot;true&quot;</span> : <span class="string">&quot;false&quot;</span>);<br />
      <span class="keyword">return</span> *<span class="keyword">this</span>;<br />
    }<br />
    <span class="keyword">void</span> flush() {<br />
      cout &lt;&lt; _buffer.str() &lt;&lt; ::flush;<br />
      clear();<br />
    }<br />
    <span class="keyword">void</span> endl() {<br />
      cout &lt;&lt; _buffer.str() &lt;&lt; ::endl;<br />
      clear();<br />
    }<br />
};</p>
</div>
<p>Y un ejemplo de funcionamiento sería:</p>
<div class="source">
<p><span class="keyword">int</span><br />
main() {<br />
  Stdout stdout;<br />
  stdout(<span class="string">&quot;Llamadas encadenadas: enteros: &quot;</span>)(42)(<span class="string">&apos;;&apos;</span>)(<span class="string">&quot; reales: &quot;</span>)(25.4)(<span class="string">&apos;;&apos;</span>)(<span class="string">&quot; y booleanos: &quot;</span>)(<span class="keyword">false</span>)(<span class="string">&apos;.&apos;</span>).endl();<br />
  <span class="keyword">return</span> 0;<br />
}</p>
</div>
<p>Siendo la salida:</p>
<p class="terminal">
$ make &amp;&amp; ./test<br />
Llamadas encadenadas: enteros: 42; reales: 25.4; y booleanos: false.<br />
$
</p>
<p>No tiene la misma funcionalidad que el operador <code>&lt;&lt;</code> porque, entre otras cosas, si se quiere añadir otro elemento imprimible habría que derivar la clase, mientras que con el operador <code>&lt;&lt;</code> bastaría con sobrecargarlo. Pero no me digáis que no es elegante ¿eh? <img src='http://beosman.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/llamadas-encadenadas-en-c.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lazarus, el clon de Delphi para FreePascal</title>
		<link>http://beosman.org/archivo/2011/informatica/lazarus-el-clon-de-delphi-para-freepascal.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/lazarus-el-clon-de-delphi-para-freepascal.html#comments</comments>
		<pubDate>Tue, 22 Mar 2011 15:29:08 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=3976</guid>
		<description><![CDATA[En el inicio de la carrera, uno de los lenguajes que usábamos era Pascal1 porque era un lenguaje muy bueno para aprender por su sintaxis y no tan complicado como el C con los punteros (aunque también los tiene). Después, con el ansia de hacer cosas más «profesionales» descubrí Delphi allá por la versión 3, [...]]]></description>
			<content:encoded><![CDATA[<p class="aligncenter">
<a href="/uploads/2011/03/lazarus.png"><img src="/uploads/2011/03/lazarus-650x406.png" alt="IDE de Lazarus" title="IDE de Lazarus" width="650" height="406" class="alignnone size-large wp-image-3977" /></a>
</p>
<p>En el inicio de la carrera, uno de los lenguajes que usábamos era <a href="http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_Pascal">Pascal</a><sup><a href="#nota20110322">1</a></sup> porque era un lenguaje muy bueno para aprender por su sintaxis y no tan complicado como el C con los punteros (aunque también los tiene).</p>
<p>Después, con el ansia de hacer cosas más <em>«profesionales»</em> descubrí <a href="http://es.wikipedia.org/wiki/Delphi">Delphi</a> allá por la versión 3, para tener ya aplicaciones con interfaz gráfica escritas en Pascal <em>avanzado</em> (orientado a objetos y demás).</p>
<p>Es en esta época que mezcla el estudio de la carrera con la programación en Delphi en la que soy más productivo: hice infinidad de aplicaciones, principalmente para aprender a programar (por mi cuenta, todo hay que decirlo) aunque alguna sí que se salvó y <a href="/proyectos"><del>usaba</del> uso habitualmente</a>.</p>
<p>Luego, con esto de la salida del estudio para integrarse en el mundo laboral, dejé de lado el Delphi para centrarme en&#8230; bueno, en lo que tocara en ese momento.</p>
<p>Pero ahora me he encontrado con que tengo que volver a hacer una aplicación, con interfaz gráfica (un editor de <acronym title="JavaScript Object Notation" lang="en"><a href="http://es.wikipedia.org/wiki/JSON">JSON</a></acronym> principalmente aunque algo <em>especial</em>) y tiene que funcionar tanto en Windows como en Linux. En su momento probé Java pero necesitaba dos librerías que había que distribuir con el <code>*.jar</code>, así que le volví a dar una oportunidad al Pascal, aunque esta vez de la mano de <a href="http://es.wikipedia.org/wiki/Lazarus">Lazarus</a> y <a href="http://es.wikipedia.org/wiki/Free_Pascal">FreePascal</a>.</p>
<p>¿Y por qué FreePascal/Lazarus? Pues porque me ha sorprendido muy gratamente que el código fuente se compila y ejecuta sin ningún cambio en Windows y Linux (obviamente son ejecutables distintos pero un sólo código fuente). No hay que preocuparse en ningún momento de directivas de compilación, de hacer diferente código para diferentes sistemas operativos y basta con distribuir un sólo ejecutable.</p>
<p>Además, la interfaz gráfica es totalmente coherente con la interfaz general del sistema sin ningún cambio en el código. Si estás en Linux tienes los temas de Linux y si estás en Windows tienes los temas de Windows. Incluso <a href="http://wiki.lazarus.freepascal.org/Aero_Glass">con los efectos de Windows 7</a>.</p>
<p>Cierto es que hay lenguajes más <em>&#8220;modernos&#8221;</em> como Python, pero digamos que Python y yo no somos muy amigos. Y pongo <em>&#8220;modernos&#8221;</em> entre comillas porque en realidad no importa la modernidad del lenguaje: <a href="http://es.wikipedia.org/wiki/C_(lenguaje_de_programaci%C3%B3n)">C</a> es de 1972, <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a> de 1980 y <a href="http://es.wikipedia.org/wiki/Cobol">Cobol</a> (el lenguaje que usan muchísimos sistemas bancarios) es de 1960.</p>
<p>En definitiva, si queréis desarrollar rápido una aplicación y habéis hecho vuestros pinitos en Pascal/Delphi hace sus años, Lazarus es una buena opción. Eso sí, no le pidáis peras al olmo porque esto es para lo que es: desarrollo rápido pero casi sin planificación y con un código un poco <em>spaghetti</em> (es lo que tiene el <a href="http://es.wikipedia.org/wiki/Programaci%C3%B3n_dirigida_por_eventos">desarrollo dirigido a eventos</a>). Y tened en cuenta también que esta experiencia no os servirá para mucho más. Aún así a mi me está resolviendo la papeleta de una forma muy&#8230; <em>elegante</em> <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p id="nota20110322" style="color: gray;">
<strong>Nota</strong>: Considero que Pascal es un lenguaje de programación excelente para aprender a programar porque abstrae mucho más que C y similares de los entresijos de la arquitectura del ordenador centrando la atención en los algoritmos y en las estructuras de datos. Y lo mismo pienso de la programación orientada a objetos: no se debería ver hasta tener una buena base de programación estructura y, ni mucho menos, iniciarse en la programación usando <acronym title="Programación Orientada a Objetos">POO</acronym>. Y parece que <a title="Barrapunto: La Universidad Carnegie-Mellon elimina la programación OO de su primer curso" href="http://barrapunto.com/articles/11/03/22/0530213.shtml">esto último no soy el único que lo piensa</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/lazarus-el-clon-de-delphi-para-freepascal.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lanzar excepciones de forma polimórfica en C++</title>
		<link>http://beosman.org/archivo/2011/informatica/lazar-excepciones-de-forma-polimorfica-en-cpp.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/lazar-excepciones-de-forma-polimorfica-en-cpp.html#comments</comments>
		<pubDate>Thu, 24 Feb 2011 19:17:42 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=3854</guid>
		<description><![CDATA[Otro de mis ladrillos sobre C++. Esta vez sobre lanzamiento de excepciones polimórficas en C++ sobre Linux. Vamos al lío: Para ponernos en antecedentes, digamos que tenemos una aplicación multihilo escrita en C++ en Linux. Cuando en uno de los hilos se produce una excepción, esta debe ser atrapada (try { ... } catch(...) { [...]]]></description>
			<content:encoded><![CDATA[<p>Otro de mis ladrillos sobre C++. Esta vez sobre lanzamiento de excepciones polimórficas en C++ sobre Linux. Vamos al lío:</p>
<p>Para ponernos en antecedentes, digamos que tenemos una aplicación multihilo escrita en C++ en Linux. Cuando en uno de los hilos se produce una excepción, esta debe ser atrapada (<code>try { ... } catch(...) { ... }</code>) dentro del propio hilo. En caso de que no se haga así, la excepción se propaga al hilo principal (<code>main()</code>) sin posibilidad de atraparla, con lo que la aplicación finaliza.</p>
<p>Para resumir este punto: las excepciones no se propagan entre diferentes hilos de ejecución por lo que hay que atraparlas y procesarlas dentro del propio hilo.</p>
<p>Pero ¿qué pasa cuando queremos que una excepción sí se propague a otros hilos? Es decir, que un error que se produce en un hilo se notifique a otro hilo para que tome medidas. Por ejemplo, tenemos un hilo que gestiona las comunicaciones y otro que gestiona la interfaz. Cuando se produce un error de comunicación es la interfaz la que tiene que notificar al usuario de dicho error.</p>
<p>Soluciones existen varias. Una de ellas es enviar un mensaje con la excepción que se produce al hilo que la procesa aunque hay que tener en cuenta que debe haber una arquitectura de paso de mensajes entre hilos previa.</p>
<p>Por ejemplo, en pseudocódigo, el hilo de comunicaciones:</p>
<div class="source">
<p><span class="keyword">void</span><br />
hilo_comunicaciones() {<br />
  <span class="keyword">while</span>(mensaje = cola_mensajes.getMensaje()) {<br />
    <span class="keyword">try</span> {<br />
      enviar_mensaje(mensaje);<br />
      mensaje = recibir_respuesta();<br />
    } <span class="keyword">catch</span>(Exception&#038; e) {<br />
      notificar_interfaz(e);<br />
    }<br />
  }<br />
}</p>
</div>
<p>Y ahora el hilo de proceso de las notificaciones en la interfaz:</p>
<div class="source">
<p><span class="keyword">void</span><br />
hilo_proceso_notificaciones_error_comunicaciones(Exception&#038; e) {<br />
  <span class="keyword">try</span> {<br />
    <span class="keyword">throw</span> e;<br />
  } <span class="keyword">catch</span>(ComunicationException&#038; e) {<br />
    <span class="comment">// procesar excepciones relativas a la conexión</span><br />
  } <span class="keyword">catch</span>(TimeOutException&#038; e) {<br />
    <span class="comment">// procesar excepciones relativas al fallo de la conexión por tiempo</span><br />
  } <span class="keyword">catch</span>(ProtocolException&#038; e) {<br />
    <span class="comment">// procesar excepciones por errores de protocolo</span><br />
  } <span class="keyword">catch</span>(&#8230;) {<br />
    <span class="comment">// procesar excepciones generales</span><br />
  }<br />
}</p>
</div>
<p>El problema del proceso de procesado de excepciones en la interfaz es que al relanzar la excepción que se recibe como parámetro (<code>throw e;</code>) esta no es la excepción recibida en el hilo de comunicaciones, es decir, no hay polimorfismo por lo que siempre se procesa como una excepción general en lugar de la correspondiente.</p>
<p>La opción de usar <code>typeid(e).name()</code> en la excepción para procesar su tipo no es viable porque es demasiado costosa (el operador <code>typeid</code> es bastante costoso) y porque el nombre de la excepción no es estándar, esto es, en GNU C++ (g++) el nombre está <em>&#8220;retorcido&#8221;</em>, <em><a href="http://en.wikipedia.org/wiki/Name_mangling">mangled</a></em> en inglés.</p>
<p>La opción recomendable es añadir a la excepción base de tu aplicación, teniendo en cuenta que para tu aplicación has desarrollado una jerarquía de excepciones acorde con su funcionalidad, <a href="http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.16">un método virtual que implementen las excepciones derivadas</a> donde, simplemente, se lancen a sí mismas.</p>
<p>Un código de ejemplo sería el siguiente:</p>
<div class="source">
<p><span class="comment">// Excepción base de la jerarquía de excepciones de mi aplicación</span><br />
<span class="keyword">class</span> Exception : <span class="keyword">public</span> runtime_error {<br />
  <span class="keyword">public</span>:<br />
    Exception(<span class="keyword">const</span> string msg) : runtime_error(msg) {}<br />
    <span class="keyword">virtual</span> <span class="keyword">void</span> raise() { <span class="keyword">throw</span> *<span class="keyword">this</span>; }<br />
};</p>
<p><span class="comment">// Excepción que se lanza cuando hay un error de acceso denegado</span><br />
<span class="keyword">class</span> AccessDeniedException : <span class="keyword">public</span> Exception {<br />
  <span class="keyword">public</span>:<br />
    AccessDeniedException(<span class="keyword">const</span> string msg) : Exception(msg) {}<br />
    <span class="keyword">virtual</span> <span class="keyword">void</span> raise() { <span class="keyword">throw</span> *<span class="keyword">this</span>; }</p>
<p>};</p>
<p><span class="comment">// Resto de excepciones derivadas conforme a los</span><br />
<span class="comment">// errores que se quieren notificar</span></p>
</div>
<p>Con esta forma de declarar las excepciones, el código de gestión de las notificaciones de error en la interfaz quedaría:</p>
<div class="source">
<p><span class="keyword">void</span><br />
hilo_proceso_notificaciones_error_comunicaciones(Exception&#038; e) {<br />
  <span class="keyword">try</span> {<br />
    <strong>e.raise();</strong><br />
  } <span class="keyword">catch</span>(ComunicationException&#038; e) {<br />
    <span class="comment">// procesar excepciones relativas a la conexión</span><br />
  } <span class="keyword">catch</span>(TimeOutException&#038; e) {<br />
    <span class="comment">// procesar excepciones relativas al fallo de la conexión por tiempo</span><br />
  } <span class="keyword">catch</span>(ProtocolException&#038; e) {<br />
    <span class="comment">// procesar excepciones por errores de protocolo</span><br />
  } <span class="keyword">catch</span>(&#8230;) {<br />
    <span class="comment">// procesar excepciones generales</span><br />
  }<br />
}</p>
</div>
<p>Con lo que funcionaría sin ningún problema ya que <a href="http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.16">la excepción se lanza de forma polimórfica</a> al usar un método virtual en la clase base que implementan todas las clases derivadas.</p>
<p>Para hacer una prueba se puede <a href="/download/exception-test.cpp">descargar un archivo con un programa de ejemplo</a> (1,4 <abbr title="Kilobytes">KB</abbr>). Para compilarlo basta con ejecutar el comando <code>g++ -o test exception-test.cpp</code>.</p>
<p>Y por ir un poco más allá, se podría pensar que para implementar todas las excepciones que usa una aplicación habría que escribir bastante código, además, la mayoría sería repetido; lo único que cambiaría sería el nombre de la excepción y del constructor, el resto es todo igual.</p>
<p>Bueno, pues para eso están las <a href="http://es.wikipedia.org/wiki/Preprocesador_de_C">macros de C</a>: se puede crear una macro a la que se le pase como parámetro el nombre de tu nueva excepción y que ella genere todo el código restante. Pero no olvidéis que <a href="http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.5">las macros son <em>malignas</em> en 4 formas diferentes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/lazar-excepciones-de-forma-polimorfica-en-cpp.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Clases en C++ con constructores con parámetros variables (variadic functions)</title>
		<link>http://beosman.org/archivo/2011/informatica/clases-en-cpp-con-constructores-con-parametros-variables-variadic-functions.html</link>
		<comments>http://beosman.org/archivo/2011/informatica/clases-en-cpp-con-constructores-con-parametros-variables-variadic-functions.html#comments</comments>
		<pubDate>Fri, 21 Jan 2011 17:10:47 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=3660</guid>
		<description><![CDATA[Tanto C como C++ tienen la característica, mediante macros, de crear funciones con un número indefinido de argumentos. Esto es lo que se conoce como variadic functions. Un ejemplo de una función en C con argumentos variables sería el siguiente: #include &#60;stdarg.h&#62; int variadic_function(int arg_count,...) { va_list arg_list; va_start(arg_list,arg_count); int i, sum; for(i = 0; [...]]]></description>
			<content:encoded><![CDATA[<p>Tanto <a href="http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_C">C</a> como <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a> tienen la característica, mediante <a href="http://en.wikipedia.org/wiki/Macro_(computer_science)">macros</a>, de crear funciones con un número indefinido de argumentos. Esto es lo que se conoce como <em><a href="http://en.wikipedia.org/wiki/Variadic_function">variadic functions</a></em>.</p>
<p>Un ejemplo de una función en C con argumentos variables sería el siguiente:</p>
<div class="source">
<p><span class="directive">#include &lt;stdarg.h&gt;</span></p>
<p><span class="keyword">int</span><br />
variadic_function(<span class="keyword">int</span> arg_count,<span>.</span><span>.</span><span>.</span>) {<br />
  va_list arg_list;<br />
  va_start(arg_list,arg_count);<br />
  <span class="keyword">int</span> i, sum;<br />
  <span class="keyword">for</span>(i = 0; i &lt; arg_count; i++) {<br />
    sum += va_arg(arg_list,int);  <span class="comment">// acciones con el argumento</span><br />
  }<br />
  <span class="keyword">return</span> sum;<br />
}</p>
</div>
<p>Para declarar una función que tenga un número indefinido de argumentos es necesario incluir los puntos suspensivos (&#8230;) como argumento, pero al menos debe tener uno que no sea indefinido, esto es, primero un argumento y, posteriormente, los puntos suspensivos. Esto es así porque en la función <code>va_start()</code> hay que pasarle, como segundo argumento, el nombre del último argumento conocido de la función. Si no tuviese al menos un argumento conocido no se podría pasar este argumento a la función <code>va_start()</code>.</p>
<p>También se pueden crear métodos (funciones dentro de clases) que tengan la lista de argumentos variable, incluidos los constructores de las clases, de la forma:</p>
<div class="source">
<p><span class="keyword">class</span> MyClass {<br />
  <span class="keyword">public</span>:<br />
    MyClass(<span>.</span><span>.</span><span>.</span>);<br />
};</p>
</div>
<p>Y dirán ustedes ¿y aquí por qué no se pone al menos un argumento como nos acabas de indicar?</p>
<p>Y yo voy a responder con otra pregunta: ¿qué es lo que te enseñan el primer día de curso de programación orientada a objetos sobre los métodos de una clase? Que los métodos no estáticos de una clase tienen un argumento implícito que es un puntero a la instancia de dicha clase. El famoso puntero <code>this</code> en lenguajes como C++, <a href="http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_Java">Java</a>, <a href="http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_D">D</a> y alguno que otro más.</p>
<p>Y como este argumento es el primero del método, se puede pasar sin problemas como segundo argumento de la función <code>va_start()</code> para indicar que es el último definido de la lista. La implementación sería, más o menos, así:</p>
<div class="source">
<p><span class="directive">#include &lt;cstdarg&gt;</span></p>
<p><span class="keyword">using namespace</span> std;</p>
<p><span class="directive">#include &quot;MyClass.hpp&quot;</span></p>
<p>MyClass::MyClass(<span>.</span><span>.</span><span>.</span>) {<br />
  <span class="keyword">int</span> size = <em>X</em>;  <span class="comment">// el tamaño lo tenemos que tener especificado de alguna forma</span><br />
  <span class="keyword">int</span> sum = 0;<br />
  va_list arg_list;<br />
  va_start(arg_list,<strong><span class="keyword">this</span></strong>);<br />
  <span class="keyword">for</span>(<span class="keyword">int</span> i = 0; i &lt; size; i++) {<br />
    sum += va_arg(arg_list,<span class="keyword">int</span>);<br />
  }<br />
  va_end(arg_list);<br />
}</p>
</div>
<p>Esto de los argumentos indefinidos en C y C++ es una de las <em>chapuzas</em> que hay para tener esta funcionalidad ya que, en su mayoría, se hace con macros (aunque están implementadas de forma interna al compilador).</p>
<p>Hasta que no tengamos el estándar <a href="http://es.wikipedia.org/wiki/C%2B%2B0x">C++0x</a> (el nuevo estándar de C++ que supongo que ya quedará poco para que salga definitivamente) no tendremos esta característica incluida en el lenguaje. Incluso se ha ampliado a <a href="http://en.wikipedia.org/wiki/Variadic_templates">parámetros variables en las plantillas (<em>variadic templates</em>)</a>, con lo que podremos tener <a href="http://es.wikipedia.org/wiki/Tupla">tuplas</a> de <em>n</em> elementos de distinto tipo. Pero, de momento, nos conformaremos <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2011/informatica/clases-en-cpp-con-constructores-con-parametros-variables-variadic-functions.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contra la tontuna lingüística un poco de gramática bien explicada</title>
		<link>http://beosman.org/archivo/2010/lenguajes/contra-la-tontuna-linguistica-un-poco-de-gramatica-bien-explicada.html</link>
		<comments>http://beosman.org/archivo/2010/lenguajes/contra-la-tontuna-linguistica-un-poco-de-gramatica-bien-explicada.html#comments</comments>
		<pubDate>Wed, 10 Nov 2010 19:55:23 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=3104</guid>
		<description><![CDATA[Yo no soy víctima de la LOGSE. Tengo 48 años y he tenido la suerte de estudiar bajo unos planes educativos buenos, que primaban el esfuerzo y la formación de los alumnos por encima de las estadísticas de aprobados y de la propaganda política. En párvulos (así se llamaba entonces lo que hoy es &#8220;educación [...]]]></description>
			<content:encoded><![CDATA[<div style="font-style:italic;">
<p>Yo no soy víctima de la <acronym title="Ley Orgánica de Ordenación General del Sistema Educativo de España"><a href="http://es.wikipedia.org/wiki/LOGSE">LOGSE</a></acronym>. Tengo 48 años y he tenido la suerte de estudiar bajo unos planes educativos buenos, que primaban el esfuerzo y la formación de los alumnos por encima de las estadísticas de aprobados y de la propaganda política.</p>
<p>En párvulos (así se llamaba entonces lo que hoy es &#8220;educación infantil&#8221;) empecé a estudiar con una cartilla que todavía recuerdo perfectamente: la A de &#8220;araña&#8221;, la E de &#8220;elefante&#8221;, la I de &#8220;iglesia&#8221; la O de &#8220;ojo&#8221; y la U de &#8220;uña&#8221;.</p>
<p>Luego, cuando eras un poco más mayor, llegaba &#8220;El Parvulito&#8221;, un librito con poco más de 100 páginas y un montón de lecturas, no como ahora, que pagas por tres tomos llenos de dibujos que apenas traen texto. Eso sí, en “El Parvulito”, no había que colorear ninguna página, que para eso teníamos cuadernos.</p>
<p>En 8º de EGB, si en un examen tenías una falta de ortografía del tipo de &#8220;b en vez de v&#8221; o cinco faltas de acentos, te suspendían.</p>
<p>En BUP, aunque yo era de Ciencias, estudié Historia de España (en 1º), Latín y Literatura (en 2º) y Filosofía (en 3º y en COU). </p>
<p>Leí El Quijote y el Lazarillo de Tormes; leí las &#8220;Coplas a la Muerte de su Padre&#8221; de Jorge Manrique, a Garcilaso, a Góngora, a Lope de Vega o a Espronceda&#8230;</p>
<p>Pero, sobre todo, aprendí a hablar y a escribir con corrección. Aprendí a amar nuestra lengua, nuestra historia y nuestra cultura.</p>
<p>Aprendí que se dice &#8220;Presidente&#8221; y no Presidenta, aunque sea una mujer la que desempeñe el cargo.</p>
<p>Y&#8230; vamos con la Gramática.</p>
<p>En castellano existen los participios activos como derivado de los tiempos verbales.</p>
<p>El participio activo del verbo atacar es &#8220;atacante&#8221;; el de salir es &#8220;saliente&#8221;; el de cantar es &#8220;cantante&#8221; y el de existir, &#8220;existente&#8221;. ¿Cuál es el del verbo ser? Es &#8220;el ente&#8221;, que significa &#8220;el que tiene entidad&#8221;, en definitiva &#8220;el que es&#8221;. Por ello, cuando queremos nombrar a la persona que denota capacidad de ejercer la acción que expresa el verbo, se añade a este la terminación &#8220;-nte&#8221;.</p>
<p>Así, al que preside, se le llama &#8220;presidente&#8221; y nunca &#8220;presidenta&#8221;, independientemente del género (masculino o femenino) del que realiza la acción.</p>
<p>De manera análoga, se dice &#8220;capilla ardiente&#8221;, no &#8220;ardienta&#8221;; se dice &#8220;estudiante&#8221;, no &#8220;estudianta&#8221;; se dice &#8220;independiente&#8221; y no &#8220;independienta&#8221;; &#8220;paciente&#8221;, no &#8220;pacienta&#8221;; &#8220;dirigente&#8221;, no dirigenta&#8221;; &#8220;residente&#8221;, o &#8220;residenta&#8221;.</p>
<p>Y ahora, la pregunta del millón: nuestros políticos y muchos periodistas (hombres y mujeres, que los hombres que ejercen el periodismo no son &#8220;periodistos&#8221;) ¿hacen mal uso de la lengua por motivos ideológicos o por ignorancia de la Gramática de la Lengua Española? Creo que por las dos razones.</p>
<p>Es más, creo que la ignorancia les lleva a aplicar patrones ideológicos y la misma aplicación automática de esos patrones ideológicos los hace más ignorantes (a ellos y a sus seguidores).</p>
<p>Os propongo que paséis el mensaje a vuestros amigos y conocidos, en la esperanza de que llegue finalmente a esos ignorantes semovientes (no &#8220;ignorantas semovientas&#8221;, aunque ocupen carteras ministeriales).</p>
<p>Lamento haber aguado la fiesta a un grupo de hombres que se habían asociado en defensa del género y que habían firmado un manifiesto.</p>
<p>Algunos de los firmantes eran: el dentisto, el poeto, el sindicalisto, el pediatro, el pianisto, el golfisto, el arreglisto, el funambulisto, el proyectisto, el turisto, el contratisto, el paisajisto, el taxisto, el artisto, el periodisto, el violinisto, el taxidermisto, el telefonisto, el masajisto, el gasisto, el trompetisto, el violinisto, el maquinisto, el electricisto, el oculisto, el policío del esquino y, sobre todo, ¡el machisto!</p>
</div>
<p style="color:gray;">
Carta de una profesora de música de un instituto que me ha llegado por correo. Seguro que está en mil sitios, pero esto siempre es bueno recordarlo.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2010/lenguajes/contra-la-tontuna-linguistica-un-poco-de-gramatica-bien-explicada.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Llamadas a métodos protegidos desde clases externas en C++</title>
		<link>http://beosman.org/archivo/2010/informatica/llamadas-a-metodos-protegidos-desde-clases-externas-en-cpp.html</link>
		<comments>http://beosman.org/archivo/2010/informatica/llamadas-a-metodos-protegidos-desde-clases-externas-en-cpp.html#comments</comments>
		<pubDate>Thu, 23 Sep 2010 19:56:31 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=2801</guid>
		<description><![CDATA[Seguro que esta solución ya está implementada por ahí pero yo no la he encontrado. Para ponernos en antecedentes, tenemos una clase Thread en C++ que representa hilos de ejecución. Esta clase tiene un método execute() que es el que realmente ejecuta el hilo. De esta se puede heredar para implementar dicho método y que [...]]]></description>
			<content:encoded><![CDATA[<p>Seguro que esta solución ya está implementada por ahí pero yo no la he encontrado.</p>
<p>Para ponernos en antecedentes, tenemos una clase <code>Thread</code> en <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a> que representa <a href="http://es.wikipedia.org/wiki/Hilo_de_ejecuci%C3%B3n">hilos de ejecución</a>. Esta clase tiene un método <code>execute()</code> que es el que realmente ejecuta el hilo. De esta se puede heredar para implementar dicho método y que este se ejecute en un hilo independiente. La clase <code>Thread</code> cuenta con <a href="http://es.wikipedia.org/wiki/Herencia_%28inform%C3%A1tica%29#Herencia_y_ocultaci.C3.B3n_de_informaci.C3.B3n">métodos protegidos (<em>protected</em>)</a> para que sólo los usen las clases derivadas.</p>
<p>Pero, además de derivar la clase <code>Thread</code>, esta clase tiene una clase anidada llamada <code>Thread::Worker</code> que también se puede derivar con la ventaja de que se pueden pasar muchas instancias de <code>Thread::Worker</code> a una sola instancia de la clase <code>Thread</code> para que las ejecute.</p>
<p>El problema surge cuando desde la clase <code>Thread::Worker</code>, al igual que desde las subclases de <code>Thread</code>, se desea acceder a los métodos protegidos (que, en teoría, son sólo para ayudar en la funcionalidad de las clases derivadas). Inicialmente esto no es posible ya que no se puede acceder a métodos protegidos de una clase si no es desde la propia clase o desde clases derivadas, no importa si son clases anidadas, a efectos de protección, son como clases externas.</p>
<p>Con algunas omisiones de código, la implementación de las clases es la siguiente:</p>
<div class="source">
<p><span class="comment">/* Clase Thread (gestión de hilos) */</span></p>
<p><span class="keyword">class</span> Thread {<br />
  [...]<br />
  <span class="keyword">public</span>:</p>
<p>    <span class="comment">/* Clase Worker (tareas que se ejecutan en los hilos) */</span></p>
<p>    <span class="keyword">class</span> Worker {<br />
      <span class="keyword">protected</span>:<br />
        Thread * <span class="keyword">const</span> getOwnerThread() <span class="keyword">const</span>;<br />
      <span class="keyword">public</span>:<br />
        <span class="keyword">virtual</span> <span class="keyword">void</span> execute();<br />
      <span class="comment">[...]</span><br />
    };</p>
<p>  <span class="keyword">private</span>:<br />
    Worker* _worker;<br />
    <span class="comment">[...]</span><br />
  <span class="keyword">protected</span>:<br />
    <span class="keyword">bool</span> isThreadRunning();<br />
    <span class="keyword">virtual</span> <span class="keyword">void</span> execute();<br />
    <span class="comment">[...]</span><br />
  <span class="keyword">public</span>:<br />
    Thread(Worker* worker) : _worker(worker) {<br />
      <span class="comment">// Al añadir el Worker que asigna el hilo al que pertenece</span><br />
      _worker-&gt;_owner = <span class="keyword">this</span>;<br />
    }<br />
    <span class="comment">[...]</span><br />
  [...]<br />
};</p>
<p><span class="comment">/* Clase MyThread derivada de Thread */</span></p>
<p><span class="keyword">class</span> MyThread : <span class="keyword">public</span> Thread {<br />
  <span class="keyword">protected</span>:<br />
    <span class="keyword">virtual</span> <span class="keyword">void</span> execute() {<br />
      <span class="keyword">while</span>(isThreadRunning()) {  <span class="comment">// llamada correcta porque esta función es protegida en la clase padre</span><br />
        <span class="comment">// hacer las cosas del hilo</span><br />
      }<br />
    }<br />
};</p>
<p><span class="comment">/* Clase MyWorker derivada de Thread::Worker */</span></p>
<p><span class="keyword">class</span> MyWorker : <span class="keyword">public</span> Thread::Worker {<br />
  <span class="keyword">protected</span>:<br />
    <span class="keyword">virtual</span> <span class="keyword">void</span> execute() {<br />
      <span class="keyword">while</span>(getOwnerThread()-&gt;isThreadRunning()) {  <span class="comment">// llamada incorrecta porque esta función es protegida en la clase Thread, que no es la clase padre</span><br />
        <span class="comment">// hacer las cosas del hilo</span><br />
      }<br />
    }<br />
}</p>
<p><span class="comment">/* Función de entrada de la aplicación */</span></p>
<p><span class="keyword">int</span><br />
main() {<br />
  MyThread* mt = <span class="keyword">new</span> MyThread();  <span class="comment">// correcto</span><br />
  Thread* t = <span class="keyword">new</span> Thread(<span class="keyword">new</span> MyWorker());  <span class="comment">// incorrecto, no se pueden llamar a funciones protegidas desde fuera de la clase</span><br />
  <span class="keyword">return</span> 0;<br />
}</p>
</div>
<p>La funcionalidad deseada es que la clase <code>Thread::Worker</code> se comporte como la clase <code>Thread</code> cuando se hacen clases derivadas de ella, para poder usar la funcionalidad de gestión de la clase <code>Thread</code> desde la clase <code>Thread::Worker</code> (las funciones protegidas).</p>
<p>Pero al compilador no le gusta que se llamen funciones protegidas desde clases externas aunque sean anidadas.</p>
<p>La solución pasa por crear un puntero a método en la clase anidada que sea asignado a la función que hay que ejecutar. Cuando la instancia de la clase <code>Thread::Worker</code> es añadida a la instancia de la clase <code>Thread</code>, esta última asigna las direcciones de memoria de sus métodos a las variables internas de la clase <code>Thread::Worker</code>, con lo que una llamada mediante dichos punteros funcionará sin problemas y ejecutará el método protegido de la clase <code>Thread</code> desde la clase externa <code>Thread::Worker</code>.</p>
<p>La implementación sería, más o menos de la siguiente forma:</p>
<div class="source">
<p><span class="keyword">class</span> Thread {<br />
  <span class="comment">[...]</span><br />
  <span class="keyword">public</span>:<br />
    <span class="keyword">typedef</span> <span class="keyword">bool</span> (Thread::*ThreadMethod1)();</p>
<p>    <span class="keyword">class</span> Worker {<br />
      <span class="comment">[...]</span><br />
      <span class="keyword">private</span>:<br />
        ThreadMethod1 _isThreadRunning;<br />
      <span class="keyword">protected</span>:<br />
        <span class="keyword">bool</span> isThreadRunning() {<br />
          <span class="keyword">return</span> (getOwnerThread()-&gt;*_isThreadRunning)();<br />
        }<br />
      <span class="comment">[...]</span><br />
    };</p>
<p>    Thread(Worker* worker) : _worker(worker) {<br />
      _worker-&gt;_owner = <span class="keyword">this</span>;<br />
      _worker-&gt;_isThreadRunning = &amp;Thread::isThreadRunning;<br />
    }</p>
<p>   <span class="comment">[...]</span><br />
}</p>
</div>
<p>Con esto se consigue que la clase <code>Thread::Worker</code> se comporte, a efectos de derivación de clases, como si se derivase de la clase <code>Thread</code>. Hay que tener en cuenta que las clases derivadas de la clase <code>Thread::Worker</code> siempre se tienen que añadir a una instancia de la clase <code>Thread</code> para todo funcione correctamente.</p>
<p>Como es bastante difícil interpretar código fuente desde esta lectura, he preparado <a title=".tar.gz (32 KB)" href="/download/protected.tar.gz">una pequeña aplicación en C++</a> para mostrar el funcionamiento de este tipo de solución.</p>
<p>Espero que esto sirva para alguien a parte de mi. Y si lo encontráis por algún otro sitio me lo comentáis, porque como he dicho al principio, seguro que no soy el primero en hacerlo.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2010/informatica/llamadas-a-metodos-protegidos-desde-clases-externas-en-cpp.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>17 pequeñas notas sobre programación en C++</title>
		<link>http://beosman.org/archivo/2010/informatica/17-pequenas-notas-sobre-programacion-en-c.html</link>
		<comments>http://beosman.org/archivo/2010/informatica/17-pequenas-notas-sobre-programacion-en-c.html#comments</comments>
		<pubDate>Mon, 10 May 2010 14:59:18 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/?p=1897</guid>
		<description><![CDATA[C++ no es C. Usa el que más te convenga en cada momento. Si programas en C++, usa su librería estándar, STL, siempre que puedas. No reinventes la rueda, si necesitas mayor funcionalidad, usa librerías que la proporcionen y que estén en un estado de madurez suficiente, como la librería boost. No se recomienda que [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="http://es.wikipedia.org/wiki/C++">C++</a> no es <a href="http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n_C">C</a>. Usa el que más te convenga en cada momento.</li>
<li>Si programas en C++, usa su librería estándar, <acronym title="Standard Template Library" lang="en"><a href="http://es.wikipedia.org/wiki/C%2B%2B#Biblioteca_Est.C3.A1ndar_de_Plantillas_.28STL.2C_Standard_Template_Library.29">STL</a></acronym>, siempre que puedas.</li>
<li>No reinventes la rueda, si necesitas mayor funcionalidad, usa librerías que la proporcionen y que estén en un estado de madurez suficiente, como la librería <a href="http://es.wikipedia.org/wiki/Biblioteca_Boost"><code>boost</code></a>.</li>
<li>No se recomienda que los <em>castings</em> se hagan de forma implícita o de la forma que lo hace C. Se recomienda usar su nueva sintaxis: <code>static_cast</code>, <code>dynamic_cast</code>, <code>const_cast</code> y <code>reinterpret_cast</code>.</li>
<li>Un <em>casting</em> con <code>static_cast</code> se evalúa en tiempo de compilación y es el más parecido al <em>casting</em> implícito de C. Se usa para convertir un tipo de dato en otro.</li>
<li>Un <em>casting</em> con <code>dynamic_cast</code> se usa para hacer <em>castings</em> en tiempo de ejecución pero <strong>sólo</strong> para objetos polimórficos, esto es, para recorrer la jerarquía de clases. No funcionará con tipos básicos.</li>
<li>Un <em>casting</em> con <code>const_cast</code> no cambia de tipo sino que cambia los modificadores <code>const</code> y <code>volatile</code>.</li>
<li>Un <em>casting</em> con <code>reinterpret_cast</code> se usa para hacer cambios de tipo a nivel de bits, es decir, para convertir entre tipos totalmente distintos.</li>
<li>Una función dentro de una clase que tenga el modificador <code>const</code> (por ejemplo <code>void MiClase::MiFuncion() const { ... }</code>) no modifica el contenido del objeto (no modifica los campos del objeto). Esto se usa para ejecutar funciones dentro de instancias constantes.</li>
<li>Una función virtual pura debe ser declarada como <code>virtual</code> e igualada a cero dentro de la clase: <code>virtual void MiFuncionVirtualPura() = 0;</code>. Este tipo de funciones <strong>deben</strong> ser implementadas en las clases derivadas. Además, no se pueden instanciar clases que tengan funciones virtuales puras.
</li>
<li>Las variables miembro (propiedades) estáticas de una clase deben ser <strong>definidas</strong> fuera de la clase para que funcionen correctamente (si no se definen así, el error lo produce el <a href="http://es.wikipedia.org/wiki/Linker">linker</a>: <code>Undefined reference to MiClase::count</code>):
<pre>
class MiClase {
	public:
		static int count;
}

int MiClase::count = 0;
</pre>
</li>
<li>Las clases y funciones con plantillas se deben declarar e implementar en el mismo archivo ya que, como el código se genera en tiempo de compilación, si se declara en un <code>.h</code> y se implementa en un <code>.cpp</code>, es el <em>linker</em> el que no encuentra el código generado. <a href="http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12">Hay más soluciones</a>, pero ninguna es buena del todo.</li>
<li>Usa el sistema de gestión de excepciones de C++ y evita en lo posible el uso de valores de retorno indicando errores y sentencias <code>if</code> ya que son mucho más propensas a errores.</li>
<li>Las excepciones deben representar el error que se produce, no quién las lanza o desde donde se lanzan.</li>
<li>Siempre que puedas, usa objetos creados en el <code><a href="http://es.wikipedia.org/wiki/Pila_%28inform%C3%A1tica%29">stack</a></code> en lugar de en el <code><a href="http://es.wikipedia.org/wiki/Heap">heap</a></code>. Con esto evitarás <em><a href="http://es.wikipedia.org/wiki/Memory_leak">fugas de memoria</a></em> (<em>memory leak</em> en inglés) ya que los objetos se destruyen cuando finaliza el ámbito de los mismos.</li>
<li>Usa herramientas automatizadas para probar y depurar las aplicaciones (como <code><a href="http://es.wikipedia.org/wiki/Valgrind">valgrind</a></code> para fugas de memoria).</li>
<li>Nunca confies en que lo has revisado todo.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2010/informatica/17-pequenas-notas-sobre-programacion-en-c.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Palabras con &#8220;ch&#8221;</title>
		<link>http://beosman.org/archivo/2009/lenguajes/palabras-con-ch.html</link>
		<comments>http://beosman.org/archivo/2009/lenguajes/palabras-con-ch.html#comments</comments>
		<pubDate>Thu, 10 Dec 2009 22:37:12 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.org/archivo/2009/lenguajes/palabras-con-ch.html</guid>
		<description><![CDATA[Esta es la entrada tonta del día que, gracias a que se ha presentado la Nueva Gramática de la Lengua Española, se me ocurrió poner todas las palabras bisílabas que sólo utilizasen la extinta letra che, hoy la ce hache: chacha, chachi, chacho, cheche, Chechu, chicha, chiche, chichi, chicho, chocha, chocho, chuche, chucha y chucho. [...]]]></description>
			<content:encoded><![CDATA[<p>Esta es la entrada tonta del día que, gracias a que <a href="http://www.e-consulta.com/index.php?option=com_content&#038;task=view&#038;id=42274&#038;Itemid=282">se ha presentado la Nueva Gramática de la Lengua Española</a>, se me ocurrió poner todas las palabras bisílabas que sólo utilizasen la extinta letra <q><em>che</em></q>, hoy la <em>ce hache</em>:</p>
<blockquote style="font-size: 1.2em;"><p>
<a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chacha&#038;TIPO_HTML=2">chacha</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chachi&#038;TIPO_HTML=2">chachi</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chacho&#038;TIPO_HTML=2">chacho</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=cheche&#038;TIPO_HTML=2">cheche</a>, <span style="border-bottom:1px dotted;" title="Diminutivo de nombre propio; acuérdense de Médico de Familia">Chechu</span>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chicha&#038;TIPO_HTML=2">chicha</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chiche&#038;TIPO_HTML=2">chiche</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chichi&#038;TIPO_HTML=2">chichi</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chicho&#038;TIPO_HTML=2">chicho</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chocha&#038;TIPO_HTML=2">chocha</a>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chocho&#038;TIPO_HTML=2">chocho</a>, <span style="border-bottom:1px dotted;" title="Diminutivo de Chuchería">chuche</span>, <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chucha&#038;TIPO_HTML=2">chucha</a> y <a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=chucho&#038;TIPO_HTML=2">chucho</a>.
</p></blockquote>
<p>Al final han salido 14, aunque algunas no están en el <a href="http://buscon.rae.es">diccionario de la RAE</a>, pero seguro que a nadie se le escapa el significado. Además, tampoco he contado las que tienen más vocales o consonantes entre estas. Ahora sólo se me ocurre <q>Chencho</q> (el hijo pequeño de <a href="http://es.wikipedia.org/wiki/La_gran_familia">La gran familia</a>). ¿Alguna más?</p>
<p>Y hasta aquí ha llegado la entrada chorra del día <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/lenguajes/palabras-con-ch.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Programando con estilo</title>
		<link>http://beosman.org/archivo/2009/informatica/programando-con-estilo.html</link>
		<comments>http://beosman.org/archivo/2009/informatica/programando-con-estilo.html#comments</comments>
		<pubDate>Mon, 13 Apr 2009 18:24:37 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.dyndns.org/archivo/2009/informatica/programando-con-estilo.html</guid>
		<description><![CDATA[Google ha liberado el código fuente de su actualizador, Google Update, es decir, la aplicación que actualiza todas las aplicaciones que tengas instaladas de Google; y lo ha hecho bajo el nombre de Omaha y con licencia Apache 2.0. Pero la cuestión que quiero comentar es que hayan dado un buen paso hacia delante (que [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://google-opensource.blogspot.com/2009/04/google-update-goes-open-source.html">Google ha liberado el código fuente de su actualizador, Google Update</a>, es decir, la aplicación que actualiza todas las aplicaciones que tengas instaladas de Google; y lo ha hecho bajo el nombre de <a href="http://code.google.com/p/omaha/">Omaha</a> y con <a href="http://www.apache.org/licenses/LICENSE-2.0">licencia Apache 2.0</a>.</p>
<p>Pero la cuestión que quiero comentar es que hayan dado un buen paso hacia delante (que lo han hecho, por cierto), sino la calidad del código en sí (suelo echar un vistazo al código fuente de los proyectos libres, simplemente por ver como están hechos).</p>
<p>Independientemente de si está bien programado o no, de si han diseñado bien la arquitectura o no, la calidad del código es impresionante: está limpio, ordenado, bien indentado, con espacios entre operadores, con las llaves correctamente colocadas,&#8230; vamos, <a href="http://beosman.dyndns.org/documentos/estilo-de-programacion/">como a mi me gusta</a>.</p>
<p class="imageparagraph">
<img class="image" src="/uploads/2009/04/google-update-source.png" alt="Muestra de código fuente de la aplicación 'Google Update'" title="Muestra de código fuente de la aplicación 'Google Update'" />
</p>
<p>Habiendo visto más código fuente, sobre todo de proyectos <a href="http://es.wikipedia.org/wiki/Gnu">GNU</a>, este es uno en los que mejor está escrito el código. De hecho, se parece <strong>mucho</strong> al código de las aplicaciones que se escribían para el <a href="http://es.wikipedia.org/wiki/BeOS">BeOS</a> (que también eran en <a href="http://es.wikipedia.org/wiki/C%2B%2B">C++</a>). Lo único que hecho en falta es que el tipo de dato que retorna una función no esté en una línea distinta (la anterior) a la del nombre y parámetros de la función, algo que se estilaba mucho en BeOS.</p>
<p>Sin duda es una buena noticia el hecho de que se liberase el código, pero también es buena noticia que haya tanta calidad en el mismo, ya que con el peso que tiene Google ahora mismo como ejemplo de hacer las cosas (no se si para bien o para mal, pero tiene peso) queda claro que habrá muchos seguidores que hagamos código similar con lo que nuestros proyectos ganarán en legibilidad y mantenibilidad.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/informatica/programando-con-estilo.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Guía de estilo de programación</title>
		<link>http://beosman.org/archivo/2009/informatica/guia-de-estilo-de-programacion.html</link>
		<comments>http://beosman.org/archivo/2009/informatica/guia-de-estilo-de-programacion.html#comments</comments>
		<pubDate>Mon, 13 Apr 2009 15:28:14 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.dyndns.org/archivo/2009/informatica/guia-de-estilo-de-programacion.html</guid>
		<description><![CDATA[Después de mucho tiempo sin hacerla y después de también mucho tiempo rondando por mi disco duro, he puesto en el blog mi Guía de Estilo de programación. Este documento muestra el estilo de programación que yo sigo a la hora de realizar mis proyectos, tanto personales como laborales. Esta guía es sólo una recomendación [...]]]></description>
			<content:encoded><![CDATA[<p>Después de mucho tiempo sin hacerla y después de también mucho tiempo rondando por mi disco duro, he puesto en el blog mi <a href="/documentos/estilo-de-programacion/"><strong>Guía de Estilo de programación</strong></a>.</p>
<p>Este documento muestra el <a href="http://es.wikipedia.org/wiki/Estilo_de_programaci%C3%B3n">estilo de programación</a> que yo sigo a la hora de realizar mis proyectos, tanto personales como laborales.</p>
<p>Esta guía es sólo una <strong>recomendación</strong> a seguir, nadie está obligado a hacerlo, pero siguiendo estas recomendaciones (u otras recomendaciones pero siendo siempre coherente) se consigue que el código fuente de nuestros proyectos sean más legibles y, sobre todo, más mantenibles.</p>
<p>Si te gusta que tu código esté bien escrito, <a href="http://beosman.dyndns.org/documentos/estilo-de-programacion/">échale un vistazo</a> y comenta tu punto de vista; aunque si has llegado hasta aquí seguro que también tienes la tuya propia y tu código ya sale <em>&#8220;bien visto&#8221;</em> <img src='http://beosman.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/informatica/guia-de-estilo-de-programacion.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>&#8220;Hola mundo!&#8221; en diferentes lenguajes de programación</title>
		<link>http://beosman.org/archivo/2009/informatica/hola-mundo-en-diferentes-lenguajes-de-programacion.html</link>
		<comments>http://beosman.org/archivo/2009/informatica/hola-mundo-en-diferentes-lenguajes-de-programacion.html#comments</comments>
		<pubDate>Fri, 03 Apr 2009 16:30:47 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.dyndns.org/archivo/2009/informatica/hola-mundo-en-diferentes-lenguajes-de-programacion.html</guid>
		<description><![CDATA[&#8220;Hola mundo!&#8221; en Piet (Wikipedia) Página descubierta desde Kabytes donde se implementa el famoso &#8220;Hola mundo!&#8221; en 421 lenguajes de programación diferentes. Los más divertidos son los llamados lenguajes de programación esotéricos como el Piet, el Brainfuck, el Ook! o el Whitespace. Pero el resto también tienen su gracia, sobre todo los ensambladores de varias [...]]]></description>
			<content:encoded><![CDATA[<div class="floatright" style="padding: 0 0 7px 8px;margin:10px 0 0 0;color:gray;font-size:.9em;text-align:center;width:150px;">
<img class="image" src="/uploads/2009/04/hello-world-in-piet-programming-language.gif" alt="'Hello world!' en el lenguaje de programación Piet (Wikipedia)" title="'Hello world!' en el lenguaje de programación Piet (Wikipedia)" /><br />
<em>&#8220;Hola mundo!&#8221;</em> en Piet (Wikipedia)
</div>
<p>Página descubierta <a href="http://www.kabytes.com/curiosidades/hello-world-en-366-lenguajes-de-programacion/">desde Kabytes</a> donde <a href="http://www.roesler-ac.de/wolfram/hello.htm">se implementa el famoso &#8220;Hola mundo!&#8221; en 421 lenguajes de programación diferentes</a>.</p>
<p>Los más divertidos son los llamados <a href="http://es.wikipedia.org/wiki/Lenguajes_esot%C3%A9ricos">lenguajes de programación esotéricos</a> como el <a href="http://en.wikipedia.org/wiki/Piet">Piet</a>, el <a href="http://es.wikipedia.org/wiki/Brainfuck">Brainfuck</a>, el <a href="http://es.wikipedia.org/wiki/Ook!">Ook!</a> o el <a href="http://es.wikipedia.org/wiki/Whitespace">Whitespace</a>. Pero el resto también tienen su gracia, sobre todo los ensambladores de varias máquinas.</p>
<p>Además de esto, también tenemos el programa <em><a href="http://99-bottles-of-beer.net/">&#8220;99 botellas de cerveza&#8221;</a></em> (<em>&#8220;99 bottles of beer&#8221;</em> en inglés, que es algo así como <em>&#8220;Un elefante se balanceaba&#8230;&#8221;</em> pero restando. Aquí sabemos que terminaremos algún día) implementado en <strong>1259</strong> lenguajes de programación diferentes (no sabía que había tantos).</p>
<p>Me ha llamado la atención la <a href="http://99-bottles-of-beer.net/language-delphi-867.html">implementación en Delphi</a>. Tan sencillo y amigable él, y aquí lo flipé.</p>
<p>Y para terminar de rayar la cabeza, recordemos el ininteligible <a href="http://beosman.dyndns.org/archivo/2008/informatica/c-ofuscado.html"><em>&#8220;Hola mundo!&#8221;</em> en C ofuscado</a>.</p>
<p style="color:gray;">
<abbr title="Post Data">P.D.</abbr>: Yo que quería hacer mi propio lenguaje de programación al que llamaría D++ (porque <a href="http://www.digitalmars.com/d">D</a> ya está cogido) y resulta que <a href="http://www.pagemac.com/">D++</a> también está cogido. ¡Leches!</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/informatica/hola-mundo-en-diferentes-lenguajes-de-programacion.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lenguajes de programación</title>
		<link>http://beosman.org/archivo/2009/citas/lenguajes-de-programacion.html</link>
		<comments>http://beosman.org/archivo/2009/citas/lenguajes-de-programacion.html#comments</comments>
		<pubDate>Fri, 03 Apr 2009 16:03:59 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Citas y frases]]></category>
		<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.dyndns.org/archivo/2009/citas/lenguajes-de-programacion.html</guid>
		<description><![CDATA[Existen dos tipos de lenguajes de programación: por un lado, aquellos de los que la gente se queja todo el rato; por otro, los que nadie utiliza. Bjarne Stroustrup, científico de la computación y desarrollador del lenguaje de programación C++.]]></description>
			<content:encoded><![CDATA[<blockquote><p>
Existen dos tipos de lenguajes de programación: por un lado, aquellos de los que la gente se queja todo el rato; por otro, los que nadie utiliza.
</p></blockquote>
<p class="blockquoteparagraph">
<a href="http://es.wikipedia.org/wiki/Bjarne_Stroustrup">Bjarne Stroustrup</a>, científico de la computación y desarrollador del lenguaje de programación <a href="http://es.wikipedia.org/wiki/C_m%C3%A1s_m%C3%A1s">C++</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/citas/lenguajes-de-programacion.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tod@s</title>
		<link>http://beosman.org/archivo/2009/lenguajes/todos.html</link>
		<comments>http://beosman.org/archivo/2009/lenguajes/todos.html#comments</comments>
		<pubDate>Wed, 18 Mar 2009 13:32:19 +0000</pubDate>
		<dc:creator>Diego</dc:creator>
				<category><![CDATA[Lenguajes]]></category>

		<guid isPermaLink="false">http://beosman.dyndns.org/archivo/2009/lenguajes/todos.html</guid>
		<description><![CDATA[La actual tendencia al desdoblamiento indiscriminado del sustantivo en su forma masculina y femenina va contra del principio de economía del lenguaje y se funda en razones extralingüísticas. Por tanto, deben evitarse estas repeticiones, que generan dificultades sintácticas y de concordancia, y complican innecesariamente la redacción y lectura de los textos. Lo dice la RAE [...]]]></description>
			<content:encoded><![CDATA[<blockquote style="font-size:1.2em;"><p>
La actual tendencia al desdoblamiento indiscriminado del sustantivo en su forma masculina y femenina va contra del <strong>principio de economía del lenguaje</strong> y se funda en razones extralingüísticas. Por tanto, <strong>deben evitarse estas repeticiones</strong>, que generan dificultades sintácticas y de concordancia, y complican innecesariamente la redacción y lectura de los textos.
</p></blockquote>
<p class="blockquoteparagraph">
<a href="http://www.rae.es/rae/gestores/gespub000018.nsf/(voAnexos)/arch8100821B76809110C12571B80038BA4A/$File/CuestionesparaelFAQdeconsultas.htm#ap19">Lo dice la <acronym title="Real Academia Española">RAE</acronym></a> (negritas mías) y yo <a href="http://desequilibros.blogspot.com/2009/03/todos-y-todas-los-duenos-y-duenas-de.html">lo vi primero en DesEquiLIBROS</a>.
</p>
<p class="blockquoteparagraph">
Y como odio que se use la arroba (@) para <em>simbolizar</em> el género neutro. Llamadme Talibán del lenguaje (que no lo soy, que también cometo mis faltas) pero hay que cosas con las que no puedo.</p>
]]></content:encoded>
			<wfw:commentRss>http://beosman.org/archivo/2009/lenguajes/todos.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

