Archive for the ‘Frikadas’ Category

Paradoxos

Friday, October 30th, 2009

Antes de empezar mis comentarios sobre la “Paradoja divina” de Antonio Vaquero [Vaquero, 2009] , es menester que establezca las premisas en las que están basados:

  1. Lo que usted crea, estimado lector, sobre la divinidad de su predilección (e.g., Elvis, Maradona, Alá, Buda, Ganesha, el monstruo volador de espagueti, etc.) se sale fuera  del ámbito de estos comentarios. No estoy aquí para probar su existencia ni mucho menos para razonar sobre ellas. Mi objetivo general es mostrar que cuando se usa la razón y una de sus herramientas (e.g., la lógica matemática) muchas de las premisas o enunciados sobre estas entidades (sino es que todas) son falsas, verdaderas y falsas al mismo tiempo o paradójicas.
  2. Fuera de las leyes de las matemáticas el resto de nociones, creencias, etc. debe, por definición, estar sujeto a un proceso continuo de verificación. Para muestra basta un botón: considere usted el modelo Ptolemaico del universo (i.e., duró 1500 años de moda) o las diferentes teorías sobre la evolución de las especies (e.g., la teoría del uso y del desuso de Lamarck).
  3. Hablaré de lo que es cierto o falso aquí y ahora, no de las posibilidades del futuro. En otras palabras, evitaré decir que tal o cual noción o creencia puede llegar a ser cierta en algún momento.
  4. Las falacias del creacionismo, el diseño inteligente y sus derivados son fácilmente echadas por tierra en  154 páginas (i.e., ver el libro de [Carmena, 2005] sobre el tema).
  5. Comento la “Paradoja divina” debido al estilo “ecoso” (i.e., de Umberto Eco) de su creador. En particular Umberto Eco siempre ha dicho que las primeras cien páginas de sus libros son una cuesta que el lector debe subir para llegar a lo mejor de ellos. Si usted no me cree, trate de leer las primeras cien páginas de “El péndulo de Foucault” sin correr a consultar con Google las mil y un cosas que ahí se dicen.
  6. No, no soy ateo. Simplemente no me creo todo lo que me dicen sin echarle un poco de chicha al asunto.

Entremos pues en el tema de la “Paradoja divina”. En particular una de las primeras cosas que el autor de esta paradoja establece es la siguiente: “la Ciencia estudia el lenguaje; es decir, quiere responder a la pregunta ¿qué quiere decir lo que se dice?, o sea las relaciones entre lenguaje y pensamiento”. Esto no es cosa nueva,  matemáticos como Wittgenstein  [Norman, 2005] y Ramsey  [1931] ya se hacen la pregunta que Antonio Vaquero en su paradoja nos hace: ¿tiene sentido lo que se dice? Sin embargo tanto Wittgenstein como Ramsey van más allá y establecen lo que se puede decir y lo que no se pude decir en general y sobre cualquier tema, utilizando para ello la razón y la lógica matemática.

En particular para Wittgenstein sólo hay 2 tipos de enunciados: a) los descriptivos, también llamados hechos y que incluyen a todos los enunciados científicos y b) las expresiones tautológicas. El resto de enunciados, en particular los filosóficos y teológicos no son, para Wittgenstein, ni verdaderos ni falsos, simplemente no tienen sentido. Esto llevó a Wittgenstein a la siguiente conclusión: “Whereof one cannot speak, thereof one must be silent”. Tiempo después (Ramsey, 1931) nos dice lo mismo de la siguiente manera:

When we have proposition capable of the two cases truth and falsity we are forced to make it a conjunction, and to have a theory of conjunctions which cannot be expressed for lack of symbolic power […] This is not a conjunction, it is not a proposition at all […] Therefore what we can’t say we can’t say, and we can’t whistle it either“.

Antonio Vaquero hace una afirmación teológica (tomada del credo) que se viene abajo con el uso de la razón, la lógica matemática y un ejemplar de la paradoja de Russell (ver [Vaquero, 2009]). Sus conclusiones son sólidas y representan una verdad tan grande como una catedral. En particular porque todos sabemos que en lógica si el consecuente es falso y el precedente es verdadero entonces toda la proposición es falsa [Luckhardt y Bechtel, 1994].  Sin embargo ¿por qué se sigue rechazando este tipo de verdades y los teólogos siguen escribiendo libros? La  respuesta la encontramos en una regla clásica de la lógica: “(p&¬p) entonces q”. En otras palabras de lo imposible se puede deducir cualquier cosa o de premisas falsas se deduce cualquier cosa: “ ex impossibile quod libet consequitur”.

A pesar de esto en la cita que he utilizado de Ramsey se ve que esto no tiene sentido alguno y que además no puede expresarse. Por tanto hay que guardar silencio. José Antonio Marina [2005] nos lo deja muy claro cuando nos dice: “He leído miles de páginas escritas para decir que de Dios no se puede decir nada”. Sin embargo quedarse sin trabajo no es  una buena idea. Por tanto para justificar sus incongruencias los teólogos han construido una gigantesca, barroquísima e intransitable catedral conceptual (i.e, una gigantomachia peri tes ousias), que según [Marina, 2005] utiliza jerarquías, mitologías, hipóstasis, mediaciones y emanaciones que originan una literatura absolutamente intragable e incomprensible.

Sin embargo esta manera de explicar a Dios choca directamente con la razón. En este caso con las características de teoría y ley establecidas por Leibniz en su “Discours métaphysique”. En este “Discours” se examina la distinción entre los hechos que admiten alguna ley y los que son irregulares y no atienden a ley alguna. Según Chaitin [2006], la idea de Leibniz es la siguiente:

Una teoría ha de ser más sencilla que los hechos que explica, pues de lo contrario no explica nada. El concepto de ley se torna vacuo si se permite que su complejidad matemática sea arbitrariamente grande: sin esa restricción, siempre se puede construir una ley por muy aleatorios y desestructurados que sean los datos. Recíprocamente, si la única ley que describe ciertos datos es una ley complicadísima, lo que realmente ocurre es que los datos no obedecen a ninguna ley.

