lunes, 14 de diciembre de 2015

10. ¿Algorítmica, estás ahí?

Los recorridos como herramienta conceptual.


  Una pregunta muy importante cuando pensamos en un curso inicial de programación es ¿cuánta algorítmica tenemos que incluir en el mismo?
Si incluímos demasiada, corremos el riesgo de que el estudiante se atore (después de todo, los algoritmos son un concepto abstracto), pero si no incluimos ninguna se torna compleja la resolución de problemas que no sean prácticamente triviales.

  Recordemos que, el objetivo de un curso inicial de programación, es llevar al estudiante de una forma concreta de pensamiento a una forma abstracta. Consecuentemente, sería deseable que los primeros conceptos algorítmicos sean lo más "concretos" posibles, y que puedan complejizarse con el tiempo.
Nuestra propuesta sigue la línea del curso de Jean Pierre Peyrin [SP88] y sus "máquinas" (máquina de caracteres, máquina de registros, etc.): utilizar el recorrido de secuencia de elementos, comenzando con secuencias muy concretas y aumentando el nivel de abstracción con cada ejemplo.

  En el enfoque didáctico Gobstones llamamos *recorrido* a una forma algorítmica de tratamiento de secuencias de elementos. Un recorrido es, entonces, una forma de dividir el problema del tratamiento de la secuencia en subtareas específicas, de manera tal que todos los elementos sean procesados exactamente una vez, en orden y sin olvidar ninguno.
Las subtareas identificables en un recorrido son:
  • Iniciar el recorrido: identificar la secuencia y preparar lo necesario para realizar el recorrido, por ejemplo, posicionándose en el 1er elemento.
  • Verificación de finalización: pregunta que indica si aún quedan elementos sin procesar.
  • Procesamiento de un elemento: tarea a realizar con cada uno de los elementos de la secuencia.
  • Avanzar en la secuencia: tarea a realizar para considerar el siguiente elemento de la secuencia, si es que el mismo existe.
  • Finalizar el recorrido: actividad que puede variar desde el tratamiento del último elemento por separado, la restauración de condiciones alteradas durante el procesamiento, o la devolución de la información final solicitada.
Así, un recorrido tendrá el siguiente aspecto en el código:

procedure RecorridoGenerico()
{
   IniciarRecorrido()
   while (not finDeRecorrido())
    {
      ProcesarElementoActual()
      AvanzarAlSiguienteElemento()
     }
    FinalizarRecorrido()
}

Además, podemos entender al recorrido como una manera de utilizar la repetición condicional de manera tal que no se produzcan situaciones no deseadas de no terminación.

  Es fundamental que los primeros recorridos sean los más concretos posibles. Nuestra propuesta es que los elementos a recorrer en los primeros ejemplos sean las celdas de una fila o una columna, puesto que son elementos contiguos y consecutivos, y el tablero es percibido como un elemento concreto. (Por ejemplo, plantar una flor en cada una de las celdas de una fila).
A medida que se avanza en el curso, los recorridos pueden complejizarse: se pueden recorrer todas las celdas del tablero, y luego celdas que no necesariamente estén contiguas o consecutivas ("caminos" con curvas, solo celdas que tienen bolitas rojas, etc.), recorridos con un propósito particular (encontrar un elemento, o totalizar cierta información), hasta considerar, si el tiempo y el nivel deseado para el curso lo ameritan, recorridos donde la noción de siguiente elemento puede ser muy compleja o abstracta (por ejemplo, un laberinto con múltiples bifurcaciones), o, si el curso continúa con estructuras de datos, trabajar con secuencias representadas de esta forma (mediante listas).

  La experiencia utilizando la didáctica Gobstones nos ha mostrado que en general la noción de recorrido es de fácil adquisición cuando se presenta en forma concreta, y se va dificultando su comprensión a medida que se vuelve más abstracta, por lo que estamos convencidos de que la propuesta es adecuada. Otras formas algorítmicas más complejas (por ejemplo, recursión, recorridos en profundidad, etc.) son demasiado abstractas y es nuestro consejo que queden para cursos posteriores.

  El hecho de identificar a los recorridos como una herramienta útil para estructurar una estrategia de solución es un elemento de la didáctica Gobstones que creemos aporta muchísimo a la hora de enseñar programación con un enfoque gradual desde lo concreto a lo abstracto. Es otro de los elementos de Gobstones que deben considerarse fundamentales en este enfoque didáctico.

