Translate

Mostrando las entradas con la etiqueta S#. Mostrar todas las entradas
Mostrando las entradas con la etiqueta S#. Mostrar todas las entradas

jueves, 24 de septiembre de 2026

S#: un lenguaje para enseñar programación funcional


Cuando enseñamos programación funcional, aparece rápidamente una pregunta: ¿Qué lenguaje usamos?

Una opción bastante obvia es Haskell. Es uno de los lenguajes funcionales más importantes y tiene prácticamente todo lo que queremos enseñar.

Pero aparece un problema: Haskell no siempre resulta sencillo para alguien que está aprendiendo programación funcional por primera vez. Básicamente, en la universidad se enseña C#, Java o C++, que están lejos de Haskell. 

La sintaxis, el sistema de tipos, las funciones de orden superior, las expresiones, las mónadas y muchas otras características hacen que el alumno pueda terminar concentrándose más en entender el lenguaje que en entender el paradigma.

Entonces aparece otra posibilidad: Scala.

Scala tiene una enorme ventaja: permite enseñar programación funcional dentro de un lenguaje que también tiene programación orientada a objetos. Y justamente ahí aparece otro problema.

Si el objetivo de una materia es enseñar programación funcional, no necesariamente queremos que el alumno pueda resolver el ejercicio utilizando:


var x = 10

x = x + 1


o utilizando clases, objetos mutables y técnicas propias de la programación imperativa.


Scala permite hacerlo porque es un lenguaje multiparadigma.

Pero para enseñar un paradigma, a veces queremos algo diferente: Un lenguaje que no permita escapar del paradigma que estamos intentando aprender.


La pregunta entonces fue: ¿Podemos diseñar un lenguaje funcional con una sintaxis más sencilla?

S# es funcional por diseño.

No hay una versión funcional y otra imperativa del lenguaje.

La idea es que el lenguaje ayude al alumno a pensar en términos funcionales.


S# es un pequeño lenguaje de programación funcional, estáticamente tipado, pensado principalmente como herramienta para enseñar programación funcional.

El proyecto actualmente transpila código S# a C# y utiliza .NET como plataforma de ejecución.


Por ejemplo, una función puede escribirse simplemente como:

def add(a: Int, b: Int): Int = a + b


Las funciones son valores:

val double = (x: Int) => x * 2


Y podemos trabajar con listas:

val numbers = List(1, 2, 3)


También podemos utilizar pattern matching:

def length[A](list: List[A]): Int = list match {

    case Nil        => 0

    case head::tail => 1 + length(tail)

}


La sintaxis intenta ser suficientemente familiar para que el alumno pueda concentrarse en la idea funcional que hay detrás del código.


Una de las decisiones importantes de S# es utilizar val para las vinculaciones:

val x = 10


La idea no es tener una alternativa como "var" para modificar posteriormente ese valor.

Esto es deliberado.

Si estamos enseñando programación funcional, queremos que el alumno se acostumbre desde el principio a trabajar con valores inmutables.


El lenguaje intenta acompañar esa forma de pensar. Funcional, pero no necesariamente extraño

Otra decisión importante es no intentar inventar una sintaxis completamente nueva.

S# toma inspiración de lenguajes como Scala y utiliza conceptos conocidos en programación funcional:

val`

funciones y lambdas;

tipos genéricos;

  • List;
  • Option;
  • match;
  • case;
  • sealed trait;
  • case class;
  • recursión;
  • currying;
  • pattern matching.


Por ejemplo:


sealed trait Shape

case class Circle(radius: Double) extends Shape

case class Rectangle(width: Double, height: Double) extends Shape


Y después:


def area(s: Shape): Double = s match {

    case Circle(r)       => 3.14159 * r * r

    case Rectangle(w, h) => w * h

}


Son conceptos que posteriormente el alumno puede encontrar en otros lenguajes funcionales.

La idea no es crear un lenguaje aislado, sino crear una puerta de entrada.


¿Y por qué transpilar a C#?

S# no intenta competir con C#.

C# es simplemente el backend.


El compilador analiza el código S#, realiza el chequeo de tipos y genera código C# que después puede ser compilado y ejecutado sobre .NET.


Esto también tiene una ventaja interesante desde el punto de vista educativo.

Podemos escribir:


def factorial(n: Int): Int =

    if (n <= 1) 1

    else n * factorial(n - 1)


y terminar generando código C# equivalente.


El alumno puede concentrarse primero en qué expresa el programa y, posteriormente, analizar cómo ese código funcional puede representarse en otro lenguaje.


El proyecto fue creciendo más allá de la idea inicial de una sintaxis funcional.


Actualmente S# cuenta con:

  • compilador;
  • lexer y parser;
  • chequeo de tipos;
  • generación de código C#;
  • runtime propio;
  • listas y Option;
  • pattern matching;
  • ADTs;
  • funciones de orden superior;
  • currying y partial application;
  • optimización de tail recursion;
  • REPL;
  • CLI;
  • API REST y gRPC;
  • diagnósticos de compilación;
  • tests de especificación;
  • extensión para VS Code.


Pero el objetivo principal sigue siendo el mismo: hacer que aprender programación funcional sea sencillo.


El proyecto está disponible en GitHub: https://github.com/emanuelpeg/SSharp