Nonsense

(In Progress: Draft notes)

Llevo mucho tiempo dándole vueltas a esto. Y empiezo a tener bastantes ideas que van tomando diferentes formas pero empieza a ser necesario ir buscando un poco de orden, una estructura que englobe a todas ellas y les dé un sentido más claro y práctico.

Voy a empezar apuntando algunas de estas cosas aquí, sin un orden especial, para luego ir dándole la forma apropiada. Cuando lo tenga, creo que esto terminará siendo “mi legado”. Jojojo, qué pretencioso. Dejémoslo en que será una de las últimas cosas que intentaré aportar a esto de la programación. Que luego le sirva de algo a alguien o no… bueh, seguramente será no LOL

Programar es básicamente como escribir

Esta es la premisa mecánica básica. Programar es como escribir en ciertos aspectos. Programar bien es como escribir bien. Requiere un esfuerzo que va más allá de el simple hecho físico de teclear o pasar un lápiz sobre un papel. Podemos escribir con diferentes estilos. Hay estilos mejores y peores en el sentido de que consiguen mejor o peor su objetivo. Hay diferentes objetivos.

Escribir implica estructurar la narración. Hay diferentes estructuras que se pueden aplicar. Durante el proceso de escribir podemos mover bloques enteros a otros puntos de la estructura, a veces tal cual, a veces con algunos cambios.

Programar es básicamente comunicarse

Esta idea expresa varias perspectivas de forma conjunta. Programar, por un lado, es comunicarse con la máquina que estamos programando. Esa comunicación implica ciertas restricciones, como el lenguaje usado, el formato de la comunicación, las herramientas que usamos, etc. Por otro lado, programar es comunicar un contrato con otras personas. Es expresar por escrito la solución a la que hemos llegado para resolver un cierto problema. Lo ponemos por escrito y otras personas (o nosotros mismos en otros momentos del tiempo) pueden verificar, modificar, mejorar, añadir, evolucionar ese contrato.

Diferentes expresiones pueden comunicar el mismo concepto a la máquina, pero diferentes matices a las personas.

El lenguaje no sólo transmite conceptos si no también la representación de esos conceptos

A veces, esa representación puede llegar a tener más relevancia o efectos más relevantes que el propio concepto en sí. Para un mismo concepto, la representación que demos de él, puede influenciar el modo en que otras personas razonan sobre ese concepto. De nuevo, esto son diferentes estilos de escribir, pero también son diferentes palabras. El lenguaje, en general, produce intencionada o accidentalmente muchos sinónimos o cuasi-sinónimos, palabras que como mucho añaden pequeños matices o detalles a un mismo concepto.

Cuando comunicamos con diferentes personas o en diferentes contextos, usamos diferentes vocabularios

Una misma palabra puede tener diferentes significados o matices según el contexto en que la usemos o la persona a quien la dirijamos. Una misma expresión en un programa puede ser comprendida de diferente modo por diferentes personas.

No sólo eso. En diferentes contextos ciertas palabras serán apropiadas y otras palabras no. En ciertos contextos el uso de ciertas palabras o expresiones introduce ruidos y mensajes innecesarios para ese contexto.

Es habitual (e interesante) definir diferentes contextos en nuestros programas

Esta es una de las reglas fundamentales: modularidad. “Juntar lo que va junto y separar lo que va separado”. Es algo que admitimos como un buen objetivo a la hora de programar por motivos puramente prácticos y económicos (en el sentido más amplio de la palabra).

La modularidad implica la creación de diferentes contextos. A un nivel estructural alto (podríamos decir “a un nivel arquitectónico” pero… en fin, eso xD) definimos bloques y capas (3 o n), cebollas y hexágonos y otras simpáticas formas geométricas. Definimos, al fin y al cabo, contextos.

En diferentes contextos usamos diferentes vocabularios (sí, otra vez lo mismo)

Por tanto, lo que deberíamos definir a la hora de programar son los diferentes vocabularios, quizá incluso dialectos o nuestro slang propio de cada contexto.

El lenguaje del contexto

Lo que estoy pensando es en una estructura más o menos así para cada uno de esos bloques/contextos:

BASIC SCHEMA OF A CONTEXT EXPOSED API BLOCK LANG Other Blocks' APIs

Es decir, cada contexto, implementa una cierta lógica de su negociado y expone una determinada API con las funcionalidades que provee. Hasta ahí todo es lo habitual. Pero en lugar de consumir directamente las APIs proporcionadas por otros contextos, lo que hace es definir una fina capa de lenguaje. Esta tiene como objetivo establecer cuál será el vocabulario que se use en el contexto. Por esto mismo, las llamadas a otros bloques no son directas, sino que se hacen sólo desde la capa de vocabulario.

Me comenta Juanma el concepto de “capa anticorrupción” y sí, parece que encaja bastante con lo que estaba pensando. Aunque es un concepto más amplio. En este caso yo estoy pensando de forma bastante concreta en el vocabulario/lenguaje. Está claro que esto puede reflejar la corrupción de estar usando dependencias externas, pero no siempre es así. Lo que pretendo es restringir incluso el uso de vocabulario externo, lo cual influirá también directamente cosas como la nomenclatura. Pero sí, conceptualmente puede encajar como “capa anticorrupción”.

Javier me ha recordado las “capas de lenguaje” de Lisp. Recuerdo por ahí un artículo con algún título como “qué significa sintaxis en Lisp” o algo así. No quiero tampoco crear un lenguaje como tal, llenar la aplicación con n DSLs. Quizá debería eliminar la palabra lenguaje e insistir sobre vocabulario. He recordado también lo que decía de Haskell, pero… mmm… bueno, no tengo claro que sea lo que pretendo pero miraré alguna cosa más.

Para explicar estas cosas, claramente necesito un proyecto de ejemplo

En el ejemplo deberá poder apreciarse no sólo que diferentes contextos usan diferentes vocabularios, sino que no usan los vocabularios de otros contextos.

Relación con la Programación Funcional

O con lo que sea que yo llamo programación funcional, claro. Porque mi definición puede no ser la habitual.

La idea es que intuyo que la construcción de estos lenguajes y vocabularios se verá tremendamente favorecida por el uso de técnicas funcionales, principalmente la composición de funciones (y posiblemente de tipos). Pero aún así esto lo veo sólo como un buen complemento, una buena forma de orientar la implementación. No dudo que se puede llegar a soluciones razonablemente válidas con una orientación a objetos.

(In Progress)