Como se puede apreciar las explicaciones teológicas no cumplen con las características establecidas por Leibniz. Esto es comprensible dado que la teología es descendiente directo de la metafísica platónica. Dietrich Schwanitz [2006] nos explica en que consiste esta metafísica:

La clave para comprender la cultura griega, la idea que organiza las relaciones entre experiencia y pensamiento, la categoría central que introduce un sentido mas profundo y de la que dependen todas las demás, la idea evidente por sí misma, es que a la realidad le subyacen unos modelos, unas estructuras o formas esenciales[1]  en torno a las cuales se organiza la realidad; y que estas formas esenciales son absolutamente cognoscibles y racionales. Para los antiguos griegos, lo único real eran las ideas o conceptos, pues lo que permite que llamemos, por ejemplo, vaca a una vaca es su idea o concepto, es decir, su forma esencial.

Si reemplazamos el universo ultramundano de las ideas propuesto por Platón por Dios, entonces tenemos que podemos razonar acerca de Dios de la misma manera que según Platón se podía razonar sobre las ideas, aunque de ellas no se supiese absolutamente nada. Pudiese ser así pero paradojas como la de Antonio Vaquero demuestran que esto es falso. ¿No me cree?  Entonces probemos suerte con las dos siguientes afirmaciones teológicas tomadas de [Marina, 2005]  y [Urmas, 2009] respectivamente:

  • “En el Concilio de Nicea los teólogos reconocieron a Jesús como “omoousios” del Padre, como consustancial a Dios,  de su misma sustancia. Y poco después, en el transcendental Concilio de Calcedonia, intentaron poner en claro esta definición y acabaron diciendo que en Jesús había dos naturalezas  -divina y humana- pero sólo una persona y, que en Dios, que era Uno, había que reconocer una trinidad de personas: Padre, Hijo y Espíritu santo”.
  • There exists at least one class of all perfections so that this class of all perfections and the statement that this class is a member of the class of all those classes which are not members of themselves are both true and the statement that a perfection is also a member of the class of all those classes which are not members of themselves is also true“.

¿Podemos afirmar la verdad o la falsedad de las proposiciones teológicas del primer punto? la verdad es que no. Yo en particular no estoy seguro ni de lo uno ni de lo otro. Por tanto, dado que no podemos establecer sus valores de verdad, entonces tal como Wittgenstein y Ramsey nos dicen, debemos guardar silencio. En cuanto a las afirmaciones del segundo punto, (Urma, 2009) nos dice:

This would add: The most perfect Being has all perfections, existence is a perfection; therefore the most perfect Being exists to the following: A perfection, say, existence is a member of the class of all those classes which are not members of themselves […] which in turn requires: God must be a fact which is neither in nor outside the world”.

Como se puede apreciar, eso no hay quién se lo trague. Además si un hecho es de este mundo se puede hablar de él, pero si no es de este mundo lo mejor es quedarse callado. En boca cerrada no entran moscas, me decía mi abuela cuando me soltaba diciendo tonterías.

Existen también las proposiciones de los apologistas del diseño inteligente, quienes según [Carmona, 2005] dicen lo siguiente: “No puedo creer (o entender, o imaginar) que Z haya ocurrido a causa de Y. Por tanto, debe haber ocurrido a causa de X”. Un ejemplar de esta proposición abstracta es la siguiente: “No puedo creer (ni quiero imaginar, ni me da la gana entender) que este  órgano haya podido evolucionar por selección natural. Por tanto, debe haberlo creado un diseñador inteligente.” Estos enunciados no son más que ejemplares del: “ex impossibile quod libet consequitur” que mencioné anteriormente.

En particular estas proposiciones no reflejan una relación objetiva entre lenguaje y pensamiento, sólo un rechazo total a los hechos científicos de los que habla Wittgenstein en su libro. Además cabe preguntarnos si el consecuente de estas proposiciones “debe haberlo creado un diseñador inteligente” se deduce las premisas. Creo que la respuesta es simple: no.

Como indiqué al inicio de estos comentarios estimado lector, usted puede creer lo que mejor le parezca acerca de su divinidad preferida. Sin embargo lo que no puede hacer usted es ir diciendo cosas que son falsas, repartiendo e inculcando más certezas de las que en realidad tiene y negando hechos y conclusiones que no admiten discusión alguna (más allá de su refinamiento).

Se ha calificado la “Paradoja divina” como “un ejercicio intelectual sin mayor interés” pero no lo es. Sobre este tema, Guillermo de Baskerville le dice a Adso en “El nombre de la rosa” algo fundamental y que mi maestro también me ha dicho: “Nunca he dudado de la verdad de los signos, Adso; son lo único que tiene el hombre para orientarse en el mundo”. Substituyamos “los signos” por “la razón” y tendremos el único instrumento que tiene el hombre para orientarse en el mundo.

En base a esto la cosa está más clara que el agua. Si usted no utiliza la espada de la razón (independientemente del instrumento que use para blandirla), entonces puede usted creer cualquier cosa y el absurdo siempre arrojará conclusiones verdaderas. Según [Marina, 2005], en griego conocimiento científico se dice epistéme, lo bien fundado, lo construido en lo sólido y es eso lo que debemos tomar de las religiones (y de todo en esta vida), desechando el resto.  Por ejemplo, el cristianismo, que es la única religión que he estudiado, tiene bases muy sencillas y sólidas, alejadas (sorprendentemente) de cualquier pretensión metafísica de verdad (ver el trabajo de [Marina, 2005]).

Por último, si nos salimos del ámbito donde se ha declarado la “Paradoja divina”, también ahí encontramos verdades a partir de premisas falsas. Por ejemplo, considere las siguiente conclusión: “El PIB  de China creció el 7,1% en la primera mitad del año”. Esta conclusión se obtiene de las siguientes premisas: a) el consumo de carbón se desplomó un 8,9% y el de petróleo un 2,6% y b) la recaudación fiscal descendió un 6%. De nuevo, pudiese ser así si no fuese porque: a) tradicionalmente, el consumo de energía en China crece alrededor del 7% anual y b) la recaudación fiscal en China solía crecer entre un 17% y el 31%. Lo mismo aplica a la proposición Zapateril que establece: “si le damos un ordenador a cada chiquillo entonces la educación en España mejora”. Como ve estimado lector, hay tela de donde cortar si utilizamos la razón.

