Introducción

A lo largo de los años, mientras iba aprendiendo a programar, me di cuenta de que me atraían algunos temas más que otros. Es lo normal, a cada uno nos gustan más ciertos aspectos de la programación que otros. En mi caso hay toda una serie de temas que me gustan. Temas de expresión y de lenguajes, temas de aprendizaje y de enseñanza, temas sobre por qué hacemos las cosas y para qué, y también algunos temas sobre lo que significa programar, pensar y solucionar problemas.

Además de esto, la oportunidad que he tenido de conocer a bastantes programadores por el camino y de poder acceder a bastantes libros y recursos de formación, me ha dejado clara una idea: Existe una notable escasez de literatura que se centre en el que probablemente sea uno de los pasos más complicados en el desarrollo de las habilidades de un programador. Hay mucho, muchísimo escrito mirando hacia temas básicos. Sintaxis y gramática de lenguajes de programación, conceptos fundamentales, paradigmas generales... Por otro lado, quizá no sea tan abundante pero también existe una cantidad apreciable de contenido avanzado y específico.

Sin embargo, entre un punto y otro, me he encontrado a demasiados programadores que se encuentran con la misma dificultad -con muy ligeras variaciones-. Esto se refleja en preguntas como "Una vez montado sí lo veo, pero, ¿cómo empezaría un proyecto desde cero? ¿Cómo lo oriento?" o como "Entiendo los conceptos y una vez vista la solución, comprendo por qué funciona y todo, pero ¿cómo se te llega a ocurrir esa solución?". Y esto no es un problema solo para programadores con poca experiencia. En bastantes ocasiones, he visto cómo programadores que aparentemente llevaban bastantes años y, en principio, sabían "hacer cosas" razonablemente bien, encontraban una gran dificultad en enfrentarse a situaciones nuevas.

En mi opinión, lo que ocurre es que, como decía, falta literatura que se centre en programar más allá de escribir código o incluso de diseñar arquitecturas. Falta, aunque alguna hay, una guía que enseñe a pensar como un programador. Es decir, que explique cómo enfrentarnos a los problemas y cómo encontrar las soluciones.

Tomando como punto de partida una cita sobre programación que me gusta particularmente

Primero resuelve el problema. Luego escribe el código.
-- John Johnson

necesitamos un modo de aprender a resolver el problema. Hay millones de palabras sobre cómo escribir el código, que, en el fondo, debería ser casi una banalidad.

¿A quién está dirigido este libro?

Como se puede deducir de lo anterior, este "libro" está especialmente dedicado a todos aquellos programadores que se encuentran en esa situación de dificultad. Diría que el perfil típico es el de alguien que tiene ya unos conocimientos básicos generales de programación. Alguien que conoce un lenguaje -o quizá en algún caso más de uno- y lo maneja con cierta rutina. Pero a la vez, se limita bastante:

  • a trabajar dentro de un equipo en un proyecto de duración media o larga, donde generalmente se defiende siguiendo pautas establecidas ya por otros.
  • a repetir proyectos pequeños o medianos, siempre de características bastante similares, porque es lo que conoce.
  • a seguir tutoriales (webs, vídeos, etc) que explican cómo hacer prácticamente cualquier cosa nueva con la que se encuentra.
  • a aplicar una serie de buenas prácticas o utilizar buenas herramientas porque son las que están establecidas pero sin tener una idea realmente clara sobre de dónde surgen esas prácticas o por qué esas y no otras.

Todo esto, no es necesariamente malo. Una persona puede trabajar así, de una forma más o menos mecánica, con un conocimiento más o menos detallado de lo que está haciendo, durante muchos años y es una forma razonable de ganarse la vida.

Este libro a quien está realmente dirigido es a quien, en esta situación o en una parecida, se da cuenta y decide que quiere, que necesita, algo más. Que quiere ser capaz de dar el siguiente paso en la programación, pasando de lo que describimos más mecánicamente como "escribir código" -código que funciona, por qué no- a realmente "solucionar problemas".

