Tutorial Haskell #0: El "Qué"

¿Cual es la diferencia entre Haskell y C?

El modelo de cómputo.

En C el modelo tiene la siguiente "forma":

{-
      |          INICIO
      |          INST1
      |     |--> INST2
      |     |    INST3
      |     |    INST4
      |     ---- INST5
      |          INST6
      v          FIN
-}

Todas las instrucciones van de arriba hacia abajo, ocasionalmente saltando de regreso.

En Haskell es más del tipo:

{-
--------------------
|     /----------- |
|     |  /-----\ | |
|     |  |B  D | | |
|  /-\ \ \----/  | |
| | A | \  E     | |
| |   |  \     C | |
| |  F|   \------/ |
|  \--/            | 
--------------------
-}

Las "células" son funciones, y las "cosas" que tiene una célula adentro, ya sean letras u otras células, son sus argumentos. No existe una figura tipo "arriba hacia abajo", aunque se podría argumentar que en cada conjunto concéntrico de células hay una figura de "adentro hacia afuera".

Hay diferencias más allá de la forma. La más importante, el modelo de memoria. C tiene un "almacén" de celditas, y cada instrucción puede seleccionar una o más celditas y guardar ahí datos. El que conozca la dirección de las celditas puede utilizar los datos en el momento que quiera.

No es así en Haskell. No tiene un almacén y, para usar un dato, es necesario "propagarlo" a partir de donde se creó.

{-
--------------------
|  17 /----------- |
|  <---  /-----\ | |
|     |  | 3*4 | | |
|      \ \----/  | |
|   *7  \        | |
|        \   +5  | |
|         \------/ |
--------------------
-}

En este ejemplo el "3*4" propaga un 12 hacia el "+5", que propaga un 17 hacia el "*7".

No tiene todas las desventajas de la propagación; en general, una vez que se ha generado un resultado, éste solamente tiene que propagar a partir de un punto en el que ha sido utilizado hasta el punto donde se requiera. No tiene que propagar a partir de la fuente hasta el destino cada vez.

Esto se debe a una de las propiedades más importantes de la programación en Haskell: todo es una función, en el sentido formal. A una función, si se le pasan los mismos argumentos, debe siempre producir el mismo resultado.

Como se cuenta con esa garantía, se sabe que los resultados que han sido medio propagados no pueden haber cambiado entre el momento que fueron creados y el momento en el que deben ser propagados más lejos.

También se pueden hacer propagaciones "hacia adentro" de "nombres" que se le dan a funciones o a valores. Por ejemplo:

{-
---------------------
|  7 se llama x     |
|        |          |
|    /---|----\     | 
|    |   v     | 10 |
|    |  x + 3 --->  |
|    |         |    |
|    \---------/    |
|                   |
---------------------
-}

Aquí, en el nivel exterior, se le ha dado al número 7 el nombre de x. Como la suma está en un nivel más interior, recibe por propagación la información del nombre. Puede realizar su cómputo y es capaz de propagar un valor al nivel superior.

Una cosa más: las celdas son capaces de propagar el resultado de su cómputo hacia afuera, pero no lo hacen a menos que algo "inspeccione" dicho resultado. Es como en el caso del gato de Schrödinger: no conocemos la respuesta hasta no verla. Aquí es por lo general determinista, pero fuera de eso es como con el gato. El cálculo no se realiza hasta que alguien no "ve" el resultado.

Powered by Drupal, an open source content management system