[SP88] P.C. Scholl and J.P. Peyrin. Schémas algorithmiques fondamentaux: séquences et itération. Université Joseph Fourier Institut Grenoblois d’études informatiques, 1988

lunes, 7 de diciembre de 2015

9. Dejá vù (o "Hay repeticiones y repeticiones y repeticiones")

La necesidad de separar cada concepto, pero abstrayéndolos.

 
  En Gobstones existen 3 formas diferentes de repetición: la repetición simple, la repetición condicional y la repetición indexada.
  La repetición simple consiste sencillamente de un número y un bloque a repetir:
  •   repeat (10)
  •    { Poner(Verde) }
Esta porción de código describe la repetición de la acción de poner una bolita verde 10 veces.
  La repetición condicional precisa de una condición para decidir cuándo dejar de repetir, por lo que es útil cuando no se conoce de antemano el número de repeticiones:
  •   while (puedeMover(Este))
  •    { Poner(Rojo); Mover(Este) }
En este ejemplo, no tenemos forma de saber a qué distancia se encuentra el borde, pero la repetición se encarga de llegar hasta el mismo.
  Finalmente, la repetición indexada es una forma de repetición que se basa en una secuencia de valores predefinidos, haciendo que cada iteración varíe según la información de la secuencia:
  •   foreach color in [Azul, Negro, Rojo, Verde] 
  •    { Poner(color) }
En este ejemplo, cada repetición pone una bolita de un color diferente. Entonces, el índice (en este caso, color) expresa la variación, tomando un valor diferente en cada repetición.

  Un programador experimentado podría indicar que no hace falta tener 3 formas, ya que con una de ellas pueden expresarse las demás (aunque utilizando algunos elementos adicionales como variables o estructuras de datos, o ignorando algunas características).  Por ejemplo, la repetición simple puede obtenerse a partir de la repetición indexada de la siguiente manera
  •   foreach i in [1..10] 
  •    { Poner(Verde) }
Esta porción de código es equivalente al ejemplo de repetición simple inicial (se itera sobre los valores del 1 al 10, pero el índice no se usa en la repetición, logrando el mismo efecto que una repetición simple).

   Entonces, ¿por qué tener 3 formas de repetición?

  Una característica importante de Gobstones es que los conceptos que se busca transmitir aparecen en forma pura. Por ejemplo, en el caso de las repeticiones, eso significa que cada repetición aparece con su forma más natural, sin necesidad de combinarse con otras herramientas para proveer soluciones sencillas. Esto facilita la comprensión del concepto por parte del estudiante, y permite que ese concepto sea presentado de manera natural en el momento correcto del currículum. Por ejemplo, si Gobstones no tuviese repetición simple, para explicar inicialmente el concepto de repetición deberíamos hablar de índices y variaciones que no aparecen en la forma más natural (más simple) de repetición, y de esa manera complicaríamos al estudiante la incorporación del concepto.

  De la misma forma, expresar repetición simple utilizando repetición condicional requiere comprender el uso de variables, que son una herramienta mucho más compleja que el sencillo concepto de repetición. Y para poder expresar repetición indexada en su forma completa utilizando repetición condicional es preciso contar con estructuras de datos (listas, por ejemplo), para poder tener almacenadas todas las variaciones necesarias (si la variación fuese regular, podría alcanzar con variables). Por otra parte, la repetición condicional trae consigo la posibilidad de que los programas no terminen, algo que con la repetición simple es sencillamente imposible. De esta forma, si enseñamos primero repetición condicional y variables para poder enseñar el concepto de repetición simple, es como enseñar a alguien a correr los 100 metros llanos para enseñarle a caminar... La didáctica, en este caso, debe ser tenida en cuenta.

  Por esto es que sostenemos que no es necesario enseñar variables y repetición condicional para poder aprender el concepto de repetición, y por eso Gobstones elige separar estas cuestiones en sus formas puras. Si bien puede utilizarse cualquier lenguaje para enseñar a programar, es mucho más fácil hacerlo cuando los conceptos aparecen de forma pura. Y por eso, Gobstones es importante.