Referencias

1. Carmena,  E. El creacionismo !Vaya timo! Editorial Laetolo. 2006.

2. Chaitin, G. The Limits of Reason. Investigación y Ciencia. Núm. 356, 2006.

3. Logical Paradoxes. The Internet Encyclopedia of  Philosophy.

http://www.utm.edu/research/iep/p/par-log.htm

4. Luckhardt, G. y Bechtel, W. How to do things with logic. Psychology Press. 1994.

5. Marina, J.A. Por qué soy cristiano. Editorial Anagrama. 2005.

6. Müller, J. Pascual, F., Delgado, J. Pardo, P. y Gallego, J. Sesión de tortura a los PIB de EEUU y China.

http://www.elmundo.es/elmundo/2009/10/29/nodoycredito/1256842545.html

7. Norman, A. Wittgenstein’s Tractatus: an introduction. Cambridge University Press. 2005.7.

8. Ramsey. F.P. General propositions and causality. En “The Foundations of Mathematics and other Logical Essays”.  1931.

9. Schwanitz, D. La cultura. Todo lo que hay que saber. Punto de lectura. 2006.

10. Vaquero, A. Una paradoja divina. Novática 199, año XXV.

http://tedeco.fi.upm.es/docs/novatica199-44.pdf

11. Urmas, S. Wittgenstein’s Tractatus 3.333 and Rusell’S paradox. Trames 2. 2009.


[1] Los griegos las llamaban ideas o conceptos [Schwanitz, 2006].

De captchas y gotchas

Tuesday, July 21st, 2009

Diario de Rorschach, 20 de Julio de 2009:

Me cuentan que en el panorama de las descargas directas hay tres actores principales: MegaUpload, GigaSize y RapidShare. Todos proporcionan un uso gratuito (y limitado) y otro de pago (y sin restricciones). Aunque varía con la localización geográfica, normalmente sólo permiten una descarga simultánea, y algunos tiempos de espera entre descargas. Por ejemplo, los dos primeros te fuerzan a esperar cosa de un minuto antes de poder comenzar la descarga. El último es mucho más estricto: aparte de esa espera, te exige un tiempo de nada más y nada menos que 15 minutos para realizar una segunda descarga.

Como ocurre en estos casos, el amigo de un amigo quería bajarse precisamente de RapidShare (el de los 15 minutos entre descargas) varios ficheros. Con paciencia y unas cañas no hay problema… pero si el número de ficheros asciende a nada más y nada menos que 400, la cosa se convierte en inmanejable. En realidad, si no hay prisa para la descarga, de nuevo, no hay problema por hacerla… pero es demasiado laborioso. Además, mi amigo me contaba que le resultaba muy agobiante tener que andar pendiente de si habían ya pasado los 15 minutos de espera y podía poner el siguiente.

De modo que me pidió ayuda…

De un rápido vistazo es fácil darse cuenta de que RapidShare es el único de los tres que no tiene captcha, esos pequeños retos de letras retorcidas que sirven para averiguar si el solicitante de la página (o servicio) es o no humano. A si es que… gotcha! ¿Habría alguna manera de automatizar las descargas? Dado que no hay prisa (mi amigo no necesitaba esquivar la limitación de los 15 minutos) ¿podría hacerse algún programita para conseguir que los 400 enlaces se bajaran solos?

Con mi sombrero de analizador  de aplicaciones Web y un diccionario de alemán, me cargué de paciencia y empecé…

Cuando se introduce la URL de la descarga directa, RapidShare nos saluda con:

Elección tipo de usuario en RapidShare

Si se analiza el .html veremos que el botón “Free user” está en un formulario, que invoca a una URL de un mirror de RapidShare con el parámetro dl.start=Free. Por tanto, el primer paso de nuestro programilla es ir a la página del enlace original, buscar la URL del formulario (un simple grep servirá), y llamar a la URL usando el método Post de HTTP con el parámetro anterior.

Tras pulsar el botón, un usuario normal,  verá la segunda página:

Espera en RapidShare

En ella se exige una espera determinada, cuya longitud depende del tamaño del fichero solicitado. Si miramos en Matrix (esto… en el html) veremos que toda esta página está programada con JavaScript. Cuanto termina el contador, el html se automodifica y nos deja ver un botón de descarga, e incluso elegir el servidor espejo del que descargárnoslo. El código del botón, y las opciones de los servidores lo tenemos en realidad desde el principio en el .html, por lo que nuestro programilla podría leerlo sin la espera. Sin embargo, los servidores se comunican entre sí, y si nos vamos directamente al servidor del fichero éste nos dirá que necesitamos JavaScript en nuestro navegador al haber podido pulsar el botón sin hacer la espera :)

Por tanto, lo que tenemos que hacer en nuestro programa es sacar el tiempo y esperar. Para eso basta buscar var c= y mirar el valor asignado, que será justo el tiempo inicial de espera en segundos. De nuevo, un grep y un poco de magia de expresiones regulares son suficiente para sarcalo.

Una vez hecha la espera, un usuario normal verá la página completa, para realizar la descarga:

 Boton de descarga en RapidShare

Si se pulsa el “+” a la izquierda de “Advanced download settings” aparecen un grupo de botones de radio para elegir el servidor espejo del que descargarse el fichero, aunque normalmente el marcado automáticamente (elegido por RapidShare) será el que se use.

Nuestro programa debe extraer del .html (y de los botones de radio) la URL para comenzar la descarga. Para eso, lo sacamos de las líneas:

‘<input  type=”radio” name=”mirror” onclick=”… [mirror] … ” >

del formulario de elección del servidor. Si queremos escoger el que RapidShare nos ha propuesto, podemos buscar la cadena checked para saber cual estaba marcado.

