Programación

Extingámonos con dignidad: generaciones actuales y futuras, no incurramos en los errores de las anteriores

Participé el otro día en una cena con gente friqui. Constaté con cierto desasosiego cómo han virado los sujetos pasivos de nuestra indignación profesional a lo largo de los años.

Antaño, fueron los viejos que seguían apegados a la paleoinformática. Hogaño, los primíparos que usan Python y desdeñan R.

Tengo sentimientos encontrados y no sé qué más añadir.

Windows Subsystem for Linux

Igual todo el mundo conoce ya WSL. Pero por si acaso queda entre la audiencia algún otro despistado, pues, eso: que existe en Windows 10 (¿solo?) un subsistema Linux que permite correr comandos de consola, instalar paquetes (p.e., con apt-get), etc. Incluso R. Me queda solo la duda del entorno gráfico, sobre el que no he visto nada.

En su día, Windows fue un programa de MS-DOS que arrancaba al escribir win en la consola. Después hubo que arrancar la consola como un programa más de Windows.

Efectos secundarios (nota: que existan no significa que debas usarlos)

Una función no debería cambiar nada de cuanto la rodea. Debería devolver algo y ya. Se acepta barco como animal acuático cuando hay funciones que escriben en logs, guardan datos en disco o crean gráficos.

R deja que los usuarios se disparen en el pie permitiendo hacer cosas tan peligrosas como:

a <- new.env()

a$1     # error

foo <- function(){
  a$a <- 1
}

foo()
a$a
# [1] 1

De la misma manera, si le enseñas un cuchillo a una vieja, es posible que te dé su bolso con todo lo que contiene. Pero eso no significa que debas usar los cuchillos para tales fines.

Una fina, tenue, somera capa de sintaxis

Estuve el otro día en una charla de José Luis Cañadas en el grupo de usuarios de R de Madrid sobre sparklyr. Hoy en otra de Juan Luis Rivero sobre, esencialmente, lo mismo, pero esta vez con Python. Y podría escribir “etc.”.

evolucion_convergente

Me centraré en la de José Luis, aunque podría decir lo mismo de cualquiera de las otras. No había trabajado con sparklyr. No soy siquiera fan de dplyr (aunque no es que no se lo recomiende a otros; es simplemente, como tantas cosas, que soluciona problemas que no tengo). Pero la seguí sin mayores problemas. Lo que tenía de nuevo era una fina, somera capa de sintaxis que enlazaba fundamentos con fundamentos.

Un curso de 15 horas de introducción a la programación

Hoy comienzo a enseñar un curso de introducción a la programación para recién graduados que comenzarán un máster de matemáticas aplicadas con incursiones en la llamada ciencia de datos. Serán 4 sesiones con el siguiente contenido:

  • Sesión 1, programación imperativa: variables, condicionales y bucles.
  • Sesión 2, programación orientada a objetos.
  • Sesión 3, colecciones: listas, tuplas, conjuntos, diccionarios, etc.
  • Sesión 4, programación funcional: map, reduce, fold, foldLeft, scan, filter, etc.

Los lenguajes a utilizar serán R y Python (via Jupyter). No me he atrevido a añadir Scala (como ejemplo de cómo deben hacerse las cosas, además de ser un lenguaje, para variar, tipado y no interpretado) por falta de tiempo.

R es un vago

Si creo la función

foo <- function(a,b) a*a + b

y la llamo mediante

foo(1 + 1,3)

pueden ocurrir dos cosas: o bien que R precalcule 1+1 y la función ejecute 2 * 2 + 3 o bien que la función ejecute directamente (1+1)*(1+1)+3. Pero, ¿qué es lo que hace realmente? Si escribimos

f1 <- function(x){
    print("Soy f1")
    x
}

f2 <- function(x){
    print("Soy f2")
    x
}

foo(f1(2), f2(3))

obtenemos

> foo(f1(2), f2(3))
[1] "Soy f1"
[1] "Soy f2"
[1] 7

lo que significa que f1 ha sido llamada una única vez. Es decir, R resuelve sus argumentos antes de aplicar la función. Pero hay más:

Metropolis-Hastings en Scala

Tengo la sensación de que un lenguaje funcional (como Scala) está particularmente bien adaptado al tipo de operaciones que exige MCMC.

Juzguen Vds.

Primero, genero datos en R:

datos <- rnorm(500, 0.7, 1)
writeLines(as.character(datos), "/tmp/datos.txt")

Son de una normal con media 0.7. En el modelo que vamos a crear, suponemos conocida (e igual a 1) la varianza de la normal y trataremos de estimar la media suponiéndole una distribución a priori normal estándar. Y con Scala, así: