El futuro de la programación

En los comentarios de hace unos días Amnio comentaba los problemas a los que se tiene que enfrentar cuando programa. Cuando tarda horas en detectar un pequeño fallo absurdo que afecta paralelamente a todo el sistema haciendo que no funcione. Este ha sido uno de los grandes problemas de la programación y creación de software desde sus inicios que nunca hemos logrado solucionar. Todo lo que se ha conseguido han sido parches que no han conseguido solucionar realmente este problema endémico.

Los gurús de Sun Microsystems trabajan a día de hoy pensando en como solucionar el problema de los bugs incontrolables cuando estamos trabajando con grandes proyectos. Dos de los mejores artículos que he encontrado por la red son el de Jaron Lanier, critica que no somos capaces de crear software potente sin bugs:

I think the whole way we write and think about software is wrong. If you look at how things work right now, it’s strange — nobody — and I mean nobody — can really create big programs in a reliable way. If we don’t find a different way of thinking about and creating software, we will not be writing programs bigger than about 10 million lines of code, no matter how fast our processors become. [After publication of this interview, Jaron Lanier realized that his sentence should read: «bigger than about 20 to 30 million lines of code…».]

Pero luego se remonta a los orígenes haciéndonos pensar sobre la verdadera naturaleza de la programación actual. Argumenta que la forma de programar de hoy en día está muy influenciada por los orígenes electrónicos de la informática.

If you look at the way we write software, the metaphor of the telegraph wire sending pulses like Morse code has profoundly influenced everything we do. For instance, a variable passed to a function is a simulation of a wire. If you send a message to an object, that’s a simulation of a wire. And it’s not that there’s anything wrong with this, but I can make an empirical observation: If you have a time-based protocol to send codes on a wire, it’s inefficient to make that kind of coding error-tolerant. It’s much more efficient to make it error-intolerant. So errors tend to be catastrophic. You tend to create a situation where, if you get one bit wrong in passing a variable to a function, the function does something that’s not just wrong, but chaotically wrong, arbitrarily wrong, terribly wrong

Finalmente nos propone librarnos de cualquier influencia anterior que tengamos sobre la informática para poder crear cosas realmente nuevas en este campo.

So, now, when you learn about computer science, you learn about the file as if it were an element of nature, like a photon. That’s a dangerous mentality. Even if you really can’t do anything about it, and you really can’t practically write software without files right now, it’s still important not to let your brain be bamboozled. You have to remember what’s a human invention and what isn’t. And you have to think about files in the same way you think about grocery carts. They are a particular invention with positive and negative elements. It’s very important to keep that sense of skepticism alive. If you do that, it will really have an influence on the quality of code that you create today.

Leeros el artículo entero que vale la pena. En él nos explica como será la programación el futuro, y como cree él que se podrán solucionar los problemas del software. Para continuar si os ha gustado este primero, leed el de Victoria Livschitz que continua hablando sobre el mismo tema. Sobre los problemas de la naturaleza del software, y como sería posible solucionarlo creando un modelo de programación más cercano a la realidad (Más aún que la programación orientada a objetos)

Software is a product of our imagination, like a book, a painting or a movie, designed to synthesize a particular representation of the real world. But unlike all other forms of pure art, software is constructed for utilitarian purposes to do more then merely reflect the real world; software interacts with the world and in many cases even controls it. And what is truly amazing — software is replicable: instantaneously, in arbitrary numbers, at zero cost!

Una conclusión que he sacado yo después de la lectura es que cuando tenemos por ejemplo un programa de 5.000 clases, con montones de relaciones entre ellas es imposible saber los efectos que tendrá un simple cambio, porque se propagará por todo el programa creando efectos secundarios. La orientación a objetos está mal diseñada en este aspecto y sería mejor crear un nuevo modelo donde las clases tenga entre ellas otro tipo de relaciones diferentes a las clásicas «Is a» y «Has a». Pero ¿Como hacerlo? ¿Como eliminar el problema de los bugs y la manutención del software?, si encuentras la solución serás uno de los informáticos más importantes de la historia. ¿No sería mejor crear un nuevo método de programación más cercano al pensamiento humano y adecuado a la potencia de las máquinas actuales?

Chicas linux

Después de unos cuantos posts «durillos» y técnicos aquí tenéis un par de chicas Linux para relajarse. Una de ellas está anticuada y usa el Kernel 2.0 (Haced click en la segunda foto para ver el detalle), si alguien la encuentra por la calle que se lo actualice 😉 A mi me están entrando ganas de meterle mano al código del kernel.

Por cierto, buscando «debian girl» en google imagenes me he encontrado esto Debian girl. La risa.

Colossus

Ya hablé de Enigma y su poder para encriptar datos del ejército alemán. Pero los ingleses con Alan Turing a la cabeza se las ingeniaron para poder decodificar la clave de cada día usando bombas y a partir de ella poder desencriptar cualquier mensaje alemán. Pero en 1943 los Alemanes crearon una nueva máquina que utilizaba la cifra de Lorenz.

La cifra de Lorenz se utilizaba para codificar las comunicaciones entre Hitler y sus generales, era muy importante para los Ingleses poder conocer esta información. Pero la nueva codificación era mucho más complicada que la que usaban las máquinas Enigma corrientes y el diseño de las bombas inglesas no era el adecuado para poder descifrarla.

