Como enseñaría yo desarrollo de software en la universidad

Hoy en twitter circuló una encuesta preguntando si las universidades deberían incluir materias específicas como Javascript o HTML. http://twtpoll.com/csioqo

Mi respuesta es no. Los planes de carrera no deberían tener materias que correspondan a lenguajes/tecnologías específicas. Considero que lo mejor es elevar el nivel de abstracción de las materias y temas, y dejar los detalles de qué lenguajes/tecnologías a la implementación de cada curso/profesor/alumno.

Entonces, un plan de carrera tendría materias como Programación I, Programación II, Programación III ... y en la I enseñan programación estructurada con uno o más lenguajes estructurados, luego en II ven OOP con uno o más lenguajes, en III ven programación funcional con uno o más lenguajes, y así ...

Las tecnologías van y vienen, lo que importa son los principios. Adicionalmente, estar cambiando los planes de carrera continuamente para cambiar nombres de materia no es práctico. Al elevar la abstracción en los nombres y temas de las materias, haces tu sistema (es decir, el plan de carrera) más robusto al cambio.

Esto no significa que creo que los estudiantes de universidad no deban aprender las tecnologías relevantes del momento. Claro que sí se debe hacer, pero eso se puede manejar como "detalles de implementación" de las materias del plan de carrera. De hecho, mi postura es que es responsabilidad de los alumnos aprender los lenguajes/tecnologías por su lado, ya sea en libros, Internet o en cursos/talleres fuera del plan de carrera.

Habiendo dicho esto, esto es lo que yo haría si fuera maestro de ingenería de software, o ciencias computacionales a nivel universitario:

"Ok, muchach@s, los principios de la programación funcional son estos ... y eso da las siguientes ventajas/consecuencias ... algunos ejemplos de lenguajes de programación funcional son estos ... Entonces, para su proyecto de este semestre deben construir un software utilizando programación funcional. ¿Con cual lenguaje? No me importa, si no saben ninguno, escojan alguno de esa lista y apréndanlo. Aquí está la lista de proyectos: un componente para reconocimiento de voz, un componente para analizar colores, un buscador de datos en redes sociales, un servidor de correo, etc. A los que su matrícula termina en 1-2 les toca x proyecto , 3-4 tal otro, 5-6 tal, .... Todo su código se sube a github y ahí lo reviso. Pueden compartir código entre ustedes siempre y cuando atribuyan el código al autor original. Cada més, la persona cuyo código sea el más usado tendrá puntos extra."

Sé que es mucho más facil decirlo que hacerlo, y probablemente algún dia el destino me presentará con la oportunidad de demostrar si realmente haría esto, pero por lo pronto me parece como escenario ideal, si verdaderamente queremos preparar a nuestros jóvenes en esta profesión.

-----------

Aclaraciones: 2012-05-10

Cuando escribí este post deje muchas cosas de lado o implícitas, y conforme mucha gente se ha involucrado en esta discusión quisiera hacer algunas aclaraciones:

Desarrollar software involucra mucho más que programar.
Por simplicidad, en este post solo hablé de aspectos de programación, pero por supuesto que estoy consciente de que programar es tan solo una parte del desarrollo de software, por algo en SG publicamos artículos relacionados con muchas prácticas y disciplinas más allá de la programación.

Los recién graduados sí deben tener habilidades "duras" en lenguajes/tecnologías modernas.
Por supuesto, ¿sino cómo van a encontrar trabajo? No estoy diciendo que solo tengan conocimientos abstractos, sino que el principal responsable de obtener dichas habilidades en lenguajes/tecnologías requeridas por el mercado laboral, es el alumno. Lo que no es aceptable para mí es la actitud de muchos alumnos de "Quisiera saber programar en X lenguaje/tecnología pero no sé porque en la escuela no me enseñaron". Como comenté hace unos días en twitter: Si no sabes Ruby/Python/HTML5/etc no es porque "en la escuela no te enseñaron", sino porque no has querido aprender.

Los estudiantes necesitan practicar desarrollando software
Como ya lo comenté arriba, concuerdo que no solo se trata de que aprendan a programar sino que también aprendan a administrar requerimientos, probar software, etcétera. Pero creo que estas son cosas que dificilmente se asimilan de los libros. Honestamente, yo prefiero mil veces tener a alguien que ha llorado de frustración porque perdió "la versión buena" de un programa, que ha perdido semanas de esfuerzo porque entendió mal los requerimientos (o se los cambiaron y no pudo defenderse) o que ha pasado vergüenzas porque liberó un software sin haber hecho pruebas de stress y tronó como ejote cuando lo empezaron a usar un número significativo de personas, que a alguien que puede recitarme de memoria los Process Areas de cada nivel de CMMI. Me preocupa encontrarme con alumnos que pasan 4 años estudiando teoría pero sin haber construido una aplicación de software de principio a fin. Como comenté en el artículo "Capital Humano en Software" de SG34, "Creo que es mucho mejor que los alumnos comiencen a desarrollar aplicaciones completas (sencillas, pero completas) desde los primeros semestres y conforme vayan avanzando en sus estudios vayan construyendo software más complejo aplicando las técnicas/conocimientos que van adquiriendo. El objetivo es que cuando se gradúen lleven 4 años desarrollando software, no 4 años estudiando técnicas que nunca han aplicado."

Posiblemente el párrafo anterior parezca contradictorio de mi parte: "Pedro, por un lado dices que los maestros deben enfocarse en conocimiento abstracto y por otro dices que está mal que los alumnos solo sepan conceptos". La explicación a esto está entre líneas en el ejemplo que puse originalmente sobre lo que yo haría si fuera maestro universitario, déjenme elaborar: Los maestros deben preocuparse por enseñar fundamentos/principios, los alumnos deben asimilar éstos (o por lo menos tenerlos por ahí de referencia) y aplicarlos en proyectos prácticos que desarrollarán y que son lo que el maestro usará para evaluarlos. Así que aunque el maestro enseña conocimiento abstracto, revisa contra entregables (las aplicaciones de software realizadas como proyecto) que reflejan la asimilación de conocimiento concreto y la aplicación de prácticas/técnicas de ingeniería de software. Poniéndolo con un ejemplo: "Yo profesor, te enseño que es la programación orientada a objetos y estrategias de testing, y para asegurar que me entendiste me vas a entregar una aplicación desarrollada con un lenguaje moderno orientado a objetos usando test driven development. Me entregas tu código fuente incluyendo tus casos de prueba y un script para generar tu build y correr las pruebas. Y contra eso te voy a calificar."

Bueno, con eso concluyo mis aclaraciones hasta ahora ;). Muchas gracias a todos por sus comentarios. Este es un tema en el que habemos muchos interesados, y con justa razón porque de él depende el nivel de competitividad de nuestros futuros profesionistas y por lo tanto el de la industria de TI en nuestra región.