Una vez elegido, saltamos a él. Pero, de nuevo, el botón está en un formulario, y la solicitud de descarga debe hacerse con Post. Ahora los parámetros son mirror=on&x=32&y=64 y listo. El servidor nos enviará sin más problemas el fichero.

Ten en cuenta, que en ocasiones la segunda página (la de la cuenta atrás) no nos llega así, sino con un error, bien porque tenemos que esperar 15 minutos hasta la siguiente descarga, bien porque no tenemos “slot de descarga” libre y nos toca esperar dos minutos a ver si hay más suerte la próxima vez. En ambos casos, nuestro programa debería salir limpiamente.

Una vez terminado, es suficiente con invocarlo un montón de veces, uno por cada URL que tengamos. Lo metemos en un script que espere 15 minutos entre invocaciones, y nos vamos a dormir.

Mi amigo me dice que anoche se bajó ya los 30 primeros enlaces.

Involución

Thursday, June 11th, 2009

Tengo 30 palos. Mis alumnos me lo recuerdan cada vez que abren el C++ Builder y me dicen:

“Este compilador es ya muy viejo, ¿verdad?”

A lo que yo les respondo:

“Yo lo usé cuando estudié tercero así que, al menos, tiene 10 años…”

Y en ese momento rueda una lágrima por mi mejilla.
Pero, pensándolo bien, vivimos en un momento muy afortunado para nosotros, gracias a las tecnologías que hoy en día nos rodean: podemos no crecer. Más aún, podemos volver hacia atrás en el tiempo y quedarnos allí.

Antes una película tenía fecha de caducidad: el tiempo que estaba en cartelera de tu cine de barrio más el tiempo que el Morty (que era el tipo de mi videoclub) decidía tenerla en el estante de pelis antes de llevarla al almacén en donde que morían bajo una capa de polvo. Podías comprar las más conocidas en VHS pero la oferta era limitada. Ahora, busca un poco y podrás volver a ver las que más te molaban porque están todas. Vuelve a partirte de la risa viendo a un imberbe Tom Hanks en Despedida de soltero, recuerda lo que te gustaría haber sido uno de Los Exploradores (sobre todo el que se echaba la novia), vuelve a verme con algo de pelo en La jungla de Cristal, o comprueba si ahora pasarías miedo con Re-Animator.

Por norma, los videojuegos que ahora salen al mercado no me gustan. Paso de tener que tener un mapa de teclas a mi lado para saber cómo tengo que mover a un personaje. ¿Qué fue de los juegos controlados con un simple QAOP-Espacio?¿Qué fue de las consolas con 4 flechas y dos botones?. No os preocupéis, tenemos emuladores de Spectrum, de Amstrad y hasta de las máquinas recreativas. ¡Viva! he podido quitarme mi frustración de adolescente y pasarme el Shinobi sin dejarme ni un duro. Y podemos volver a jugar a los de consola on-line. Menudo vicio. Lo divertido que era un monigote de dos colores hecho con cuatro cuadrados.

Pregunta a tus padres qué fue de sus compañeros de colegio. Es muy probable que ni lo sepan. Yo he encontrado a la mitad de ellos a través de Facebook. Nos vemos las caras 12 años después. Pensad en qué es lo que tendríamos que hacer para recuperar el contacto con esta gente: desempolva la chorbagenda, empieza a llamar a los padres de esta gente y reza para que confíen en un desconocido que le pide el teléfono de su hija, que ya está casada y con un churumbel. Ahora, desempolvas la chorbagenda, metes el nombre en el buscador, le pides ser su amigo acompañado de un mensaje que le recuerde quién eres y cruzas los dedos para que tenga la misma curiosidad que tú en ver qué aspecto tienes 12 años después (mira, está más gordo; joder, qué calvo se ha quedado; ¿pero yo me lié con este callo?; ¡¿!pero yo le dije que no a este pibón!?!).

¿Y qué me decís de la TV? Están volviendo todas las series de TV que veíamos. Hasta han hecho remakes de V, de Battlestar Galactica (cómo han cambiado para bien los Zylon), o de El coche fantástico. Y han reeditado todas las demás y puedes comprarlas en cualquier tienda (o descargarlas, por supuesto). O puedes volver a ver sólo aquéllas escenas míticas que te marcaron de por vida o que te descubieron a Tom Jones (nunca volví a bailar igual). Si eres más osado hasta puedes volver a ver esa escena cachonda que tanta gracia te hacía, bailarla en una fiesta, reeditarla y colgarla en Youtube para que alguien como yo te pueda enlazar desde un blog. Incluso tener acceso a la tele de entonces puede hacer hasta que te redescubras: he descubierto en mí un monologuista frustrado gracias a poder volver a ver El club de la comedia

Voy a terminar con la música. Recuerdo que en el radio-casette tenía metida siempre una TDK virgen para poder grabar las canciones que más me molaban. Al final, la mayoría de ellas estaban cortadas porque antes de que terminasen te metían una cuña publicitaria. Muchas de ellas permanecen en casa de mis padres como recuerdo del niño que vivió allí. Ahora ya no sólo puedo escuchar la música de los 80 y de los 90 sino que también puedo ver los vídeos musicales: los pantalones vueltos de los Kriss Kross, las gafas que llevaba en el cole (y que se vuelven a lleva ahora) de Rick Ashley, el pezón de Sabrina o lo linda que era Marisol en el 68 (ups, creo que esta vez he retrocedido demasiado).

Una reflexión: si las nuevas tecnologías nos permiten involucionar hasta nuestra pubertad, ¿nos quedaremos allí estancados o evolucionaremos? Mi opinión: Viva el retro.
¡Yippikayei, Teclarios!

La igualdad y la orientación a objetos

Friday, May 15th, 2009

Cuando vivíamos en el tranquilo mundo de la programación estructurada (incluso con C), era fácil saber que la igualdad era real. Por ejemplo ante la sentencia:

a = b;

Sabremos que el resultado de la expresión del lado derecho se asignará a la variable del lado izquierdo. Si por el camino tienes punteros, te da igual: se asignan los punteros y listo.