Como es lógico, existe la posibilidad de que el libro pueda ser útil también para personas en otras situaciones. Quizá, por ejemplo, puede servir también a quien viniendo de alguna otra disciplina afín o trabajando con programadores, quiera comprender mejor en qué consiste realmente el desarrollo de software y dónde se encuentran las dificultades. También puede servir a quien haya tenido una formación relativamente mecanicista sobre programación. Sé que existen, por ejemplo, bastantes cursos y programas de formación que pretenden enseñar a programar en unos pocos meses o incluso semanas. Sin entrar a valorar la calidad de ninguno de dichos programas, mi opinión es que la formación que dan en general es bastante superficial y sobre todo está centrada en cómo escribir código. Estos cursos pueden, en algún caso, ser un buen primer paso, pero claramente no pasan de ahí y necesitan una continuación más sólida.

Por supuesto, este libro también puede resultar interesante para quien le guste reflexionar sobre estos mismos temas, sobre cómo pensamos y porqué tomamos unas u otras decisiones. Espero que sea un libro suficientemente entretenido.

Por otro lado, nada garantiza que ningún contenido de este libro resulte de interés específico para ninguna persona concreta. Si te decides a leer y no encuentras nada que te sirva o te interese, 仕方ないわね, es lo que hay, no puedo hacer mucho más. Ahora bien, si crees que encajas en la descripción, si crees que este libro te debería servir a ti, pero que, por el motivo que sea no lo hace, no dudes en ponerte en contacto. Puedes dejar un comentario en un capítulo concreto si hay algo en particular que no te quede claro o que eches en falta, o puedes enviarme un mail si el problema es más amplio o quieres que añada algún tema que no encuentres aquí.

Sobre el aprendizaje

Durante este último año he hecho más o menos unos 2500 sudokus. Es una especie de experimento conmigo mismo. Es cierto que ya antes los resolvía como entretenimiento, pero esta vez tenía una intención más concreta y quise empezar lo más "desde cero" posible.

Cuando empiezas a resolver sudokus, parecen un poco una trampa. Las reglas en sí son muy sencillas de entender, pero lanzarse así sin más, sin pensar un poco, probablemente no es una buena idea. Lo primero porque hay sudokus con muy diferentes niveles de dificultad, y segundo porque en apariencia el problema puede parecer mucho más complicado de lo que es. Resolver sudokus es tremendamente mecánico; tiene mucho menos "razonamiento" de lo que muchos creen.

Precisamente por eso eran un ejercicio muy bueno para el experimento que quería hacer. Cuando empiezas a resolver sudokus puedes, si quieres, sí, lanzarte sin más pero o bien esta fase te dura poco o bien nunca vas a salir de ella. Si no sigues una metodología, puede que mejores tu velocidad con el tiempo, sí, pero nunca vas a pasar de nivel, por decirlo de alguna forma.

Normalmente lo que ocurre es que aprendes rápido las técnicas más básicas y fundamentales. Son las técnicas más básicas de eliminación de opciones. De hecho, lo que son en sí, son las propias reglas del sudoku -que no se pueden repetir los números por fila, columna o bloque- pero que ahora aplicas con un orden, como una técnica. Y en relativamente poco tiempo las estás aplicando y usando de una forma natural, casi instintiva. Estas técnicas básicas te permiten resolver con soltura los sudokus más fáciles y con un poco más de esfuerzo los del siguiente nivel.

De nuevo, puede que no pases de ahí. Como digo es suficiente para resolver un buen número de sudokus y tiene una cosa interesante: Te quita los sudokus más facilones, lo más básicos... los más aburridos. Y a la vez te da lo justo suficiente para que los siguientes, que ya tienen algo más de reto, sean asequibles. No fáciles, porque eso se haría aburrido, pero sí asequibles. Con algo de esfuerzo mental puedes tener entretenimiento para bastante rato.

Para seguir avanzando, lo que necesitas es aprender nuevas técnicas, un poco más complejas, un poco más avanzadas. En el sudoku en concreto hay un par de técnicas iniciales que son muy sencillas y se derivan casi directamente de las reglas. Las aprendes a aplicar con soltura y avanzas un poco más de nivel. Luego hay otras técnicas que son, ahora sí, más avanzadas. En realidad no son mucho más avanzadas pero sí son cualitativamente más avanzadas porque se basan en algo diferente: La exclusión por grupos. Bueno, no quiero tampoco profundizar mucho en el sudoku en sí mismo, pero son unas técnicas de un carácter diferente. Requieren más atención y esfuerzo para aplicarlas y no siempre se da el caso de que te sirvan.

El hecho de ser cualitativamente distintas, hacen que haya un salto igualmente cualitativo en tu capacidad para resolver sudokus. Puede que nunca las aprendas y entonces nunca des ese salto. O, para ser más precisos, puede que aprendas una -o dos- de estas técnicas y des un paso cualitativo pero pequeño. O que vayas aprendiendo más y des más pasos. Puede también que aprendas la abstracción, la generalidad que hay detrás de estas otras técnicas y entonces el paso cualitativo sea completo. Esto te soluciona todo un nuevo campo de sudokus y te abre el camino al siguiente nivel de dificultad.

Existe un salto más en el sudoku y es que llegados a un cierto nivel de dificultad, lamentablemente, ninguna de las técnicas anteriores lo puede resolver todo. Hay sudokus que únicamente puedes resolver haciendo hipótesis y probando si son correctas, y volviendo atrás cuando resultan no serlo.

Todo este proceso de aprendizaje nos enseña algunas cosas que creo que son interesantes y que creo también que son muy similares al proceso que seguimos para aprender y mejorar en la programación.

  • Es importante practicar. Y es importante hacerlo con frecuencia y con atención. Si no practicamos, nunca vamos a aprender. Pero además, si no practicamos prestando atención, fijándonos conscientemente en cómo estamos haciendo las cosas, entonces podremos resolver problemas pero no vamos a aprender a hacer las cosas de un modo mejor.
  • Hay que aprender las reglas y las técnicas. Hay que entenderlas y hay que practicarlas hasta que se vuelven algo natural, algo que no solo sabemos y entendemos, sino algo que conocemos de forma íntima, algo que forma parte de cómo hacemos las cosas. Resolviendo sudokus llega un momento en que incluso la vista termina encontrando ciertos patrones que te indican puntos donde "atacar". Además, puedes leer sobre estas técnicas. Están por ahí en internet, seguro. Pero eso no basta. Leer sobre esas técnicas solo te da el conocimiento más genérico de las mismas. Solo cuando haces tuyas esas técnicas, cuando las interiorizas, cuando llegas a comprenderlas y conocerlas de forma íntima, es cuando realmente llegas a manejarlas bien.
  • Hay siempre, en el proceso de aprendizaje, saltos cualitativos y son, a la vez, los más costosos de dar y los más interesantes. Estos suelen implicar la necesidad de aprender algún concepto nuevo, no solo "hacer mejor lo que ya haces". Estos saltos requieren un esfuerzo mayor de nuestra forma de pensar y además un nuevo periodo de aprendizaje y práctica hasta que lleguemos a conocer íntimamente de nuevo esas nuevas ideas.
  • Casi siempre unas ideas construyen sobre las anteriores. Y a veces esto significa que aplicamos directamente las técnicas "avanzadas" y estas ya implican en sí mismas a las que quedan por debajo. Nos sale natural aplicar las técnicas avanzadas y entonces podemos llegar a creer que las simples ya no las necesitamos. Esto no es así. Por un lado por lo ya dicho, las estamos aplicando de forma implícita. Pero también porque en muchas ocasiones, seguirá siendo necesario aplicar las técnicas simples por sí mismas. Siguen siendo útiles y no las olvidamos.
  • Finalmente hay algunas cosas que hay que probarlas. Esto no significa en absoluto que tengas que descartar las cosas que sabes, las técnicas que manejas. Lo que significa es que hay ocasiones en que necesitas, además de tus técnicas y conocimientos y demás, hacer hipótesis y comprobarlas. Sigue siendo un proceso metódico y ordenado, pero ahora, añadiendo ciertos riesgos. Si intentas resolver un sudoku de los muy difíciles olvidando todas las ideas anteriores y simplemente probando, lo más probable es que no lo consigas. En lugar de eso, se trata de hacer la hipótesis más pequeña que puedas, y validar si funciona lo más pronto posible y, siempre, de forma ordenada.

Todo esto recoge bastante bien, creo yo, cuál es la intención de todo lo que viene a continuación. Enlazando con la sección anterior, este libro está dirigido principalmente a quien conoce ya y maneja con soltura esas primeras técnicas más básicas (sintaxis, conceptos básicos generales, un lenguaje de programación...). Pero más aún, está dirigido a personas que estén dispuestas a hacer el esfuerzo necesario para poder dar saltos cualitativos en sus formas de hacer y para quienes quieran hacerlo de una forma consciente y atenta. Se trata, insisto, mucho más de aprender a pensar en programar que al hecho mecánico de programar en sí mismo.

Estructura y contenido

Antes que definir el contenido del libro, quiero señalar que veremos poco código. O, mejor dicho, veremos una cantidad razonable código, pero cuando lo hagamos siempre será para presentar la expresión de alguna idea. Saber escribir código es un requisito que asumiré en el lector y no nos pararemos a explicar el significado de una determinada sintaxis, el funcionamiento de una función particular o el uso de un API.

Aviso que la mayoría de ejemplos en los que aparezca código estarán escritos o bien en JavaScript o bien en algún tipo de pseudo-código, que ni siquiera nos molestaremos en definir formalmente. Personalmente creo que el uso de un pseudo-lenguaje informal puede encajar bien con el objetivo del libro. En cualquier caso, esto es algo que iré viendo por el camino.

Es bastante probable que, de vez en cuando, algún trozo de código esté escrito en otros lenguajes. La elección de JavaScript como base no responde a ninguna preferencia en particular, sino a que considero que, hoy en día, podemos tomarlo casi como una especie de lingua franca. Quien más y quien menos ha tenido que trabajar en alguna ocasión con él. Y para quien no, la sintaxis es suficientemente sencilla y familiar como para que no sea una dificultad. Sin embargo, en ocasiones, las características de JavaScript a veces no serán las mejores para expresar ciertas ideas. De ahí el uso ocasional de otros lenguajes. En cualquier caso, creo que por la naturaleza de los temas a tratar, precisamente el uso de uno u otro lenguajes no debería tener demasiada relevancia.

En cuanto a la estructura del libro, la idea inicial es la de seguir el desarrollo de un proyecto de principio a fin... O al menos esa era la idea inicial. En realidad, creo que aunque seguiremos esa vía, será mejor no hacerlo sobre un único proyecto, ya que un único proyecto puede no adaptarse a todos los asuntos que quiero tratar. Así, he pensado en tener tres, quizá cuatro, proyectos, de diferente alcance y complejidad, que puedan cubrir más temas y más variados. También el poder tener proyectos diferentes nos ayudará a poder ver diferencias en nuestros razonamientos dependiendo de las circunstancias.

El recorrido del libro va a ser una experiencia bastante personal. No solo personal para mi, que intentaré volcar mi cerebro sobre palabras, sino que la actividad de pensar, que es lo que vamos a tratar, es algo fundamentalmente personal. Como ya sabemos desarrollar software también incluye otras actividades mucho más sociales (comunicación, coordinación, compromisos...). Posiblemente roce puntualmente algunos de estos temas en lo que implican a nivel personal, pero no tengo intención de incluir temas que considero son fundamentalmente empresariales. Es decir, que no tengo interés en hablar de metodologías organizativas, de gestión de equipos, de técnicas de producción.

Sobre la terminología técnica

No tengo un interés demasiado significativo en que este libro contenga una terminología técnica especialmente precisa. Como es lógico, intentaré siempre usar los términos técnicos correctos y creo que aprender y manejar estos términos es importante. Sin embargo, el foco del libro está mucho más concentrado en las ideas y conceptos, y en cómo pensamos a la hora de programar.

