Ocaml v. C

No tengo palabras para describir a Ocaml aparte de raro. Es un lenguaje nuevo, distinto. Con elementos ajenos. Por eso decidí, que lo más lógico sería hacer un simple programa en C y retratarlo en Ocaml con lo poco que entiendo.

Se me ocurrió que sería interesante ver un programa que imprima un string s, unas n veces. Sea repeat la función descrita, en C la implementamos de la siguiente manera:

 1 /* repeat.c */
 2 #include <stdio.h>
 3 
 4 void repeat(char *s, unsigned int n) {
 5     unsigned int i;
 6     for (i = 0; i < n; ++i)
 7         printf("%s\n", s);
 8 }
 9 
10 int main(void)
11 {
12     /* Seteamos las variables de la función */
13     char *s = "hola";
14     unsigned int n = 5;
15 
16     /* Corremos la función */
17     repeat(s, n);
18     return 0;
19 }

El código no es la gran cosa, incluimos la libreria stdio.h para tener la función printf y repeat es simplemente un ciclo con dicho printf.

Con Ocaml la historia es distinta, tenemos tres archivos:

1 open Repeat
2 
3 let _ = repeat "hola" 5
1 (* Solo damos el tipo de la función, el cual puede
2  * ser copiado del interprete de Ocaml
3  *)
4 val repeat : string -> int -> string -> unit
1 let rec repeat s n =
2     let open Printf in
3         if n < 1 then
4             printf "%s\n" 
5         else 
6             begin
7                 printf "%s\n" s;
8                 repeat s (n - 1)
9             end

Principales diferencias

Es evidente que son lenguajes muy distintos, ¿pero cuales son verdaderamente las diferencias?

Podemos notar inicialmente que la interfaz de repeat dice los tipos de la función, pero jamás dijimos en “repeat.ml” que tipo tiene s y n. La respuesta a esto es lo que se llama en Ocaml, inferencia de tipos.A grandes rasgos, lo que esto significa, es que Ocaml es lo suficientemente inteligente para inferir que tipo tienen las variables que usa y devuelve. Esta capacidad del lenguaje nos permite olvidarnos de las declaraciones de tipo a la hora de escribir, y para casos más avanzados, hacer polimorfismo paramétrico.

En una segunda instacia, es nuevo para nosotros tener que definir la interfaz del programa (en “repeat.mli”). Lo útil de esto es que nos facilita utilizar a repeat, sabiendo los tipos y cantidad de argumentos.

La tercera diferencia principal es la falta de corchetes,

if n < 1 then
            printf "%s\n" 
        else 
            begin
                printf "%s\n" s;
                repeat s (n - 1)
            end

reemplazados por los simbolos: begin y end.

También es importante notar el uso del punto y coma. No es necesario utilizarlo para cada sentencia como en C, pero en un bloque, debemos separar las sentencias con uno.

Finalmente, vemos que, a diferencia de la mayoría de los lenguajes, no es necesario incluir una libreria en todo el programa, podemos incluirla solo en una función cuando la necesitamos:

let open Printf in
    ...

Conclusión

Esas diferencias son solo una pequeña parte de la diferencia de Ocaml con C, y más aún de Ocaml con el resto de los lenguajes. Uno podría pasar días analizando este lenguaje, pero por ahora nos conformamos con esto.

Entre estas semanas es probable que siga escribiendo sobre Ocaml, ya que me es de mucha ayuda a la hora de aprender y estar seguro de porqué estoy resolviendo así los problemas.