Pero cuando llega la orientación a objetos, la igualdad pasa a ser mucho más dudosa. De nuevo, ante el código:

a = b;

asignamos en el atributo a, el objeto b. Pero, ¿lo asignamos realmente? Si cambio el objeto b, ¿cambiará también el objeto a? En Java no soy consciente de los punteros (como lo era en la programación estructurada), y sin embargo, como todos sabemos, si cambio b, también cambia a.

Obviamente, el problema está en si la igualdad hace copia superficial o profunda. Pero, en realidad, no he venido hoy a hablar de eso. He venido a hablar de un tipo de igualdad que hoy está mucho más de moda. Un tipo de igualdad que también ha cambiado en el salto a la orientación a objetos (siendo estrictos, la anterior era asignación, no igualdad).

Y es que, en la programación estructurada, teníamos las variables, y las funciones. Ahora tenemos los objetos, los atributos, los métodos y los interfaces.

En el único sitio donde ellas permanecen es en las clases. Pero, en realidad, es una confabulación para engañarlas y tenerlas contentas. Porque todos seguimos pensando en masculino. Por eso hablamos de la clase padre.

Menos mal que nuestra ilustrísima Ministra de Igualdad no programa. O, al menos, no pasó de Pascal (claro, que si alguna vez aprendió a programar, seguro que lo hizo en Ada).

2 de febrero

Tuesday, February 3rd, 2009

Esta mañana ha sonado mi despertador a las 6:00 y en la radio sonaba Sonny y Cher, con su canción I got You Babe. Me he metido en la ducha y el agua me ha salido completamente helada. He bajado de la habitación de invitados en la que estaba alojado y… espera, espera. Esto no me ha pasado a mí. Esto le pasaba a Bill Murray en Atrapado en el tiempo.

Teclarios, hoy, 2 de febrero de 2009, la marmota Phil ha “hablado” y, desgraciadamente, tendremos otras seis semanas de invierno.

Desde 1887, el día de la marmota más famoso se celebra en la impronunciable ciudad de Punxsutawney, en el estado de Pensilvania, donde la marmota Phil (que lleva viva durante más 120 años gracias al elixir de la vida que se toma cada verano durante el Picnic de la Marmota) sale de su guarida y busca su sombra. La fiesta es especialmente celebrada en Estados Unidos pero la llevaron los inmigrantes alemanes que llegaron a esta zona. En Alemania, los granjeros observaban al tejón durante estas fechas del año cuando salía de su madriguera. Si el día estaba soleado, el tejón, asustado por su sombra, volvía a su guarida para hibernar durante seis semanas más. En cambio, en un día nublado, salía sin miedo, augurio de que ya llegaría la primavera. A falta de tejones en Pensilvania, los granjeros alemanes decidieron observar a la marmota para conservar esta tradición.

Pero, como no, algún investigador inquieto decidió poner cifras a la superstición, tirando abajo la efectividad de Phil. Según National Geographic, las predicciones de Phil sólo fueron acertadas en un 39% de las ocasiones. Pero no dejemos que nos amarguen el día. De eso ya se ha encargado Phil prediciendo otras seis semanas de este laaaaaargo invierno que estamos teniendo.

Podréis acusarme de haber tardado demasiado en escribir este post. Cuando lo publique ya será día 3. Pero para mí el día 2 no terminará hasta que me acueste. Y quién sabe qué día será mañana. Tal vez día 2, de nuevo y vuelva a escuchar I got you, babe

Yippikayei, Teclarios!

Preguntas de probabilidad

Wednesday, December 24th, 2008

Esta vez en vez de contar una vivencia, en vez de hacer una reseña de un libro, en vez de, en definitiva, ser yo el participante activo de esta comunicación que tenemos desde hace ya meses, te toca a tí, lector, hablar.

Porque esta vez lo que hago es lanzarte dos preguntas; la razón de por qué te hago estas dos preguntas te la daré en un futuro cercano. Ah, y no temas, son fáciles. Bastante fáciles. Y por si aún te queda algo de miedo o intriga en el cuerpo sobre si sabrás dar con la respuesta correcta, te lo voy a poner aún más fácil. Te diré que, a la vez que te doy la razón por la que lanzo hoy estas preguntas, te ayudaré a asumir la “verguenza interior” que te puede haber causado el hecho de no haber sabido responder a alguna de las dos… aunque ya digo que son bastante asequibles.

Empezamos.

Pensemos en un juego de apuestas sencillo. Tan sencillo como que un grupo N de personas (el caso fácil es N = 2) juegan y apuestan a ver quién es el primero en conseguir que al tirar un dado de N caras (en el caso fácil, vale con una moneda), consigue que su número (cara para un jugador, cruz para el otro) salga, digamos 4 veces. El juego comienza con los N jugadores poniendo la misma cantidad de dinero en un cuenco en el centro de la mesa, que se llevará el jugador que primero alcance esa cifra de apariciones de su número.

Mis dos preguntas están relacionadas con un escenario singular: imaginemos que una vez empezado el juego, por alguna razón hay que parar de jugar. En ese caso, lo que debe hacerse es repartirse el dinero del cuenco en base a la situación actual del juego, es decir, teniendo en cuenta el número de veces que a cada jugador le ha salido su número.

Mis dos preguntas son:

  1. Si son dos los jugadores y en el momento de tener que parar al primero de ellos le ha salido su número dos veces, y al segundo una, ¿cómo deben repartirse el dinero apostado?.
  2. ¿Y si son tres jugadores, a uno de ellos su número le ha salido tres veces y al resto dos?

¡A calcular!

El idioma y la distancia entre hombres y máquinas

Sunday, November 30th, 2008

Querido Ndugu,

El otro día un italiano me preguntaba por qué los españoles traducimos todo. ¿Por qué “El equipo A” en vez de “A-team”? ¿Por qué “Parque jurásico” en vez de “Jurassic Park“? ¿Por qué “El coche fantástico” en vez de “Knight Rider“? ¿Por qué “El hombre araña” en vez de “Spiderman”? Y así la lista sigue interminable…

