7 puntos por GN⁺ 2023-12-27 | 1 comentarios | Compartir por WhatsApp
  • Si es difícil elegir un proyecto personal, un editor de texto, un juego 2D, un compilador o un mini sistema operativo son buenos puntos de partida, porque cuanto más veces los construyes, más amplio es lo que aprendes
  • Un editor de texto te hace implementar por tu cuenta la estructura para guardar documentos, el comportamiento del cursor, deshacer/rehacer y el ajuste de línea, lo que ayuda a aprender estructuras de datos y abstracción
  • Incluso un juego 2D simple como Space Invaders revela la estructura básica de la programación de juegos: renderizado, manejo de entrada, game loop, gestión del estado de objetos, IA de enemigos, sonido, shaders y hasta redes
  • Un compilador de Tiny BASIC y un mini sistema operativo te hacen trabajar directamente con conceptos de bajo nivel como lexing, parsing, análisis semántico y generación de código; o compilación cruzada, bootloading, gestión de memoria y scheduling
  • Las hojas de cálculo y los emuladores de consola combinan la dificultad de los proyectos anteriores y se expanden hasta la etapa de construir incluso una máquina virtual que imite el funcionamiento real

Proyectos que vale la pena construir una y otra vez

  • Si necesitas un proyecto personal o quieres aprender un nuevo lenguaje o framework, puedes hacer el mismo proyecto varias veces y aun así aprender algo distinto en cada intento
  • Los proyectos recomendados difieren entre sí en dificultad y áreas de aprendizaje
    • Editor de texto: estructuras de datos, comportamiento del cursor, deshacer/rehacer, representación en pantalla
    • Juego 2D: renderizado, manejo de entrada, game loop, objetos y gestión de estado
    • Compilador: lexing, parsing, análisis semántico, generación de código
    • Mini sistema operativo: arranque, gestión de memoria, scheduling, sistema de archivos
    • Hojas de cálculo y emuladores de consola: combinan los conceptos de los proyectos anteriores en una estructura más grande

Editor de texto

  • Un editor de texto es una herramienta que usamos todos los días, pero si lo implementas directamente sin un componente básico de caja de texto, tendrás que lidiar con los detalles de mover el cursor, seleccionar, insertar y borrar
  • El mayor reto es cómo almacenar el documento de texto en memoria
    • Un arreglo simple tiene mal rendimiento cuando insertas texto en una posición que no sea el final del documento
    • Algunas estructuras para comparar son arreglo, rope, gap buffer y piece table
  • El cursor no se mueve solo hacia arriba y abajo
    • Si te mueves a una línea corta, va a la posición posible, y cuando más adelante aparece una línea lo bastante larga, intenta volver a la columna original: ese comportamiento de memoria de columna
  • Después del editor básico, puedes agregar deshacer/rehacer y ajuste de línea
    • Deshacer/rehacer te lleva a comparar diseños como arreglo de estados previos, patrón memento o patrón command
    • El ajuste de línea obliga a separar la representación visual de las líneas de texto de su representación en memoria
  • Material de referencia

Juego 2D - Space Invaders

  • Incluso un juego simple requiere estructuras de datos y patrones de diseño propios
  • En lugar de un gran motor de juegos, usar una librería básica de gráficos 2D como SDL, SFML o PyGame evita que las partes interesantes queden ocultas
  • El juego crea el efecto de movimiento borrando la pantalla y redibujando rápidamente cada elemento
  • El flujo real sigue una estructura que repite renderizado, recepción de entrada del usuario y procesamiento de la lógica del juego dentro del game loop
  • El manejo de entrada debe considerar detalles como la primera pulsación de una tecla o botón del mouse, mantenerlo presionado, soltarlo o hacer doble clic
    • Si solo revisas la entrada todo el tiempo, el resto del juego queda detenido
  • También hay que manejar directamente los objetos del juego y su estado
    • Para crear enemigos que aumentan dinámicamente, puede ayudar el factory pattern
    • A la IA de los enemigos se le puede aplicar una máquina de estados
  • Después del juego básico, puedes agregar menú de título, pantalla de game over, lógica para que corra a la misma velocidad en distintas computadoras y una IA enemiga más interesante
  • Si quieres expandirlo más, puedes implementar efectos de shaders, sonido y multijugador en línea
  • Material de referencia

Compilador - Tiny BASIC

