Nemerle es una de propósito general , de alto nivel , tipos estáticos lenguaje de programación diseñado para plataformas que utilizan el Common Language Infrastructure ( .NET / Mono ). Ofrece características funcionales , orientadas a objetos e imperativas . Tiene una sintaxis simple similar a C # y un poderoso sistema de metaprogramación . En junio de 2012, los desarrolladores principales de Nemerle fueron contratados por la empresa de desarrollo de software checa JetBrains.. El equipo se está enfocando en desarrollar Nitra, un marco para implementar lenguajes de programación nuevos y existentes. Este marco probablemente se utilizará para crear versiones futuras de Nemerle. [2] [3] [4]
Paradigma | Multi-paradigma : funcional , imperativo , meta , orientado a objetos |
---|---|
Diseñada por | Kamil Skalski, Michał Moskal, Prof.Leszek Pacholski, Paweł Olszta en la Universidad de Wrocław |
Desarrollador | JetBrains |
Apareció por primera vez | 2003 |
Lanzamiento estable | 1.2.507.0 [1] / 6 de agosto de 2016 |
Disciplina de mecanografía | Inferido , nominal , estático , fuerte |
Plataforma | CLI |
Extensiones de nombre de archivo | .norte |
Sitio web | nemerle |
Implementaciones importantes | |
Nemerle | |
Influenciado por | |
C # , Lisp , ML |
Nemerle lleva el nombre del archimago Nemmerle, un personaje de la novela de fantasía A Wizard of Earthsea de Ursula K. Le Guin .
Características
La característica más notable de Nemerle es la capacidad de mezclar estilos de programación orientados a objetos y funcionales. Los programas pueden estructurarse utilizando conceptos orientados a objetos como clases y espacios de nombres, mientras que los métodos pueden (opcionalmente) escribirse en un estilo funcional. Otras características notables incluyen:
- inferencia de tipo fuerte
- un subsistema de metaprogramación flexible (usando macros )
- soporte completo para programación orientada a objetos (OOP), al estilo de C #, Java y C ++
- Soporte completo para programación funcional, al estilo de ML , OCaml y Haskell , con estas características:
- funciones de orden superior
- la coincidencia de patrones
- tipos algebraicos
- funciones locales
- tuplas y tipos anónimos
- aplicación parcial de funciones
El sistema de metaprogramación permite una gran extensibilidad del compilador , incorporando lenguajes específicos de dominio , evaluación parcial y programación orientada a aspectos , adoptando un enfoque de alto nivel para eliminar la mayor carga posible de los programadores. El lenguaje combina todas las características estándar de Common Language Infrastructure (CLI), incluido el polimorfismo paramétrico , lambdas , métodos de extensión, etc. Acceder a las bibliotecas incluidas en las plataformas .NET o Mono es tan fácil como en C #.
Inferencia de tipo
def x = 1 ; // int def myList = List (); // Lista genérica [T], el tipo T se deduce del uso en la siguiente línea myList . Suma ( x ); // el compilador deduce el tipo de T como int haciendo que myList sea el tipo de List [int]
Todo es una expresion
def x = { // similar ax = 3 def y = 1 ; def z = 2 ; y + z // esta última declaración es un valor de retorno de bloque };def x = if ( DateTime . Now . DayOfWeek == DayOfWeek . Monday ) // if, using, try son también expresiones "Monday" else "other day" ;def x = intente int . Parse ( someString ) catch { | FormatException () => 0 };def x = returnBlock : { foreach ( i en [ 1 , 2 , 3 ]) cuando ( i > 2 ) returnBlock ( verdadero ); // bloque de salida (x = verdadero) falso // x = falso };
Tuplas
def k = ( 1 , "uno" ); // k: (int * cadena) def ( a , b ) = k ; // a = 1, b = "uno"
La coincidencia de patrones
def resultado = coincidencia ( número ) { | 0 => "cero" | 1 => "uno" | x cuando x < 0 => "negativo" | _ => "más de uno" }
Coincidencia de tipos con vinculación variable:
def check ( o : object ) { match ( o ) { | i es int => $ "An int: $ i " | s es cadena => $ "Una cadena: $ ( s .T oUpper ()) " | _ => "Objeto de otro tipo" } }
Coincidencia de patrones de tuplas:
coincidencia ( tupla ) { | ( 42 , _ ) => "42 en primera posición" | ( _ , 42 ) => "42 en segunda posición" | ( x , y ) => $ "( $ x , $ y )" }
Coincidencia de expresiones regulares:
utilizando Nemerle . Texto ; coincidencia de expresiones regulares ( str ) { | "a +. *" => printf ( "a \ n" ); | @ "(? \ d +) - \ w +" => printf ( "% d \ n" , num + 3 ); | "(? (Ala | Kasia))? ma kota" => coincidir con ( nombre ) { | Algunos ( n ) => printf ( "% s \ n" , n ) | Ninguno => printf ( "noname? \ N" ) } | _ => printf ( "predeterminado \ n" ); }
Tipos funcionales y funciones locales
utilizando System . Consola ; // las clases y los módulos (clases estáticas) se pueden poner en espacios de nombres def next ( x ) { x + 1 }; // el tipo de argumento x y otros argumentos de función se pueden deducir del usodef mult ( x , y ) { x * y };def fibonacci ( i ) { | 0 => 0 | 1 => 1 | otro => fibonacci ( i - 1 ) + fibonacci ( i - 2 ) };WriteLine ( siguiente ( 9 )); // 10 similar a "Console.WriteLine (next (9));" WriteLine ( mult ( 2 , 2 )); // 4 WriteLine ( fibonacci ( 10 )); // 55
Variantes
Las variantes (denominadas tipos de datos o tipos de suma en SML y OCaml) son formas de expresar datos de varios tipos diferentes:
variante RgbColor { | Rojo | Amarillo | Verde | Diferente { rojo : flotar ; verde : flotar ; azul : flotar ; } }
Metaprogramación
El sistema de macros de Nemerle permite crear, analizar y modificar el código del programa durante la compilación. Las macros se pueden utilizar en forma de llamada a un método o como una nueva construcción de lenguaje. Muchas construcciones dentro del lenguaje se implementan usando macros (if, for, foreach, while, using, etc.).
Ejemplo de macro " si ":
macro @if ( cond , e1 , e2 ) syntax ( "if" , "(" , cond , ")" , e1 , Optional ( ";" ), "else" , e2 ) { / * <[]> define una área de cuasi-comillas, el compilador de Nemerle transforma el código en un AST, tales transformaciones son algo similares a una compilación de Expresión en C # * / <[ match ( $ cond : bool ) { | verdadero => $ e1 | _ => $ e2 } ]> }// usando esta macro en el código: def max = if ( a > b ) a else b ; // durante un tiempo de compilación, la línea superior se transformará en esto: def max = match ( a > b ) { | verdadero => a | _ => b }
IDE
Nemerle se puede integrar en el entorno de desarrollo integrado (IDE) Visual Studio 2008 . También tiene un IDE totalmente gratuito basado en Visual Studio 2008 Shell [5] (como Visual Studio Express Editions ) y SharpDevelop ( enlace al código fuente del complemento ).
Nemerle también se puede integrar en Visual Studio 2010 mediante un complemento. [6]
Ejemplos de
¡Hola Mundo!
¡El tradicional Hello World! se puede implementar de una manera más similar a C #:
class Hola { static Main () : void { System . Consola . WriteLine ( "¡Hola, mundo!" ); } }
o más simplemente:
Sistema . Consola . WriteLine ( "¡Hola, mundo!" );
Ejemplos de macros
Las macros permiten generar código repetitivo con comprobaciones estáticas adicionales realizadas por el compilador. Reducen la cantidad de código que debe escribirse a mano, hacen que la generación de código sea más segura y permiten que los programas generen código con comprobaciones del compilador, manteniendo el código fuente relativamente pequeño y legible.
Formato de cadena
La macro de formato de cadena simplifica las variables a manipulaciones de cadenas usando la notación $:
def s = $ "El número es $ i " ; // inserta el valor de la variable i donde se coloca $ i def s = $ " $ x + $ y = $ ( x + y ) " ; // $ (...) se puede usar para hacer cálculos o acceder a miembros
Generación de código declarativo
StructuralEquality , Memoize , json y with son macros que generan código en tiempo de compilación. Aunque algunos de ellos ( StructuralEquality , Memoize ) pueden verse como atributos de C #, durante la compilación, el compilador los examinará y los transformará al código apropiado utilizando la lógica predefinida por sus macros.
[StructuralEquality] // Implementar la interfaz IEquatable [Sample] .Net utilizando la igualdad de comparación de elementos. class Sample { [Memoize] // recuerda el primer resultado de la evaluación public static SomeLongEvaluations () : int { MathLib . CalculateNthPrime ( 10000000 ) } [DependencyProperty] // Propiedad de dependencia de WPF public DependencyPropertySample { get ; establecer ; } public static Main () : void { / * macro de sintaxis "json" genera código: JObject.Object ([("a", JValue.Number (SomeLongEvaluations ())), ("b", JValue.Number (SomeLongEvaluations () + 1))]) * / def jObject = json { a : SomeLongEvaluations (); b : ( SomeLongEvaluations () + 1 )} // macro de inicialización de objeto "<-" es el desarrollo de la inicialización de objeto de corchetes en C # def k = Diagnostics . Process () <- { StartInfo <- // puede iniciar las propiedades de los objetos internos sin llamar a ctor { FileName = "calc.exe" ; UseShellExecute = verdadero ; } Salido + = () => WriteLine ( "Calc hecho" ); // eventos y delegados } ReadLine (); } }
Accesibilidad a la base de datos
Usando macros de Nemerle para SQL puede escribir:
ExecuteReaderLoop ( "SELECCIONAR nombre, apellido DEL empleado DONDE nombre = $ myparm" , dbcon , { WriteLine ( $ "Nombre: $ nombre $ apellido " ) });
en vez de
string sql = "SELECCIONAR nombre, apellido DEL empleado DONDE nombre =: a" ; usando ( NpgsqlCommand dbcmd = new NpgsqlCommand ( sql , dbcon , dbtran )) { dbcmd . Parámetros . Agregar ( "a" , myparm ); usando ( NpgsqlReader reader = dbcmd . ExecuteReader ()) { while ( reader . Read ()) { var firstname = reader . GetString ( 0 ); var apellido = lector . GetString ( 1 ); Consola . WriteLine ( "Nombre: {0} {1}" , primer nombre , apellido ) } } }
y esto no es solo ocultar algunas operaciones en una biblioteca, sino trabajo adicional realizado por el compilador para comprender la cadena de consulta, las variables utilizadas allí y las columnas devueltas desde la base de datos. La macro ExecuteReaderLoop generará código aproximadamente equivalente a lo que tendría que escribir manualmente. Además, se conecta a la base de datos en el momento de la compilación para comprobar que su consulta SQL realmente tiene sentido.
Nuevas construcciones de lenguaje
Con las macros de Nemerle también puede introducir una nueva sintaxis en el lenguaje:
macro ReverseFor (i, begin, body) syntax ("ford", "(", i, ";", begin, ")", body){ <[para ($ i = $ comenzar; $ i> = 0; $ i--) $ cuerpo]>}
define una macro que introduce la sintaxis EXPR de ford (EXPR; EXPR) y se puede usar como
ford (i; n) imprimir (i);
Nemerle con ASP.NET
Nemerle se puede incrustar directamente en ASP.NET :
<% @ Page Language = "Nemerle" %> runat = "server" > Por favor ingrese su nombre: ID = "Name" runat = "server" /> OnClick = "EnterBtn_Click" Text = "Enter" runat = "servidor" />
ID de etiqueta = "Mensaje" runat = "servidor" />