(Otro término por el que podíamos preguntar en esto de las traducciones es “ordenador” en vez de “computadora”, pero es bastante más conflictivo. En realidad también es una traducción, pero esta vez del francés. Y como muchos puristas opinan, hicimos mal en adoptar la palabrita del francés, porque estas máquinas no ordenan, sino que computan (del latin, computāre).)

Mi respuesta fue simple y concisa: porque nosotros respetamos nuestro idioma. Me salió de dentro.

En realidad, esto está empezando a cambiar un poco. Ya podemos ver en nuestros cines y videoclubs películas como “Minority Report“, “Saw” o “Daredevil”. Pero no voy a discutir sobre esto, defendiendo ninguna de las dos posturas, pues se me antoja una discusión interminable, como si emacs es mejor que vi o no (vamos, que todos sabemos que es claramente superior ;) ).

Lo que quería comentar hoy es justo la perspectiva contraria: los angloparlantes nunca traducen nada. Eso tiene una implicación inmediata en las películas extranjeras (o no): siempre las ven en versión original.

Pero como la cabra tira siempre para el monte, vamos a ir hacia nuestro terreno. Como no traducen nada, los propios lenguajes de programación “hablan inglés”.

El caso más claro es el antiguo COBOL. Como fue uno de los primeros lenguajes de alto nivel, ni cortos ni perezosos, casi le hablaban en inglés al compilador:

ADD UNO TRES 5 TO RESULTADO.
ADD UNO TRES 5 GIVING RESULTADO.

La primera línea suma los valores de las variables UNO, TRES y el 5 a la variable RESULTADO, mientras que la segunda suma los tres valores y los asigna a RESULTADO, que no es lo mismo. El “TO RESULTADO” en C++ es el cómodo “resultado +=“, mientras que el “GIVING RESULTADO” es la asignación típica.

Hoy por hoy las cosas no son tan exageradas, claro, pero la mayoría de los lenguajes conservan dentro de sus palabras reservadas una batería de palabras inglesas. De alguna forma los gringos se dieron cuenta de que no tenía sentido hablarle un inglés tan “perfecto” a la máquina para que hiciera su tarea.

A nosotros, los no angloparlantes desde la cuna, no nos preocupa demasiado tener que escribir palabras inglesas mientras programamos. Al fin y al cabo el inglés siempre ha estado ahí con nosotros, y esas palabrejas nos salen de forma más o menos fácil. Otro gallo cantaría si a Strouptrup le hubiera dado por poner las palabras clave de C++ en Danés, o a Guido van Rossum las de Python en Holandés o a Yukihiro Matsumoto las de Ruby en Japonés, obviamente.

Lo curioso en este caso es que, bajo mi punto de vista, los no nativos llegamos a tener cierta ventaja sobre los nativos cuando programamos. Porque si le pasáramos un traductor automático a uno de nuestros programas saldrían cosas como las siguientes (espero otros ejemplos vuestros, si es posible graciosos, en los comentarios…):

C, C++ y amigos

#incluye "esestandard.cab"
real dios, demonio;
entero resultadoParcial;

clase CJugador {
público:
   entero aplaude();
privado:
   clase amiga CEnemigo;
};

estandard::Conjunto *dameCaracteres() {
   vuelve NULO;
}

vacío principal(entero contadorArgs, caracter **args) {
   Cadena *c = nuevo Cadena();

   escribef("%c", c->cadena_c());

   vuelve;
}

Java (que se llamaría Lanzarote, o Fuerteventura…)

importa paquete.grande;

clase pública MiClase {
   vacío estático público principal(Cadena []args) {
      Sistema.salida.EscribeLin("bu?");
   }
};

SQL y amigos

CREA BASEDEDATOS [MisDatos] EN PRIMARIO (...)

CAMBIA BASEDEDATOS [MisDatos] PON
         CREA_ESTADISTICAS_AUTOMATICAS SI

USA [MisDatos]
CREA TABLA [MiTabla] (
      [Clave] [Entero] IDENTIDAD(1, 1) NO VACIO,
      [Nombre] [caracterVariable](50) NO VACIO,
      RESTRICCION [CP_MiTabla] CLAVE PRIMARIA (
      Clave ASCENDENTE
      ) CON ( IGNORA_CLAVES_DUPLCADAS = NO ) EN PRIMARIO
VAMOS

Me encanta. “vacío principal“, “público: entero aplaude();“.

No sé a vosotros, pero a mí esas cosas en el código me despistarían. A priori, tener que utilizar unas palabras de otro idioma puede hacer que aumente la distancia que el desarrollador percibe entre él y la máquina. Sin embargo, en realidad esas palabras en tu cabeza no significan otra cosa que instrucciones dadas al compilador. Al fin y al cabo, cuando yo tecleo “void“, no me viene a la cabeza el vacío interestelar, qué queréis que os diga. Sin embargo, ver en un fichero de código fuente “vacío llenaVaso()“, pues oye, despista.

Y no sólo eso. En realidad, si le hablas a la máquina en tu lenguaje simplificado, la sensación que percibes es que la máquina es idiota. Simple y llanamente. Porque me obliga a decirle “nuevo Cadena();”, en vez de “nueva Cadena();”. El resultado, supongo, es un distanciamiento aún mayor entre hombre y máquina, porque, al fin y al cabo, la máquina me está obligando a que cambie la forma en la que hablo con la gente sólo para que ella me pueda entender. Distancia, distancia y más distancia.

Que se jodan los nativos (con cariño).

El duro trabajo de estandarización

Thursday, October 30th, 2008

Querido Ndugu,

Hoy los programadores de C++ estamos de enhorabuena. El famoso nuevo estándar de C++, conocido entre los amigos como 0x tiene ya el primer borrador completo. El nombre, 0x, era una especie de promesa de la gente del comité que hace años asumió la responsabilidad de tenerlo listo antes de 2010 (la ‘x’ viene a ser el comodín que sería sustituido por el año de publicación, por lo que el estándar tendría la forma C++ 0x y nunca C++ 1x…).

Hace por lo menos dos años que le vengo siguiendo la pista a las reuniones del comité, a las propuestas y a los documentos generados sobre los estudios de las nuevas características que estaban planteándose añadir, y me alegro de que por fin se acerque el momento de poder utilizar el “auto” especialmente en la declaración de variables con tipos parametrizados, los “conceptos” que mejorarán los mensajes de error dados por el compilador, y otro montón de cosas que iban siendo necesarias en C++.

El borrador tiene nada más y nada menos que 1352 páginas (que espero que no tengan en un único documento en Word :) ). Es un documento que merece la pena conservar aunque la misma portada reconoce que son conscientes de que está incompleto y contiene errores. Pero merce la pena, digo, conservarlo al menos hasta que haya otra versión de borrador más moderna, porque puede que, igual que el documento del estándar anterior, haya que pagar por la versión definitiva.

