miércoles, abril 23, 2008

Premios Nebula 2007 – Preview (Novela corta y noveleta)

Esta es la semana de los premios Nebula, con Felipe nos habíamos prometido tratar de leer las cosas que estaban en linea, como estuvimos muy lentos al principio, pues pensé que no íbamos a alcanzar, pero en estas tres semanas, me llego el groove lector, y me dí a la tarea de leer los que más pudiera, estas son mis impresiones, espero en este par de días que quedan alcanzar a ver los cuentos.


Justo ahora, tengo que hacer otras cosas de mis proyectos aquí--que son igualmente divertidas ;)--así que esta semana no pude leer los cuentos xP... igual, los leeré con calma y comparare mi apreciación con los resultados definitivos ;).

martes, abril 15, 2008

Also known as...

Definitivamente esto es muy diferente al clima tropical al que estaba acostumbrado xD, el viernes estábamos sobre los 25 grados, cuando cayo un frente frío, muy frío, y desde entonces la máxima a sido de 10 grados. El cambio ha sido fuerte, y me tomo totalmente por sorpresa, espero ahora, con algunas lukas, pueda comprar al menos un par de cobijas xD. Algo que me a impresionado es colo el frío lo impregna todo, es totalmente distinto al frío bogotano!

Pablo y Loló me recomendaron comprar una estufa, vamos a ver como pega el invierno cuando llegue (faltan más de dos meses).

Ayer me entere de varias cosas graciosas, como que llevar muchas cosas, es estar como un ekeko (si! como ese famoso enano milagroso!), que una salamanca es un diablo o una reunión de diablos... pero lo mejor, fue al final de la jornada, cuando me entere del apodo que me tienen por los pasillos del Lillo: tachuelas xD, tan pronto como lo escuche me pareció muy chistoso, ya me imaginaba yo que pronto tendría un apodo de ese tipo por estos lados.

Lo triste fue darme cuenta que el calefón, el nombre local de los calentadores de agua, esta averiado (o no se como hacerlo funcionar) :S... otra de las “pequeñas averías” que venían incluidas con la casa :P.

lunes, abril 14, 2008

C--

No se si en realidad estoy buscando una excusa para descargar mi frustración de esta semana, o si es más bien porque Pablo me sugirió que para facilitar nuestra comunicación (en el ámbito de la programación) mejor usara C, o porque quiero usar SWIG, que no soporta templates, o porque quería usar wxWidgets y no importaba que hiciera siempre me reportaba el “falta el archivo cc1”...

Como sea que fuere, estoy cada vez más molesto con algunas cosas de C++. Es cierto, el lengujae tiene muchas cosas que son brutales. Para mi la principal es el encapsulamiento explicito de los datos, pero de las otras cosas...

Por un lado estan los operadores sobrecargados, yo al principio me emocione mucho, pero ya después uno comienza a descubrir que quizá sea más optimo usar las tradicionales funciones. Por ejemplo, yo tengo un campo de bits:

class BitField {
public:
BitField(int b=0);
BitField(const BitField&);
private:
unsigned bits;
};

Para los que no estén familiarizados con C++, las funciones públicas son dos constructores, uno que modifica el constructor por omisión y el otro un constructor copia. En la parte privada están los bits del campo de bits.

Entre otras cosas yo quiero que el objeto b, sea el inverso del objeto a. Para ello puedo hacer un operador:

friend BitField& operator~(const BitField&);

Aquí esta parte del asunto, el operador es amigo porque la idea es formar un nuevo objeto que tenga todos los valores de a inversos, pero manteniendo a a intacto.

BitField& operator~(const BitField& a) {
BitField b=a;
b.bits=~a.bits;
return b;
}

Aquí se debe construir una copia de a, luego, bien sea cada elemento de a, o de b es invertido. Lo adecuado debería haber sido de una vez copiar en b los inversos de a, estamos haciendo una operación redundante. Más aun si después de eso tenemos que asignar el resultado:

BitField& operator=(const BitField&); //Esto se declara en la parte pública de BitField

BitField& BitField::operator=(const BitField& b) {
//Aquí va una limpieza de todo lo que hay en el objeto actual
bits=b.bits; //Y esta es la asignación
}

De nuevo otra copia, es decir, hemos copiado 3 veces cuando solo una vez era suficiente! Quizá con problemas pequeños no pasa nada, pero con las filogenias (árboles) cuya construcción suele ser un problema NP-completo, es urgente evitar redundancia de evaluaciones y así ahorrar tiempo que puede ser usado para probar otras combinaciones.

Usando una filosofía de no-operadores la cosa seria instantánea:

void add_inverse(const BitField&); //Esto se declara en la parte pública de bitField

void add_inverse(const BitField& a) {
//Aquí va una limpieza de todo lo que hay en el objeto actual
bits=~a.bits; //Y esta es la asignación
}

La situación es equivalente usando suma, resta, o las otras operaciones, las únicas realemente optimas son +=,*=, etc. pues estás asignan directamente al objeto que estemos trabajado, eludiéndose las copias redundantes.

Una solución podría ser tener un enum, con las operaciones y ponerlo en la declaración, del constructor copia o del de asignación. Más o menos así:

enum Operations {
NONE, NEGATION, SUM, ...
};

//Constructores copia
BitField(const BitField&, Operations op=NONE); //Para operadores unitarios
BitField(const BitField&, const BitField&, Operations op=SUMA); //Operadores duples
//Funciones de asignación
bool assign(const BitField&, Operations op=NONE);
bool assign(const BitField&, const BitField&, Operations op=NONE);

Despues simplemente en cada función hacemos un switch(op) para determinar que hacemos, genera funciones más grandes, pero si tenemos varias operaciones, podemos siempre llamar a la función, y evitamos tener mil funciones que hacen más o menos lo mismo.