domingo, 29 de noviembre de 2015

8. Primero esto, después esto, después esto otro,... ¿o no?

Pensamiento denotacional vs. pensamiento operacional y su importancia en la abstracción.

 
  En varios posts anteriores hemos insistido con la importancia del pensamiento denotacional por sobre el pensamiento operacional. ¿Por qué insistimos tanto en esto? La razón, que discutiremos en este post, es que las personas NO solemos pensar de manera operacional, sino de manera denotacional, y por lo tanto entender y manejar los programas de manera denotacional es fundamental para poder lograr una verdadera habilidad de programación.

  Es innegable que los programas son, en el fondo, entidades operacionales; o sea, un programa es, si lo reducimos a su forma más elemental, un elemento destinado a guiar a una máquina durante su ejecución. La forma tradicional en la que interpretamos esta naturaleza operacional es a través de una secuencia de instrucciones (aunque hoy día, con máquinas de múltiples procesadores, ya no sea cierto que un programa es simplemente una secuencia de instrucciones).
  Consecuentemente, la mayoría de los cursos tradicionales de programación comienzan con esta definición, y se concentran en determinar la secuencia adecuada para resolver determinado problema. Es notable que la gran mayoría de las personas cuando se enfrentan a un problema simple de programación, empiezan por pensar de esta manera. En una conversación reciente sobre este fenómeno, un docente de programación sugirió que podía ser así por la forma en que están planteados los problemas... Es un tema fascinante que da para mayor indagación.

  Sin embargo, cuando las personas pensamos en solucionar un problema, no lo hacemos de forma operacional. Si por ejemplo se plantease como problema "realizar un viaje a un país vecino", no es natural empezar pensando en levantarse de la silla, caminar hasta la puerta, subir al auto, etc., aunque estas son operaciones que DEBERÁN ser parte de la solución. Es mucho más natural para una persona pensar en algunas actividades grandes vinculadas al viaje, por ejemplo, decidir el medio de transporte, decidir el tipo de alojamiento que vamos a utilizar, decidir qué tipo de cosas vamos a llevar con nosotros. Luego, cada una de ellas involucra nuevas tareas: por ejemplo, si decidimos que el medio de transporte es por avión, deberemos reservar pasajes, decidir la forma de pago, ver cómo nos movilizaremos al aeropuerto, etc. En lugar de concentrarnos en las operaciones invididuales que serán necesarias para solucionar el problema, lo que hacemos naturalmente es *descomponer el problema en subproblemas* cuyas soluciones combinadas permitan solucionar el problema mayor. A esto es a lo que nos referimos cuando hablamos del *pensamiento denotacional*.

  ¿Por qué si nuestra forma de pensar es naturalmente denotacional, cuando pensamos un programa lo hacemos de manera operacional? La respuesta es simple: en la definición clásica se le da más importancia a la máquina que soluciona el problema que al problema en sí, o a su solución. Son las operaciones primitivas de la máquina las que pasan a primer plano, y para ejemplos pequeños resulta más fácil pensar en esos términos. ¿Puede hacerse de otra manera? Creemos que sí, y por eso el enfoque didáctico Gobstones utiliza otra definición del concepto de programa, y otro enfoque para comenzar a pensar los programas.

  Nuestra propuesta de definición para el concepto de programa es **descripción ejecutable** de la solución a un problema computacional. Esta definición es suficientemente general, e incluye por partes iguales los aspectos denotacional y operacional. Así como no es sabio focalizarse exclusivamente en el comportamiento operacional de un programa, tampoco lo es hacerlo en el sentido opuesto: un programador tiene que formarse para poder ver *ambos* niveles y focalizarse en el que haga falta en cada momento. Sin embargo, y dado que el aspecto operacional se impone de una manera ineludible, nuestra propuesta didáctica resalta mucho más el aspecto denotacional, e intenta que el mismo sea tenido en cuenta desde el principio.

  De esta forma, la propuesta incluye comenzar enseñando procedimientos (ver "¡Dame más comandos!"), que las expresiones y los comandos sean enseñados en conjunto, sin privilegiar a ninguno de ellos (ver "¿Comando mata expresión?"), que la representación de información se pueda abstraer soslayando las definiciones con bolitas (ver "¡Está lleno de bolitas! (o "It's full of stones")"), así como otra serie de elementos que permiten poner el foco en el aspecto denotacional y que serán tema de futuros posts (precondiciones, ausencia de debugging, definición precisa de nociones como parámetros o formas de repetición, etc.)

  Para ir cerrando el post, creemos que la conceptualización de un programa como una descripción de la solución a un problema, o sea, su naturaleza denotacional es un elemento imprescindible en la formación de pensamiento abstracto, ya que permite soslayar detalles irrelevantes de la ejecución para concentrarse en qué solución se describe. Dicho en otras palabras, el pensamiento denotacional es una forma de abstraer los programas, y por ello es tan importante a la hora de enseñar abstracción.

  Gobstones tiene esto en cuenta, y por eso es importante.

 

domingo, 22 de noviembre de 2015

7. ¡Está lleno de bolitas! (o "It's full of stones!")

Modelos de representación y su rol en la abstracción.


  Una característica fundamental de la programación es la capacidad de representar elementos abstractos a través de otros elementos (ya sean abstractos o concretos). Por ejemplo, uno puede representar un colectivo simplemente como dos números: el número de asientos disponibles, y el número de pasajeros sentados, suponiendo que esos datos son lo único que nos importa del colectivo. Así, (25,0) representa a un colectivo de tamaño mediano, vacío, y (50,49) representa a un colectivo grande, casi lleno. Claramente, no es cierto que (25,0) *sea* un colectivo, pero si nos ponemos de acuerdo en que vamos a entender a un colectivo de esa manera, podemos decir que (25,0) *ES* un colectivo.

  Esta forma de representar la información (o la realidad) a través de elementos que en principio no tienen nada que ver con lo que pensamos en primer lugar es una de las características que hacen de la programación una disciplina tan poderosa. Los lenguajes de programación de propósitos generales proveen usualmente un conjunto de elementos primitivos consistente en números, agrupaciones de números y abstracciones para manejar la memoria (de distinto nivel para distintos lenguajes).
  A la hora de enseñar, es usual que no nos cuestionemos estos elementos básicos, y consideremos importante empezar a enseñarlos de manera temprana. Sin embargo, estos elementos (números, memoria, etc.), son abstractos. Y como dejamos establecido en el primer post de esta serie ("Por qué Gobstones es importante"), el objetivo del enfoque didáctico Gobstones es enseñar abstracción. ¿Qué sentido tiene asumir que el estudiante conoce elementos abstractos si lo que queremos enseñarle es abstracción?

  Los cursos tradicionales de programación fallan justamente en este punto: dan por supuesto que los estudiantes pueden entender con facilidad números, arreglos, punteros y otra variedad de elementos abstractos y la forma en que se representa la información con ellos.
   Los cursos de programación que utilizan otro tipo de herramientas (Logo, Scratch, etc.) no cometen este error, pero para no incurrir en él, eliminan el componente de "representar la información" de su repertorio. De esta forma, sobresimplifican la enseñanza de la programación, y dificultan el proceso de aprendizaje posterior, cuando el estudiante deje esas herramientas y pase a temas más avanzados.

  El lenguaje Gobstones propone una solución intermedia: se utiliza un dominio concreto (tablero y bolitas), pero lo suficientemente poderoso para que gradualmente se pueda representar información sobre él, facilitando lentamente el proceso de abstracción. Así, luego de los primeros ejercicios donde se utilizan las bolitas como tales, se comienza a utilizarlas como representación de otros elementos. Se pueden presentar problemas donde haya flores, bananas, extraterrestres, piezas de ajedrez, aviones, y muchos otros elementos, todos los cuales van a estar representados por bolitas.
  El uso de procedimientos permite trabajar esto en diferentes niveles, pues un procedimiento que se llame PlantarFlor() puede conceptualizarse desde el punto de vista del problema, soslayando que en realidad pone una bolita roja (que representa a la flor). Así, si necesitamos ver que una flor es una bolita roja miramos el código del procedimiento (en el nivel inferior), pero si precisamos concentrarnos en la flor y olvidar la bolita, solo miramos su utilización (en el nivel superior).

  Para facilitar este proceso, las herramientas que implementan Gobstones pueden implementar mecanismos de ayuda. Actualmente, PyGobstones implementa el concepto de *vestimenta* que permite visualizar de manera clara esta representación, sin necesidad de tener que recurrir a la imaginación. Sin embargo, las vestimentas son solamente un agregado posterior al programa, y pueden quitarse en cualquier momento, verificando que el trabajo real sucede solamente sobre las bolitas. Entonces, con la vestimenta, veremos el gráfico de una flor, y sin ella, veremos que realmente hay una bolita roja.

  Es interesante observar que, si bien al comienzo los estudiantes solo piensan de manera concreta en las bolitas que pueden ver, no se dan cuenta del momento exacto en que dejan de pensar en concreto y se encuentran pensando en abstracto. Este proceso de adquisición de pensamiento abstracto continúa luego reemplazando gradualmente el tablero por estructuras de datos abstractas (en XGobstones)

Por lo expuesto, consideramos que las bolitas son una contribución enorme al enfoque didáctico Gobstones: permiten enseñar representación de información de manera gradual y amena. Si bien no son irremplazables, creemos que cualquier curso que implemente el enfoque didáctico Gobstones debería tener en cuenta este factor, y elegir un universo de discurso que permita manejar ambos niveles, el concreto y el abstracto, de manera simultánea, y sobre todo, gradual.

La representación de información es importante.

domingo, 15 de noviembre de 2015

6. No me dejan imprimir... (o "I/O considered harmful")

Las razones por las que NO se debe incluir E/S en un curso inicial.


  Una característica fundamental de Gobstones es que carece completamente de comandos de "entrada/salida" (o sea, comandos para leer información del teclado y para imprimir información por una pantalla -- excepto en el modo interactivo, pero ese es tema de otro post). Esta es una característica totalmente intencional.

   La razón fundamental para esta decisión tan controversial tiene que ver con la manera en que queremos que los programas sean comprendidos, y con una forma particular de pensarlos: según su naturaleza denotacional.
   Como hablamos en "La importancia de empezar por los procedimientos", los programas tienen dos formas de ser comprendidos:
  1. la *naturaleza operacional*, o sea, qué es un programa desde el punto de vista de la máquina
  2. la *naturaleza denotacional*, o sea, qué es un programa desde el punto de vista de las personas que lo leen.

   La naturaleza operacional permite entender a un programa como una secuencia de instrucciones compleja, y se focaliza en la forma en que el programa ejecuta, las formas concretas en las que la información se representa. Esta forma es compleja de entender para una persona cuando el programa tiene más de unas docenas de líneas, y es normalmente complejo tratar de deducir lo que un programa hace contenmplando solo esta forma. Sin embargo, es útil para, por ejemplo, poder hacerse una idea del tiempo que demandará ejecutar el programa.

   La naturaleza denotacional, por otra parte, permite entender a un programa como una transformación de información, y se focaliza en los efectos que el programa tendrá luego de completar su ejecución. Esta forma es normalmente la que es interesante para las personas, pues permite entender al programa como la solución a un problema (transformar cierta información en otra distinta) y analizar sus características, sin importar lo que las instrucciones individuales hagan. (Para los veteranos de la programación, esta forma se conoce usualmente con la denominación de "programa como caja negra", haciendo alusión a la caja negra de los aviones. Sin embargo creemos que esta denominación es inadecuada y confusa.)

   Volviendo al tema de este post, la posibilidad de poner comandos de entrada/salida (E/S) en un programa hace que el programador se focalice casi exclusivamente en la naturaleza operacional del mismo, olvidando o soslayando la naturaleza denotacional.
   Puesto que el objetivo del enfoque didáctico Gobstones es que los estudiantes de programación adquieran la capacidad de entender a sus programas como transformaciones de información, es necesario que los comandos de E/S no sean parte del repertorio de herramientas a utilizar.

   Para reemplazarlo, las herramientas que implementan Gobstones (PyGobstones, al momento de escribir este post) utilizan como mecanismo de comunicación la visualización del tablero antes de que corra el programa (*el tablero inicial*) y la visualización del mismo después que el programa finalizó (*el tablero final*). Esto permite destacar al programa como una forma de conseguir que el tablero inicial se transforme en el tablero final, sin que importe el orden en que los pasos individuales necesarios para lograr tal transformación son realizados.
   Creemos que la naturaleza denotacional de un programa requiere mayor aprendizaje y entrenamiento para ser adecuadamente comprendida que la naturaleza operacional. Por esa razón, los comandos de E/S, que enfatizan la segunda y dificultan la conceptualización de la primera, fueron removidos de Gobstones.

   Y esta es la razón fundamental para que Gobstones no tenga E/S: la secuencia Gobstones busca formar pensamiento de naturaleza denotacional, abstracta. Y para eso, la E/S es dañina.

  Continuaremos en futuros posts analizando las características de Gobstones.

domingo, 8 de noviembre de 2015

5. ¿Comando mata expresión?

La base aparentemente imperativa de Gobstones.


  Una cuestión de Gobstones que llama la atención a muchos expertos, especialmente en estos tiempos de programación funcional y programación con objetos, es el hecho de que su base es, en principio, imperativa, a través de comandos que modifican el estado del tablero.
   Sin embargo, Gobstones solo es imperativo en apariencia. La parte imperativa viene dada por los comandos, utilizados para describir acciones y modificaciones sobre el tablero (o sea, serían los "verbos" del lenguaje); pero Gobstones también tiene una parte importante del lenguaje dedicada a la descripción de valores y datos, de información: las expresiones (que serían los "sustantivos" del lenguaje).

  Con respecto a la parte imperativa del lenguaje, la misma tiene varias características que hacen que sea más simple de entender, y que permiten que los conceptos fundamentales se puedan aislar de los demás y así comprenderlos de manera separada del resto. Esto facilita el aprendizaje de dichos conceptos.  Por ejemplo, los parámetros en los procedimientos se entienden como un valor que se fija en cada invocación del procedimiento, y que permanece inmutable durante la ejecución resultante de dicha invocación. De esta manera, los parámetros se diferencian con claridad de las variables, concepto relacionado pero diferente (volveremos sobre este punto en futuros posts).
  También cada una de las formas de combinar comandos aparecen en una forma pura, y razonable para la secuncia didáctica: repetición simple (repeat), alternativa condicional (if-then-else), repetición indexada (foreach), alternativa indexada (switch) y repetición condicional (while), son las únicas formas de combinación (además de la secuencia y los procedimientos).
  Y para ser puros, los comandos no pueden devolver información, pues su única tarea es describir acciones, y no información.
  Por otra parte, las variables no representan espacios de memoria, sino que representan asociaciones temporales entre un valor y un nombre. Cuando se empiezan a agregar estructuras de datos (en XGobstones), las mismas se agregan con esa misma filosofía y eso hace que Gobstones no sea tan imperativo como puede parecer a primera vista.

  Con respecto a la descripción de información, se utilizan las expresiones y funciones, que son elementos puros (o sea, no modifican el tablero), lo que permite pensarlos de manera totalmente independiente de los comandos y procedimientos, y entender su utilidad para describir valores y datos. También volveremos sobre este punto en futuros posts.

  Esta clarísima separación entre "verbos" y "sustantivos" hace que el aprendizaje logrado con Gobstones sea transversal a los paradigmas. Si luego de aprender Gobstones, queremos que los estudiantes aprendan un paradigma funcional, simplemente nos concentramos en la parte de las expresiones, y dejamos los comandos completamente de lado. Si en cambio queremos que aprendan un lenguaje imperativo, dejamos las expresiones en 2do plano y nos concentramos en los comandos. Y si queremos que aprendan un lenguaje orientado a objetos, combinamos ambos, expresiones y comandos, incorporando los comandos como parte de los datos. 
  De esta forma conseguimos que Gobstones sea general y transversal a cualquier paradigma, cumpliendo así con uno de los objetivos originales, y mostrando que la separación de conceptos es fundamental para un aprendizaje como el propuesto.

   Es posible empezar con un lenguaje que no tenga estas características (por ejemplo, que tenga parámetros como espacios de memoria, otras formas de pasaje de parámetros, funciones con efectos, etc.) pero en nuestra experiencia es más complejo para los estudiantes comprender las ideas fundamentales cuando no aparecen en forma pura y además es luego más costoso enseñar a pensar con otros paradigmas.

  Por esa razón, si bien Gobstones tiene base aparentemente imperativa, la realidad es que su base es dual, y transversal; queremos resaltar que éste es uno de los elementos que hacen de Gobstones lo que es.

domingo, 1 de noviembre de 2015

4. ¿Qué me importan las bolitas?

El universo de discurso de Gobstones.

 

  Una de las características distintivas del lenguaje Gobstones es su universo de discurso: el tablero, las bolitas y el cabezal. En este post discutiremos el por qué de la elección de este universo, así como las desventajas de otros universos, tanto específicos (como puede ser el de Logo) como generales (como es el de los lenguajes de programación generales como Python, Java, etc.).

  Comencemos con una afirmación básica: para programar se necesita un autómata capaz de expresar soluciones a problemas de manera mecánica, y que este autómata sea reconfigurable a través de diferentes descripciones ejecutables (programas).

  En el caso de los lenguajes de propósitos generales tradicionales, el autómata es una computadora de arquitectura von Neumann (memoria y procesador), y las soluciones se expresan en términos de modificaciones a la memoria, que es donde los datos se expresan mediante representaciones abstractas.
  Este modelo, si bien poderoso, es demasiado abstracto para comenzar a aprender a programar (con consecuencias indeseables en la forma en que los estudiantes perciben la disciplina). Y puesto que el objetivo de la secuencia Gobstones es formar la capacidad de expresar abstracciones, comenzar con un modelo demasiado abstracto pone una barrera inicial muy alta, lo cual provoca frustración en los estudiantes. Es, entonces, casi una decisión obvia que se hace necesario un tipo de autómata más simple, con un universo de discurso más concreto.

  Ahora bien: ¿qué autómata y qué universo? Esta pregunta ha sido formulada muchas veces antes, y respondida de diversas maneras.

  Por ejemplo, en el caso del lenguaje Logo se decidió que el autómata fuese una "tortuga" que se podía desplazar tanto dejando una línea a su paso, como sin dejarla. De esta manera, las tareas a resolver son la realización de dibujos diversos. Este modelo es bien concreto, pero su problema fundamental es que es *demasiado* concreto: es complejo migrar de estos dibujos a representaciones más abstractas, además de que no hay una correspondencia clara con modelos más abstractos. Por otra parte, para la realización de dibujos de cierta complejidad hacen falta conocimientos básicos de geometría y no poca manipulación numérica.
  Es por ello que el modelo provisto por Logo también resulta inadecuado para comenzar a aprender a programar más allá de los rudimentos más básicos.

  También podemos considerar herramientas/lenguajes como Scratch o Alice, donde el universo de discurso viene dado por un "lienzo" (en 2 o 3 dimensiones, según la herramienta) donde se pueden combinar diversos "actores" (elegidos de una biblioteca predefinida). Las tareas ahora resultan más ricas, puesto que se pueden expresar dominios diversos en términos de los actores, y no dependen prácticamente de conocimientos previos de geometría o matemáticas (aunque ciertas tareas lo requieran, las mismas usualmente se pueden evitar al comienzo).
  Sin embargo, estos modelos también resultan demasiado concretos, pues las abstracciones ya vienen provistas, y el estudiante solo las manipula. Por otra parte, están pensados, en general, para guiar a los estudiantes a aprender el paradigma de orientación a objetos, lo cual, como establecí en posts anteriores (Por qué Gobstones es importante), no es lo suficientemente general (ya que otras formas poderosas de programación, como la Programación Funcional, no son fácilmente expresables en términos de objetos). Es por ello que también estos modelos resultan inadecuados.

  En Gobstones elegimos que el universo de discurso sea un tablero y bolitas, junto a una máquina, denominada "cabezal", que puede realizar modificaciones al tablero. De esta forma, las tareas se expresan en términos de bolitas sobre el tablero.

  ¿Qué ventajas proveen un tablero y bolitas? Decidimos usar este universo de discurso por varias razones:
  1. es lo suficientemente concreto para que los estudiantes se lo puedan imaginar con sencillez, aún sin tener desarrolladas formas avanzadas de pensamiento abstracto.
  2. es lo suficientemente abstracto para permitir su utilización en la representación de numerosos problemas de diversa índole.
  3. permite una transición gradual de formas e ideas concretas a formas e ideas abstractas.
  En su forma más concreta se lo puede entender de manera similar al lienzo de Logo, pero con la gran diferencia de que no se limita a eso y puede vérselo de otras maneras (además de que un tablero es mucho más "discreto" que un lienzo, que podría entenderse como más "analógico"). De hecho, dado un tablero suficientemente grande, Logo podría ser expresado en términos de Gobstones, pero con un tablero de Gobstones podemos expresar muchas otras cosas que no serían fáciles de expresar con un lienzo de Logo.
  En su forma más abstracta, el tablero puede entenderse como una memoria de computadora von Neumann, donde las bolitas codifican elementos abstractos.
  Sin embargo, la decisión de si se lo verá de manera concreta o abstracta no está prefijada, y es el docente el que elije en cada momento desde qué "distancia" (conceptual) se "mirará" el tablero. Además, es posible diseñar herramientas que ayuden en la adecuada manera de "mirar" y favorezcan la explicitación del uso de la abstracción (lo cual será tema de posts futuros).

  El último elemento del universo de discurso de Gobstones es el cabezal. Es el autómata que realiza las tareas. Sin embargo, esta máquina no se visualiza en ningún momento, favoreciendo el hecho de que la ejecución es un proceso abstracto y rara veces observable. Los programas deben razonarse por las transformaciones que producen sobre los elementos del universo de discurso (ya sean, o bien efectos sobre un estado, o bien transformaciones de información). La naturaleza del cabezal favorece este tipo de razonamiento (volveremos sobre este punto en futuros posts).

  Podrían proponerse quizás otros universos de discurso que sirviesen a los mismos objetivos. El enfoque didáctico de Gobstones no precisa de las bolitas de manera imprescindible. Sin embargo, sí es necesario un universo de discurso que posea las características enunciadas (suficientemente concreto, pero a la vez suficientemente abstracto) para que el enfoque didáctico Gobstones se manifieste en su máximo potencial. Nuestra decisión fue por la de un tablero y bolitas, y demostró ser extremadamente adecuada.

  En futuros posts continuaremos analizando las características que hacen que Gobstones importe.