Pero Max Newman, un matemático que trabajaba con Alan Turing creó una nueva máquina capaz de adaptarse a diferentes problemas basándose en el concepto de máquina universal de Turing. Este fue posiblemente el primer ordenador programable de la historia. Su nombre era Colossus y constaba de 1.500 válvulas electrónicas y lo más importante de todo es que era programable. Con Colossus los aliados fueron capaces de descifrar todos los mensajes de los enemigos predeciendo los ataques alemanes, sabiendo las posiciones de las tropas, movimientos de submarinos etc. y de esta forma poder ganar la guerra con más rapidez y efectividad.

Colossus fue destruido después de la guerra, y a todo el mundo que lo conocía se le prohibió hablar de él. Incluso los papeles del diseño del primer ordenador de la historia se quemaron. Esto significó que en 1945 J. Prespert Eckert y John W. Mauchly, crearan el ENIAC con 18.000 válvulas considerándose el padre de todos los ordenadores. Estados Unidos tomaba una ventaja crucial en el mundo de la computación y la tecnología que se ha mantenido hasta la época presente.

Java y C#

La verdad es que no estoy en contra de ninguno de los dos lenguajes. Pero voy a criticar ciertas cosas de ambos. C# ha copiado inteligentemente muchos de los conceptos que se idearon con Java en cuanto a una programación orientada a clases elegante pero también es verdad que han introducido nuevas cosas para hacer más agradable el trabajo del programador. Una de las cosas que más me han tocado las narices de Java son los casts (supongo que otros compartiran este sentimiento y se habrán facilitado las cosas con Java 1.5). Me refiero a cosas como esta (El código funciona compilando con Java y C#, que casualidad 😉 :

   String cadena=»22″;
    int numero=Integer.parseInt(cadena);

¿Para qué usar un método estático? No sería mejor algo más intuitivo que lo siguiente:

   String cadena=»22″;
    int numero=cadena.toInt();

Supongo que en Java 1.5 esto ya estará solucionado de la forma que comento. ¿Pero no sería incluso mejor poder hacer esto?:

   String cadena=»22″;
    int numero=cadena;

Y que el compilador se encargue de hacer el cast automáticamente si es que se puede. Esto que comento es la eterna discusión entre los lenguajes que te permiten un control total tipo C, a lenguajes restrictivos como Java. Yo pienso que un lenguaje muy restrictivo crea programadores malos porque no saben realmente lo que están haciendo. Por otra parte si el compilador «se lo traga todo» sin avisar haciendo casts a lo bestia puede dar lugar a bugs difíciles de detectar. Lo ideal creo que es poder el escoger el nivel de restricción. ¿Qué pensais que es mejor, que el compilador haga lo que tu quieras (C,C++ …) o hacer lo que te mande el compilador (Java, C# …)?

Los puentes de Königsberg

Leyendo un post de Tirando Líneas me vino una duda que me resolvió Jacobo sin problemas. El tema me hizo recordar el problema de los puentes de Königsberg. Cuenta la leyenda que un ciudadano se propuso dar un paseo por todos los puentes del río Pregel sin pasar dos veces por el mismo. Los puentes tenían la siguiente disposición:

Durante años se fue extendiendo el rumor y la gente del pueblo se dedicaba a intentar dar un paseo sin cruzar dos veces por el mismo puente. Si intentáis hacer con papel y lápiz, equivale a dibujar una línea pasando por todos los puentes una sola vez. Nadie consiguió realizar tal proeza, y si no comprobadlo vosotros mismos 😉

Pero en 1736, el gran matemático suizo Leonard Euler publicó que era imposible dar tal paseo. Veamos como se puede demostrar matemáticamente. Podemos representar los puentes mediante lo que los matemáticos llaman Grafo. Veamos como se obtiene el grafo a partir de los puentes:

En el grafo las aristas representan los puentes y los vértices tierra firme. Si pensamos en como dibujar el grafo sin levantar el lápiz y sin pasar dos veces por la misma arista se ve que cada vez que «llegamos» a un vértice necesitamos una arista para «salir», es decir, que si a un vértice llegan 2 aristas podremos entrar por una y salir por la otra. Pero si un vértice tiene 3 aristas llegaremos por una, saldremos por otra, pero la siguiente vez al llegar ya no tendremos salida.

  • Concluimos que todo los vértices del grafo deben de tener grado (Numero de aristas que inciden en el vértice) par para poderse dibujar sin levantar el lápiz empezando y terminando en el mismo punto.
  • En el caso de haber dos vértices con grado impar también se puede solucionar el problema pero empezando y terminando en diferentes puntos.

El grafo de los puentes de Königsberg tiene los vértices A,C y D con grado impar, por lo que es imposible dar un paseo si pasar dos veces por el mismo puente.

Dibujad vuestros propios grafos con vértices de grado par y vértices de grado impar para hacer las pruebas. Un ejemplo típico y cotidiano es el de la casita con la cruz dentro en la cual todos los vértices tienen grado par. También podéis resolver fácilmente usando grafos el problema de Tio Petrus que acabo de encontrar. Ya es casualidad que hablemos de lo mismo 🙂

Wonderful Days

    

Incréibles los gráficos de esta superproducción Koreana. Una película de una belleza apabullante, por las imágen, la música y los personajes. Que habría sido perfecta teniendo un guión un poco más original. Utiliza la típica formula de mundo post-apocalíptico contaminado y una historia que no aporta nada nuevo. En todo caso muy recomendable solo para ver como Disney, Pixar y compañía están a años luz de la animación asiática. Otra película Koreana con unos gráficos mucho más humildes pero con un guión bueno es Oseam