Por esta razón, cuando haya necesidad de hacer referencia a un término técnico la haré, pero es mi intención que las explicaciones que dé casi siempre empiecen utilizando un lenguaje más accesible, más centrado en qué es cada cosa, que en utilizar uno u otro término. Sobre todo me disgustaría que por utilizar un determinado término, asuma yo que tú como lector ya lo conoces o ya sabes a qué me refiero.

Por supuesto, que, insisto, es importante aprender a manejar estos términos, especialmente para comunicar con otros programadores, pero, insisto también, son más importantes los propios conceptos e ideas que esos términos representan.

Los proyectos

A lo largo del libro se usan algunos proyectos como ejemplo. La mayoría serán pequeños juegos o proyectos sencillos que resultarán familiares al lector -espero-. Incluiré, siempre que sea necesario, una descripción de cada uno de ellos en el apéndice. Se pueden tomar como ideas para hacer ejercicios, ya que seguramente no los resolveré de forma completa.

Además de eso, en la segunda parte del libro intentaré plantear un proyecto más amplio, más completo. Con casi total seguridad, será un juego de mesa de varios jugadores, sin una carga gráfica demasiado intensa. El juego probablemente sea Espías y Confidentes, el Cluedo, Monopoly o Trivial Pursuit.

¿Quién soy yo?

Hasta ahora, cuando he escrito alguna cosa o he estado enseñando a alguien algún tema, nunca he dado mayor importancia a quién era yo, a por qué era yo quien enseñaba o si yo tenía la capacidad para escribir sobre esos temas. Esto no va a cambiar mucho en esta ocasión. Sinceramente no creo que ni mi experiencia, ni mi capacidad o conocimiento sean particularmente destacables o diferentes a las de otros.

Sin embargo, visto cómo el libro se pretende centrar mucho en "pensar", creo que es conveniente aclarar algún detalle. Como es obvio, el libro terminará reflejando en buena medida una forma concreta -entre muchas- de pensar y de hacer las cosas: la mía. Así que supongo que es conveniente por lo menos, a modo de aviso, explicar de dónde viene esa forma mía de pensar.

Mi formación es de Ingeniero en Automatización y Electrónica Industrial. Podría decir que llevo programando desde los X años, o desde que era niño, pero es irrelevante y, además, seguramente mentiría porque no lo recuerdo con tanta precisión y estoy seguro que en esa época lo que hacía con el ordenador era poco más que trastear y hacer el tonto.

Algo más relevante es que llevo unos 25 años programando en entornos bastante variados. Mi formación es bastante autodidacta. No totalmente, porque en la carrera algo de C, Pascal, Ada y ensamblador aprendí. Y también tuve algunas asignaturas sobre diversos temas de computación. Pero al margen de esto, he tenido que aprender muchas cosas por mi cuenta, y aquí es donde viene lo relevante: A lo largo de los años he tenido la suerte de poder leer bastante y, por suerte o por lo que sea, he tenido la oportunidad de acceder a una mezcla bastante variada de autores "clásicos" y modernos. Esto creo que es una de las cosas que me ha dado una visión más amplia de lo que supone programar. Y comento esto no como algo especial o positivo sobre mi, sino para que se entienda de dónde vienen las cosas en las que creo. De libros viejos y de libros aburridos xD

Por último añado sobre mi que soy una persona bastante crítica en especial con charlatanes, vendedores de humo, y con algunas ideas que mucha gente acepta como buenas. Tengo mis propias ideas sobre lo que creo que es bueno y correcto y tengo algunos valores personales que me importan a mi. No tengo intención de tratar temas que no están directamente relacionados con el objetivo principal. Es muy probable que en algunos momentos incluya comentarios basados en estas creencias que tengo y, quizá, deje de lado o no dé apenas relevancia a metodologías o técnicas que muchos consideran importantes, incluso algunas que yo mismo considero interesantes pero que forman parte de otra cosa más cercana a la gestión de proyectos. El lector es libre de no compartir mis ideas, evidentemente; pero creo que puede ser bueno, como mínimo, plantear algunas de estas cuestiones para que cada uno las medite y saque sus propias conclusiones.