C++ simple example

I’m beginning to read the glorious: The C++ Programming Language, 4 ed., by Bjarne Stroustrup.

I’m okay saying I have no knowledge at all about C++. I’ve been avoiding it ever since I started college, but I feel compelled to give it a try. Not just because I feel like it but it’s one of the most used programming languages and it’s needed to learn Vulkan (wich interests me), the succesor of OpenGL.

It looks hard, but I guess time will prove. I remember C looked impossible 3 years ago, now it’s just another language. (Nevermind my journey with Ocaml).

Let’s jump right into it!

Always remember that the C++ compiler reads C code without any trouble. So we just have to add concepts and know C.

I think a comparison will do to show some light concepts that are new in C++.

How would you create an array of integers, of a size determined at run-time, and then fill it?

In c we would just do this:

 1 /* example1.c */
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 
 5 int main(void)
 6 {
 7     uint size = 0;
 8     scanf("%u", &size);
 9 
10     int arr[size];
11     uint i;
12     for (i = 0; i < size; ++i)
13     {
14         scanf("%d", &arr[i]);
15     }
16     return 0;
17 }

Simple enough, and in c++:

 1 /* example1.cpp */
 2 #include <iostream>
 3 
 4 int main(void)
 5 {
 6     uint size {0};
 7     std::cin >> size;
 8 
 9     int arr[size];
10     for (auto& x : arr)
11     {
12         std::cin >> x;
13     }
14     return 0;
15 }

As I said, C++ and C are totally related. Each line has been “translated”, the structure of the program remains the same.

The first difference is found at the headers: <stdio.h> has been replaced by <iostream>. So now we don’t use printf and scanf but std::cout and std::cin. The std prefix means that cin and cout are found in the standard namespace, them being streams and not functions.

Then, in the first line of the main function we replace uint size = 0; with uint size {0};. In C++ the assignment = can be replaced with curly braces, this feature is optional, we can still do it as we did in C. I did it just to illustrate an interesting difference.

As said earlier, we replaced scanf was replaced by using cin. To use it we use the >> operator (“get from”), as we have the << operator (“put to”) to use cout.

In the for loop we make an interesting change, we iterate over our array, a very useful feature. But we did more than that:

/* simplest case while iterating on the array */
for (int x : arr) { ... }

/* we use "auto", wich guesses the type of the element based on the type or our array */
for (auto x : arr) { ... }

/* another useful C++ feature, we get the element of the array by reference, so we can directly modify x */
for (auto& x : arr) { ... }

Finally we modify x with cin, thanks to our auto& x.

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:

  • main.ml: aquí definimos el main, quien llama a nuestro repeat
1 open Repeat
2 
3 let _ = repeat "hola" 5
  • repeat.mli: la interfaz de repeat
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
  • repeat.ml: la definición de repeat
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.

El poder de Jekyll

Como dije antes, estoy probando Jekyll. Estoy sorprendido por la capacidad de modificación que tiene realizando practicamente ningún cambio.

Probando un poco, logré con solo 3 lineas, que se pueda leer el post sin entrar al post:

1 <div class="post-content">
2     { { post.content } } 
3     <!-- Agregué espacios entre las llaves -->
4     <!-- para que se pueda renderizar. -->
5 </div>

Cuando tenga tiempo haré una inspección más profunda.

Primera publicación!

Estoy probando Jekyll. Por ahora parece lo más “simple”, pero aún manteniendo el control de que esta sucediendo en el sitio. A nadie le debe agradar tener un sitio y no poder saber como funciona. No sé que enfoque le voy a dar, si es que le doy un enfoque. Sería interesante. El tiempo dirá!

Voy a hacer un ejemplo de codigo solo por curiosidad sobre Jekyll:

1 def say_hi(name)
2   print "Hi,", name
3 
4 say_hi("Tom")
5 # printea "Hi, Tom" a STDOUT.

Recomiendo ver Jekyll docs por si alguien está interesado. Cubre todo (creo).