No es que me de por leerme el estándar de C++ en mis momentos ociosos, pero alguna vez he recurrido a él cuando hacía cosas un poco conflictivas. Y siempre queda bien resolver la cuestión con la frase concreta del estándar que te resuelve la duda… si alguien te viene diciendo que no le funciona, le puedes soltar que su compilador no cumple el estándar, y que la culpa no es tuya :)

Siempre he creído que trabajar en un comité de estandarización no debe ser nada fácil. Este borrador lo refleja claramente. Pero por si sois perezosos y ni siquiera abrís el enlace para intentar entender el soporte de las hebras (si pasáis de la primera página de la sección habiéndolo entendido, decidlo :) ), contaré algo yo sobre esto.

En el desarrollo del estándar hay que intentar fijar unas normas de tal forma que sean tan claras que no dejen lugar a dudas sobre lo que quieren decir, ni dejen cabos sueltos que abra las puertas a futuras incompatibilidades entre los implementadores.

A eso hay que añadir la gran cantidad de conflictos de intereses contra los que algunos estándares tienen que luchar, las sugerencias o ideas que reciben los comités, las presiones de tiempo y un largo etcétera.

El libro “The design and evolution of C++” es una buena fuente para darse cuenta de todos estos aspectos, pues describe la experiencia desde dentro (los ejemplos que aquí describo están sacados del libro). Con él se aprende que gran parte del proceso de estandarización consiste en “encontrar la forma de expresar completa y claramente lo que todo el mundo sabe pero resulta no estar escrito en ningún manual”, en aclarar aspectos oscuros que afectan a un pequeño número de programadores, pero que son vitales para los implementadores de los compiladores que en un momento dado se enfrentan al problema de decidir cómo compilar un ejemplo concreto de código.

El libro dedica unas cuántas páginas a resolver el problema de estandarización del método para determinar con exactitud a qué declaración corresponde un nombre cuando se declara una clase. Por ejemplo, ¿a qué x se refiere la implementación de X::f() en el siguiente código?:

int x;

class X {
   int f() { return x; }
   int x;
};

Cualquiera que haya programado un poco en C++ contestará (correctamente) que se refiere a X::x. Podríamos incluso ser capaz de deducir una regla (incorrecta, como veremos) del tipo “en la definición de las clases, los símbolos definidos dentro de ella están disponibles también para las declaraciones anteriores a la propia definición del símbolo”.

Entonces, ¿qué ocurre con este código?

class T {
   A f();
   void g() { A a; /* ... */ }
   typedef int A;
}

Con la regla anterior debería compilar, pues A está definido dentro de la clase T que lo utiliza… pero no. No compila. Y no compila porque en realidad, el primer ejemplo compilaba por otra regla distinta, una cuyo nombre técnico es “regla de reescritura” y que viene a decir que las funciones miembro que se declaran inline deben ser analizadas como si estuvieran definidas inmediatamente después del final de la declaración de la clase. Con esta regla, la implementación de X::f() del primer ejemplo se analiza “después” de analizar toda la clase, y en particular, su atributo X::x.

Y según esta regla, este segundo ejemplo no compila cuando analiza la línea A f(), ya que el tipo A no está definido, pero no da error en la función inline ya que, aplicando la regla de reescritura, al final de la clase A ya está definido.

La regla de reescritura, no obstante, introduce un nuevo problema, a saber: ¿a qué T se refiere Y::f() en el siguiente trozo de código?

typedef char *T;

class Y {
   T f() { T a = 0; return a; }
   typedef int T;
};

El problema surge debido a que la implementación anterior utilizando la regla de reescritura es equivalente a (o mejor dicho, se compila como):

typedef char *T;

class Y {
   T f();
   typedef int T;
};

inline T Y::f() { T a = 0; return a; }

De tal forma que en la definición de Y::f() (dentro de la clase) ésta devuelve un char *, pero en la declaración/implementación posterior, pasa a devolver un entero.

Pues bien, para evitar esto, se introduce una regla más, conocida como la regla de la redefinición del tipo, que dice que un tipo no puede ser redefinido en una clase después de su primer uso en ella. Por lo tanto, el error que da el compilador es algo como “error en la declaración typedef int Y::T, por cambio de significado” (es curioso comprobar que esta regla no se tiene en cuenta en Visual Studio, al menos en las versiones 2003 ni 2005…).

Volviendo al proceso de estandarización, estas dos reglas ya estaban claras cuando el proceso de estandarización de C++ comenzó. En principio, parecían suficientes para cubrir todos los casos pero ahí es donde entra el trabajo de la gente del comité que se dedica a busca casos esotéricos que no sean cubiertos por las reglas. Son fragmentos de código que uno no se encuentra en su quehacer diario pero que, cuando alguien se enfrenta al problema de programar un compilador, debe resolver. Si se utilizan únicamente las dos reglas anteriores, no está claro qué se debe hacer.

El ejemplo que aparece en el libro y que refleja que el trabajo de una de estas personas puede llegar a ser perjudicial para su salud mental es el siguiente (tengo que reconocer que me costó bastante entender qué quería decir…):

typedef int P();
typedef int Q();

class X {
   static P(Q); // equivalente a static P Q; es decir
                // la definición del símbolo Q del tipo
                // P, es decir, función que devuelve un int

