Mono/.NET: No importa el lenguaje

Una de las cosas que vamos a probar en el trabajo práctico de implementación de Administración de Recursos, es qué tan cierto es eso de que Mono/.NET es independiente del lenguaje.

Bueno, estuve haciendo unas pruebas con Python y C#. Hay una implementación de código abierto (bajo la licencia de Microsoft Ms-PL) del intérprete de Python escrita en C#, que permite ejecutar estos programas compilando el código Python a CIL (el código intermedio). También tiene una consola, como Python, y es posible utilizar toda la biblioteca de .NET. Se llama IronPython.

Esta implementación, en su versión estable actual 1.1, tiene compatibilidad con CPython 2.4.4. Esto significa que un programa escrito para ser corrido con Python 2.4.4 puede correrse también con IronPython 1.1. Sin embargo no es que podemos correr cualquier cosa hecha para Python con IronPython: un juego que utiliza el módulo PyGame no funciona (por lo menos yo no pude).

Les voy a mostrar un ejemplo en el que desde Python creo una clase que hereda de otra creada en C#. Sip, ¡esto está muy bueno!

Esta es la clase Persona (si, es algo bien sencillo) en C#:

using System;

public class Persona
{
	private string nombre;
	private string apellido;

	public Persona(string nombre, string apellido)
	{
		this.nombre = nombre;
		this.apellido = apellido;

		Console.WriteLine("Constructor C#");
	}

	public string Nombre
	{
		get { return this.nombre; }
		set { this.nombre = value; }
	}

	public string Apellido
	{
		get { return this.apellido; }
		set { this.apellido = value; }
	}

	public string NombreEnMayusculas
	{
		get {
			return this.nombre.ToUpper();
		}
	}

	public string ApellidoEnMayusculas
	{
		get {
			return this.apellido.ToUpper();
		}
	}
}

Para los que no conocen C#, esas cuatro ultimas cosas raras que están definidas se llaman propiedades. Vienen a reemplazar los getters y setters. Así, en lugar de setear el nombre con un objeto.setNombre(“Nombre nuevo”), lo hacemos con un objeto.Nombre = “Nombre nuevo”. Pueden ser de sólo lectura (cuando hay sólo un get), sólo escritura, o lectura/escritura.

En fin, la clase Python es esta:

import clr
clr.AddReferenceToFile("Persona.dll")

import Persona

class Mujer(Persona):

    def imprimirNombreCompleto(self):
        print self.Nombre + ' ' + self.Apellido

    def nombreEnMinusculas(self):
        return self.Nombre.lower()

    def apellidoEnMinusculas(self):
        return self.Apellido.lower()

x = Mujer('Juana', 'Vargas')
x.imprimirNombreCompleto()

print x.NombreEnMayusculas + ' ' + x.ApellidoEnMayusculas
print x.nombreEnMinusculas() + ' ' + x.apellidoEnMinusculas()
print x.nombreEnMinusculas() + ' ' + x.ApellidoEnMayusculas

(Cuando copian y pegan, las comillas simples se cambian. Así que no va a compilar a menos que las reemplacen)

Los pasos para probar este codigo son:

  1. Compilar la clase hecha en C# a una librería (Persona.dll) ejecutando: “mcs -t:library -out:Persona.dll Persona.cs”, suponiendo que han llamado al archivo de la clase C# Persona.cs
  2. Instalan la versión Community Edition de IronPython (IPCE). La pueden bajar aquí. Hay que agregar a la variable de entorno PATH el lugar donde lo descompriman.
  3. Corren el archivo Mujer.py (suponiendo que así lo han llamado) con IronPython: “ipy.exe Mujer.py”

La salida de eso es:

Constructor C#
Juana Vargas
JUANA VARGAS
juana vargas
juana VARGAS

Python desde C#

Lamentablemente el ejemplo anterior invertido no es posible (crear una clase en C# que herede de la de Python), sin embargo obvio que sí se pueden ejecutar métodos y otras cosas.

Python es un lenguaje dinámico, y esta característica complica las cosas. Si bien IronPython ha demostrado que CLR (Common Language Runtime) tiene buen soporte para los lenguejes dinámicos, se está trabajando en una capa que está encima de CLR, llamada DLR (Dynamic Language Runtime) que lo hace muchísimo mejor para este tipo de lenguajes. DLR hace que sea mucho más fácil implementar lenguajes dinámicos en .NET, además de poder compartir código con otros lenguajes (dinámicos y estáticos).