No se si para los constructores se puedan usar punteros a funciones pero para las funciones de asignación esa sería una segunda alternativa.

Si algún guru de C++ (en realidad, cualquier usuario) que tenga una solución a ese problema usando operadores, me gustaría saber su idea :).

Ahora pasemos al problema de las librerías “estándar” de C++. Yo uso dos compiladores, así que bien podría ser 'culpa' de ellos más que del estándar. Uno es gcc (MinGW), que produce unos archivos enormes, como IDE uso Dev-C++, que es fantástico, aunque su versión anterior, la 4.1, creo, el depurador funcionaba mucho mejor que en la actual (la 4.9.9.9....9), es decir, funcionaba, ahora, no importa que haga, el depurador nunca a vuelto a funcionar :( porque falta 'información' de depuración! Un depurador fantástico lo tiene OpenWatcom, y por eso es mi segundo compilador... pero OpenWatcom no usa C++ estándar :S... lo cual me genera algunos problemas para moverme entre plataformas, y teniendo en cuenta que quiero tener programas que compilen en windows y en linux (es decir, con gcc).

Las funciones de la librería “estándar” de OpenWatcom, parece más una forma tipo C de usar C++ (lo que yo quiero hacer ahora), no usa templates, y los archivos finales son más chicos. Pero algunas clases tienen nombres diferentes, y otros servicios, por ejemplo, en gcc, uno usa ostringstream, la función str() devuelve un string (la clase de la librería estándar), mientras que su equivalente en OpenWatcom (ostrstream) regresa un char* que además no termina en '\0'. La solución es muy fea, en un archivo de definciones, por ejemplo “my_def.h”:

#ifdef GCC_COMPILER
#include
typedef std::ostringstream OutString;
typedef std::istringstream InString;
#endif
#ifdef OPENWATCOM
#include
typedef std::ostrstream OutString;
typedef std::istrstream InString;
#endif

Y en el código fuente, agregar el '\0' antes de llamar str():

OutString ost;
#ifdef OPENWATCOM
ost(menorque)(menorque)'\0';
#endif
return ost.str();

Hasta ahí las cosas van bien.. pero por ejemplo, en OpenWatcom, uno no puede usar un objeto string para inicilizar InString! Peor aún, los strings de openwatcom solo devuelven char const*, que se muestran fuertemente reacios a ser movidos a un char*, probé con un strcpy(), pero uno de los motivos para usar string es no tener que depender de las funciones de C donde uno debe tener limites iniciales fijos del string... Después de dar un millón de vueltas, llegue a esta solución, un poco molesta, pero funcional:

#ifdef OPENWATCOM
char* ts;
OutString ost;
ost(menorque)(menorque)s(menorque)(menorque)'\0';
ts=ost.str();
InString in(ts);
#endif


... Y después de todo eso, compilo mi programa, con el mismo conjunto de datos, de repente el compilado con gcc se cae, a veces si, a veces no, el compilado con Watcom, esta perfecto, pero si corro otro conjunto zaz! Muerte súbita... parece que hay un leak en el manejo de memoria, pero el crash no debería pasar, la versión anterior que no usaba delete (esa si que tenía leaks de memoria!) funcionaba bien... es muy raro! Así como mi instalación de wxWidget, después de probar mil y un alternativas (los makefiles que vienen, ninguno funciono :(, ni los de watcom, ni los de MinGW, baje entonces una serie de paquetes para Dev-C++, que tienen las librerías precompiladas, seguí las instrucciones, y ahora gcc llama a un 'cc1', en el faq no dice nada de ese error, creo que tendre que buscar en el foro xD, después instale wxDev, que es la versión de Dev-C++ con wxWidget integrado y zaz, de nuevo, el mismo error (y una interfaz 10 veces más lenta). Como dice Loló, que bajón!

Y Pablo pues, el a vivido siempre con C, y hace cosas brutales con el (cualquiera que haya corrido TNT lo va a notar!), y pues para mi seria mejor poder mostrarle mi código a mi director, y que el lo pueda entender sin problemas. Quizá utilice una programación tipo C++ con C, es decir, yo mismo me pongo el requerimiento de mantener ocultos los datos xD. Creo que eso lo puedo hacer usando clases normales, mantener todas las operaciones lo más C posible (no referencias, no operadores, no librería estándar, no herencia--que igual, casi nunca uso--usar malloc y free para manejar memoria? Bueno creo que const si forma parte del C estándar, y la sobrecarga de funciones, y los parámetros por omisión son ideas que seguro Pablo va a entender de una vez, y quizá las use con C xD. Se me ocurre colocar todo en una clase, poner solo funciones friend, y después cuando todo funcione, cambiar de class a struct y borrar la declaración de los friend (dentro del nuevo struct).

No se, lo pensare en estos días mientras logro solucionar mis leaks de memoria xD...

Pero bueno, sirvió el desahogo :). Por si algún amigo alcanzo a llegar hasta aquí, cosa que dudo xD, pues me pagaron, pero solo la primera semana de febrero, supuestamente ya hoy debería tener lo de marzo, ya veremos :P.

Side-note: que post más largo y más geek xD jajajaja...

Addendum
Ya solucione mi leak de memoria :), aún así, decidí eliminar buena parte de mis operadores...

martes, abril 08, 2008

Predicciones Grandes Ligas 2008

La temporada de las Grandes Ligas comenzó la semana pasada, como aún no tengo i-net en mi casa, me entero de las cosas con una mirada fugaz a la página de las mayores, así que a diferencia de otros años, mi cubrimiento es bastante pobre :(... espero en el trascurso de este mes o el otro, recupere la normalidad de las cosas ;).