                // Q por tanto ya no es el typedef

   static Q(P); // definición de Q como una función que
                // recibe como parámetro a P y que devuelve
                // un entero (int implícito heredado de C).
};

Si obviamos que finalmente eliminaron la posibilidad de omitir el int en el tipo devuelto por una función, el código anterior era válido; “simplemente” declara dos funciones Q con tipos distintos en los parámetros. Sin embargo, si le damos la vuelta a sus declaraciones, estaríamos definiendo dos funciones P. Si quitamos alguno de los typedef tenemos otros significado…

Un ejemplo más sencillo que tampoco era cubierto por las reglas anteriores es:

int b;

class Z {
   static int a[sizeof(b)];
   static int b[sizeof(a)];
};

En este caso, también debería resultar en un error pues b cambia de significado después de su primer uso (aunque no cambia en realidad el significado de ningún tipo).

Espero que estas secciones de código y sus explicaciones hayan sido suficientes para ejemplificar lo duro que debe ser trabajar en uno de estos comités.

Por terminar el post, pongo aquí las reglas que finalmente adoptó el comité en Marzo de 1993:

  1. El ámbito de un nombre declarado en una clase es no sólo el texto que sigue a la declaración de ese nombre, sino también el cuerpo de todas las funciones, argumentos por defecto e inicializadores de constructores en esa clase (y sus clases anidadas). Obviamente se excluye en la propia definición.
  2. Un nombre N utilizado en la declaración de la clase S debe evaluarse de igual manera en el contexto que aparece y en el ámbito completo de S, entendiendo como ámbito completo la clase S, sus clases base y todas las clases que la encierran.
  3. Si reordenando la declaración de miembros conduce a un programa válido bajo las reglas dos reglas anteriores, el comportamiento del programa no está definido.

Yo, Teclario

Saturday, October 11th, 2008

Este verano me enteré, gracias al informe especial de IEEE Spectrum, de lo que es la Singularidad Tecnológica.

La Singularidad, como lo abrevian ahora, es aquel evento futuro en el cual el progreso tecnológico conduce a la superación de la inteligencia humana, provocando una revolución cultural y social sin precedentes, una evolución artificial y vertiginosa del ser humano… una especie de transhumanismo.

¿Robots tomando conciencia de sí mismos? ¿Mentes humanas que pueden cargarse y descargarse de la red como si fueran ficheros MP3? ¿La felicidad software infinita y eterna al alcance de un click? Todo eso y mucho más (según algunos visionarios) lo veremos pronto, en menos de 30 años.

Imagino que la mayoría habréis acabado de leer el último párrafo con el mismo gesto de escepticismo que yo al hojear las páginas del susodicho informe. ¡Y es que no es para menos! Aunque tratar algunos de estos temas desde un punto de vista científico me parece apasionante, descoloca un poco verlo expuesto en forma de “debate científico” (más bien tutti frutti de conjeturas) donde podemos encontrar sabores tan opuestos como el del artículo de Alfred Nordmann “no tengo nada contra los singularitaristas, lo tengo contra el razonamiento endeble, los pensamientos ilusorios y las invitaciones a la irresponsabilidad”, o el del ensayo de Vernor Vinge (escritor de ciencia ficción y “padre” de la criatura, ¡al que además se le deja cerrar el infome, casi a modo de conclusión!), “he aquí los signos del inminente advenimiento de la Singularidad…”, pasando por el leve comentario de Gordon Moore, “no me preguntes por qué… pero no me lo creo”.

De todo el informe yo me quedo con la propuesta de Koch y Tononi: un nuevo test de Turing para probar si una máquina es consciente. El artículo, en realidad más que definir dicho test, hace un divertido “descarte” de todo aquello que, al contrario de lo que cree el común de los mortales, nada tiene que ver con la consciencia. Los autores argumentan que las capacidades senso-motoras, emocionales, memorísticas, lingüísticas, de atención o incluso de auto-reflexión (instrospección) no son requisitos para la consciencia porque los seres humanos podemos (de muchas y muy diferentes maneras) “prescindir” de ellas y aun así mantener intacto nuestro más inequívoco rasgo de humanidad.

Y he aquí la clave, el meollo del asunto (a mi entender) y la razón de ser de este post: ¿pero qué demonios es la consciencia?

Leyendo a Pinker empecé a descubrir que había significados muy distintos para la palabra consciencia. La RAE recoge dos muy parecidos, el conocimiento inmediato que todos tenemos de nosotros mismos (una especie de habilidad intrínseca de nuestra mente) y la capacidad de percibirnos e identificarnos como otro objeto más de los que habitan este  mundo (algo así como tratarnos igual que tratamos otras cosas en el plano de lo “sensible”).

No sé si lo habéis intentado alguna vez, pero es terriblemente difícil definir (= demostrar formalmente a los de “ahí fuera”) que somos conscientes. Si, como en Blade Runner, fueramos sometidos a un test Voight-Kampff para demostrar que no somos replicantes y nos fuera la vida en ello… ¿qué argumentos usaríamos?? Oh, dios mío, cuan acuciante es esta cuestión :)

Yo creo que todavía estamos lejos de tener una buena respuesta, pero mi definición provisional sería: “Consciencia es la experiencia subjetiva de conocer la propia existencia” y probablemente tenga mucho que ver con un cierto conocimiento del mundo (siempre subjetivo) y de UNO MISMO como parte integrada y en esencia “generadora” (por paradójico que sea) de dicho contexto. Ahí es nada… :P

Catálogos, conjuntos e ISBN

Monday, October 6th, 2008

¿Está incluido en el catálogo de libros de una biblioteca el propio catálogo?

Si M es el conjunto de todos los conjuntos que no se contienen a sí mismo, ¿está M incluido en M?

Si los barberos sólo pueden afeitar a la gente que no sabe afeitarse por sí misma, ¿quién afeita al único barbero del pueblo?

Y para terminar, una más fácil: El manual del usuario del ISBN, ¿tiene ISBN?…

… pues no.

(para las otras preguntas, informarse sobre la Paradoja de Russell)