Mini sistema operativo

  • Los algoritmos y estructuras de datos de un sistema operativo pueden parecer abstractos o inútiles en el aula, pero también se pueden aplicar en muchas otras áreas, como juegos o modelos para predecir el comportamiento humano
  • Implementarlo por tu cuenta te da una comprensión más profunda de lo que pasa dentro de un sistema operativo
  • Por su dependencia del hardware, hay una barrera de entrada y una curva de aprendizaje, pero si sigues un libro o tutorial puedes crear un OS booteable capaz de ejecutar programas hechos por ti
  • Los temas de aprendizaje son los siguientes
  • Material de referencia

Proyectos más difíciles: hojas de cálculo y emuladores de consola

  • Una aplicación de hoja de cálculo, como Excel, combina los retos de un editor de texto con los de un compilador
    • Hay que representar el contenido de las celdas en memoria
    • Hay que implementar un intérprete para el lenguaje de programación usado en las fórmulas
  • Material de referencia para hojas de cálculo
  • Un emulador de consola de videojuegos es un proyecto que junta en uno solo la dificultad de implementar compiladores, sistemas operativos y motores de juego
  • Para emular una consola real, necesitas escribir una máquina virtual que se comporte como la CPU y otros componentes de hardware
    • En esta máquina virtual se pueden ejecutar juegos para esa consola
  • Como punto de partida, se recomienda emular la consola virtual CHIP-8, que es más simple que una consola real
  • También se pueden emular NES, SNES, Gameboy y Gameboy Advance, y hay bastante documentación y emuladores open source, pero cada consola tiene particularidades interesantes
    • Ciertos juegos pueden depender de bugs o funciones no documentadas de hardware específico
  • PICO-8 se convirtió en una consola “fantasy” rentable
  • Material de referencia para emuladores

Proyectos sugeridos adicionalmente

  • Se reunieron más ideas de proyectos desde Hacker News, Reddit, Twitter y correo electrónico
    • una base de datos hecha desde cero
    • un ray tracer
    • un clon de MS Paint
    • un editor de gráficos vectoriales
    • un decodificador de imágenes
    • una web app de sala de chat
    • una calculadora de dígitos de pi
    • utilidades generales de terminal como grep
    • cliente y servidor FTP

