2010-08-27 3 views
11

Community Wiki Вопрос:Сравнение Nemerle и F # Для функционала на .Net

В соответствии с этим вопрос: What are the benefits of using Scala in .Net? другой вопрос приходит на ум. Может ли кто-либо изложить сравнительные преимущества (и недостатки) Nemerle и F # для функционального развития на платформе .Net? Я только что посмотрел на Немерле. Похоже, что это разные игры в одном и том же поле, как F #, поэтому мне было интересно, какие отличия там отличаются от очевидных различий синтаксиса и большое преимущество F # от Microsoft.

ответ

4

Я мало знаю о Nemerle, но я думаю, что одна из его больших особенностей - макросы (а-ля гигенные схемы, подобные счастливым макросам, в отличие от уродливых макросов типа C). Я никогда не сталкивался с тем, что люди так много любят макросы, но опять же, я никогда не сталкивался с тем, почему люди так любят алгебраические типы данных и сопоставляют шаблоны, пока я не начал использовать F #. Поэтому я подозреваю, что если вы любите макросы, и используете .NET, то вы являетесь бешеным поклонником Nemerle.

+0

Мм, сопоставление с образцом. Интересно, насколько вкусная схема похожа на счастливые макросы. Теперь я должен попробовать Нермерле в выходные. – gradbot

+0

Макросы Nemerle - это, в основном, расширения компилятора. Они используются для реализации большинства языковых конструкций, в том числе операторов «if» и «для» циклов, поддержки Linq и различных полезных библиотек для регистрации, профилирования, АОП и т. Д. –

+1

«Я никогда не сталкивался с тем, почему люди так любят макросы ». Учитывая, что вы знаете F #, попробуйте макросы OCaml (camlp4). –

18

Я коснулся обоих этих языков, и мои впечатления от Nemerle кратко следующие: (Я полагаю, что большая часть аудитории знакома с F #, а Nemerle менее популярен, поэтому ради справедливости я покрою это бит больше):

  • Сообщество F # довольно большое и постоянно растет из-за большого количества блог-постов, статей и т. д. Также оно распространяется по странам. Как противоположность, энтузиасты Nemerle в основном русскоязычны и сосредоточены на сайте RSDN.ru.
  • Синтаксис Nemerle IMO намного дружелюбнее для разработчиков с фоном на языках C-типа.
  • Nemerle (а также F #) имеет функции вывода типа. Механизм ввода типа в Nemerle привязан к телу метода (локальные функции, переменные и т. Д.), Противоположный области вывода типа F #. Однако компилятор Nemerle не применяет никаких конкретных идиом написания кода, чтобы помочь механизму ввода типа.

F #

open System.Text 

let l = [1; 2; 3] 
let r1 = l |> List.fold(fun (sb : StringBuilder) v -> sb.Append(v).AppendLine()) (StringBuilder()) // type annotation is required on the function argument 
let r2 = (StringBuilder(), l) ||> List.fold(fun sb v -> sb.Append(v).AppendLine()) //here compiler can infer type of State parameter 

Nemerle

using System.Console; 
using System.Collections.Generic; 
using System.Text; 

def l = [1,2,3]; 
def res = l.FoldLeft(StringBuilder(), (v, acc) => acc.Append(v).AppendLine()); 
WriteLine($"Result:\n$res"); 

def d = Dictionary(); // generic parameters are absent (even placeholders!!!) 
d.Add(1, "!"); 
WriteLine(d.GetType()); // System.Collections.Generic.Dictionary`2[System.Int32,System.String] 

Также вы можете заметить еще одну особенность Nemerle компилятора - он может выводить типы из дальнейшего использования. Для вывода типов F # использует подход, основанный на алгоритме Хиндли-Милнера, и пытается вывести наиболее общий тип. Nemerle, напротив, никогда не сталкивается с полиморфными типами и всегда ищет наиболее специфический тип.

F #

let addInt = (+) 5 
let addString = (+) "!!!" 

let run f x = f (f x) // ('T -> 'T) -> 'T -> 'T 

run addInt 5 
run addString "S" 

Nemerle в одних и тех же условиях будет вывести тип запуска как (int-> Int) * Int -> Int.

Подробнее о Nemerle механизме вывода типов можно найти в магистерской диссертации Михала Москаля: Type Inference With Deferral

  • Nemerle имеет богатые возможности метапрограммирования. Большинство конструкций управления языками, таких как циклы, условные выражения, поддержка LINQ, предстоящая функция синтаксического анализа включала источники C# и многие другие - все они создаются с использованием макросов. Один пример приложений макросов можно найти here. BTW, возможности форматирования строк с $ синтаксис в примере выше - это также встроенный макрос.

РЕДАКТИРОВАТЬ: Добавлено немного больше образца

using System.Console; 
using System.Collections.Generic; 
using System.Text; 

variant Expr 
{ 
    | Const { value : double } 
    | Var { name : string } 
    | Operation { id : string; left : Expr; right : Expr } 

    public Eval(operations : Dictionary[string, double*double -> double], context : Dictionary[string, double]) : double 
    { 
    match(this) 
    { 
     | Const (value) => value 
     | Var(name) => context[name] 
     | Operation(id, left, right) => 
      def f = operations[id]; 
      f(left.Eval(operations, context), right.Eval(operations, context)) 
    } 
    } 
} 

module Program 
{ 
    public Main() : void 
    { 
     def expr = 
      Expr.Operation(
       "*", 
       Expr.Const(10), 
       Expr.Operation(
       "+", 
       Expr.Var("n"), 
       Expr.Const(5) 
       ) 
      ); 
     def operations = Dictionary.[string, double * double -> double](); 
     operations["+"] = (x, y) => x + y; 
     operations["*"] = _ * _; 

     def vars = Dictionary(); 
     vars["n"] = 3.0; 

     def result = expr.Eval(operations, vars); 
     WriteLine($"Result is $result"); 
    } 
}