1 comentarios

 
GN⁺ 2023-12-27
Opiniones de Hacker News
  • Crear un editor de texto, un compilador, un sistema operativo o un ray tracer puede convertirte en mejor programador, pero no necesariamente en mejor ingeniero de software.
    Más bien, podrías interiorizar la desastrosa doctrina de “Not Invented Here” y terminar peor en ingeniería de software.
    Los hackers se obsesionan con teorías avanzadas como la notación Big O, las estructuras de datos y HoTT, pero casi no se discuten ni se practican cosas esenciales para la ingeniería real: “decidir qué hacer uno mismo y qué resolver con una biblioteca”, “identificar buenas bibliotecas y frameworks”, “juzgar dónde vale la pena optimizar”, “escribir código que siga siendo legible años después” y “ver un proyecto como un sistema complejo a gran escala, incluidas dependencias de software y no software”.
    Por eso, como tarea alternativa, propongo un motor de búsqueda web. Cosas como los algoritmos de coincidencia de cadenas ya las hicieron otros, así que no te preocupes por eso; al principio basta con “simplemente” crear un motor de búsqueda y un crawler que funcionen de verdad, aunque solo soporten una parte de la web y 1 usuario concurrente.

    • No veo por qué un motor de búsqueda exigiría especialmente “habilidades reales de ingeniería”, como elegir bibliotecas o identificar oportunidades de optimización.
      Un editor de texto, un compilador, un sistema operativo o un ray tracer también pueden entrenar todas esas mismas actividades.
      Habiendo trabajado en un ray tracer usado en varias películas de largometraje, puedo decir que todos los puntos mencionados arriba también aplicaban a ese proyecto.
      Al final, parece más una diferencia entre hacer algo pequeño y divertido, o aplicar tal cual las restricciones desmoralizantes por las que te pagan en una empresa y quitarle toda la diversión.
    • Ese consejo suena razonable, pero tiene problemas cuando se crea software solo con bloques de construcción ya preparados.
      Primero, los bloques ya preparados suelen ser mucho más malos que buenos, y como resultado el software también refleja esa mala calidad; la vida deja de ser usar software y pasa a ser mantener y apaciguar esas cosas malas.
      Segundo, aunque los bloques sean de buena calidad, limitan el tipo de software que se puede hacer. Idealmente, uno debería imaginar el comportamiento que quiere, escribir software para que lo haga y, en el proceso, crear los bloques.
      Si solo usas bloques ya preparados, directamente no puedes crear buena parte del software excelente; de hecho, creo que esa es una razón por la que no hay mucho software excelente a nuestro alrededor.
      Si estás creando “software casi igual al de siempre”, el segundo problema aplica menos, y el primero quizá sea manejable porque principalmente usas el camino feliz. Pero ese tipo de software pronto lo usará una IA, no una persona.
    • Es parecido a decirle a un estudiante de música que no practique escalas ni estudios porque en una orquesta se necesitan otras habilidades.
      Esas habilidades también son importantes, pero en algún momento hay que desarrollar fundamentos, y convertirse en mejor programador claramente ayuda en todo el conjunto de habilidades enumeradas arriba.
    • El artículo decía programador, no ingeniero de software.
      Personalmente, la ingeniería de software es lo que hago para pagar las cuentas; la programación es algo que empecé porque era divertido.
      Los proyectos de este artículo son del tipo que me gustaría hacer por diversión si tuviera tiempo.
  • Desde una perspectiva de UI/Web, además de una hoja de cálculo, que es muy útil para entender los sistemas de flujo de datos, recomendaría lo siguiente:
    Crear un videojuego simple con Unity o Unreal te ayuda a entender las restricciones de rendimiento en juegos donde 30–60 fps importan, y también sirve para crear interfaces rápidas en otros lugares, incluida la web.
    Crear un framework JavaScript simple parecido a React ayuda a entender el flujo de datos y el manejo de eventos.
    Crear tú mismo una biblioteca HTTP que envuelva XMLHTTPRequest te permite entender desde cero cómo se envían y se leen las solicitudes HTTP, aunque hoy exista fetch, y más adelante ayuda a depurar problemas de CORS o solicitudes OPTIONS.

    • Para este propósito, Godot quizá sea una alternativa mejor que Unity o Unreal. No solo no tienes que caer en licencias propietarias, sino que además puedes ver qué ocurre internamente.
  • También se discutió en ese momento.
    Challenging projects every programmer should try - https://news.ycombinator.com/item?id=21790779 - Dec 2019 (297 comments)
    También hay un artículo relacionado.
    More challenging projects every programmer should try - https://news.ycombinator.com/item?id=25489879 - Dec 2020 (223 comments)

    • El enlace externo del segundo artículo da 404.
  • +1 al mini sistema operativo.
    Los desarrolladores de aplicaciones dependen de muchas funciones del sistema operativo, como la gestión de memoria y el sistema de archivos, y tarde o temprano uno se pregunta: “¿cómo funcionan estas cosas por detrás?”.
    Por eso, en mi tiempo libre estuve trasteando con xv6(https://github.com/mit-pdos/xv6-public).
    Aprender varios algoritmos de planificación de procesos en un libro de texto y implementarlos uno mismo son cosas completamente distintas, y aprendí mucho.
    Como desarrollador de apps móviles, la probabilidad de que este conocimiento esté relacionado con mi trabajo es casi 0, pero sin duda es divertido.

  • Haber desarrollado un juego 2D sin motor fue la experiencia más aleccionadora para darme cuenta de lo absurdamente rápidas que se han vuelto las computadoras.
    Aunque hagas algo que estás seguro de que va a ser demasiado lento, incluso en un Game Boy hay un millón de operaciones por segundo, así que simplemente corre. Resulta que un millón es un número más grande de lo que uno cree.
    Pasas de decir “espera, ¿busca y dibuja todos los sprites cada vez? ¿No hay un cálculo diferencial inteligente que sepa solo lo que hay que cambiar, ni un segundo búfer que use el frame anterior para reducir trabajo?”, y luego te sorprendes aún más al ver juegos mucho más complejos que sí empezaron a usar esas técnicas.

    • Antes también había trucos interesantes, tanto en las aplicaciones como en el hardware, para ayudar con este tipo de problemas.
      Por ejemplo, un atlas de sprites es una forma típica en que se usa este tipo de estructura de datos. No tiene sentido subir cada vez varios sprites que normalmente se renderizan de forma predecible; subes una sola imagen grande y muestreas una parte de ella.
      Para los estándares actuales, sí. Con hardware comercial de gama baja, incluso sin ser una PC gamer, casi cualquier cosa de hace unos 15 años se puede manejar con renderizado bruto de dibujar y redibujar la escena.
    • Empecé haciendo juegos 2D en una TRS-80 Color Computer, y eso me dio una buena base para entender las computadoras.
      Como era hardware puro y ensamblador, había que manejar manualmente gráficos, sonido, entrada, gestión de memoria, etc.
      Creo que una introducción ideal sería un entorno simplificado donde un programador principiante pueda encargarse de todo eso para crear un juego 2D, pero sin la carga excesiva necesaria para hacerlo funcionar.
  • Si crees que necesitas el patrón factory para hacer Space Invaders, algo anda mal.
    Me parece muy poco probable que el original tuviera conceptos de diseño como ese.

    • Es el resultado de 30 años de programación orientada a objetos y patrones de diseño.
      Cuando tu cerebro se infecta con eso, empieza a buscar formas de propagar la infección.
    • En ninguna parte del artículo se dice ni se insinúa que haga falta el patrón factory para implementar Space Invaders.
      ¿Leímos artículos distintos?
  • Me gustaría hacer algo mucho más físico, como una simulación precisa de dinámica de vuelo para robots, drones con piloto automático o naves espaciales con parámetros GNC programables.
    Tengo “Fundamentals of Astrodynamics” de Bate, Mueller y otros, y quiero intentar hacer algo durante estas vacaciones.
    Hablo de simulación porque lo demás parece que sería caro. Me interesa mucho el aspecto de GNC en robótica, y me gustaría recibir buenas recomendaciones de recursos.

    • https://ksp-kos.github.io/KOS/ Puede que Kerbal Space Program no simule la aerodinámica de forma tan realista como quieres, pero parece que mucha gente disfruta escribiendo software GNC ahí.
    • Un robot bípedo de dos ruedas autoequilibrado parece un proyecto divertido y relativamente seguro.
      Me refiero a algo tipo Segway que pueda quedarse de pie en un solo lugar sin caerse ni salir volando de la mesa.
      Creo que harían falta un microcontrolador, una IMU, un controlador de motores paso a paso, motores, ruedas LEGO y quizá un bloque de madera.
      No lo he hecho yo mismo, así que puede que mis suposiciones estén bastante erradas.
    • Me da curiosidad qué planeas hacer con “Fundamentals of Astrodynamics”.
      Me gustaría escuchar más sobre qué contiene el libro y qué proyectos se podrían intentar.
    • Me pasa igual. Casi todos mis proyectos personales tienen algún componente de hardware.
      Después de trabajar con software todo el día, se siente muy bien trabajar orientado a un objeto físico.
  • Creo que un pequeño ray tracer de juguete también es un excelente reto para intentar.
    Basta con manejar esferas, algunas fuentes de luz, reflexión difusa y especular, y generar gráficos bitmap.
    Si no lo haces crecer demasiado, puede ser un proyecto con alcance relativamente bien acotado.

  • Es una lista interesante y, aunque depende de la personalidad y las circunstancias de cada quien, es un buen punto de partida si buscas ideas.
    No diría que todos los programadores deban intentar algo en particular; solo voy a anotar lo que yo elegí hacer.
    En la Sinclair ZX Spectrum hice, de forma muy rudimentaria, un editor de pentagramas musicales y un tracker, y como juego 2D hice un Space Invaders con un solo invasor.
    Esa computadora ni siquiera era mía. En mi primera computadora, una 386, hice un compresor Huffman, un índice B-Tree que era más rápido que DBase/Clipper, un generador de formularios orientado a objetos y varios programas de fondo para DOS, uno de los cuales después se usó en el proceso de instalación de una gran empresa.
    Unos años después hice un verificador de correo para dial-up, un parser manual para resaltado de sintaxis y hasta algo parecido a una hoja de cálculo, y todavía sigo haciendo eso. Seguro que también estoy omitiendo algunas cosas.

  • Es una buena lista. Sería bueno mantenerla como una lista viva para que pueda evolucionar con el tiempo
    Quisiera agregar dos cosas
    Crear un memcached ligero requiere combinar algoritmos básicos con buenas prácticas de diseño de sistemas. Es un problema “simple”, pero hay que pensarlo bien desde varios ángulos, como invalidación, concurrencia y gestión de memoria
    También es buena idea crear tu propio Docker. No es tan complejo como suena y te da la oportunidad de entender los fundamentos de la programación de sistemas operativos, algo que muchos ingenieros hoy no usan mucho en su trabajo diario