Re[24]: Вопрос к Vlad2: Nemerle & R#
От: Oyster Украина https://github.com/devoyster
Дата: 27.03.06 09:23
Оценка: 6 (1)
Здравствуйте, eao197, Вы писали:

E>В общем-то я с вами согласен, смущает меня только то, что в C++ в одном выражении можно будет сочетать operator*() (и другие) для разных типов данных. Например, Physic<A,B,C> еще и на скаляр умножить можно будет -- в самом выражении с использованием операторов это никак не будет явно подчеркиваться. В Nemerle для таких ситуаций, вероятно, еще что-то додумывать придется.


Насколько я понимаю, оператор * можно сделать макросом и тогда получится оставить "прозрачный" синтаксис.

E>Но поинт здесь был в другом. Хоть на C++ решение и не тривиальное на первый взгляд, но самое сложное в нем -- это додуматься до него. Сама же реализация отнюдь не сложная. Бывают гораздо более сложные навороты (например, проверка чисел на простоту в compile-time). И, возвращаясь к первоначальному замечанию VladD2 о скалярных параметрах шаблонах, вполне себе востребованный и жизнеспособный код.


На самом деле, макросы Nemerle позволяют делать compile-time вычисления проще, потому что — сам понимаешь — в них можно выполнять любой код.

Сейчас дам ма-аленький такой пример. Будем считать факториал в compile-time:

namespace Oyster
{
  public module Math
  {
    // Просто метод, который просто считает факториал в рантайме
    static public Fact(x : int) : int
    {
      | 1 => 1
      | _ => x * Fact(x - 1)
    }
  }
}

namespace Oyster.Macro
{
  // Макрос
  macro Fact(expr)
  {
    match (expr) {
      | <[ $(x : int) ]> => <[ $(Oyster.Math.Fact(x) : int) ]>
      | _ => <[ Oyster.Math.Fact($expr) ]>
    }
  }
}

Макрос Fact или вернёт константу (если передана константа) или вставит вызов Math.Fact (в противном случае). При этом вызов макроса ничем не отличается от вызова функции и оба варианта из примера ниже отработают:

using System.Console;
using Oyster;

// Выведет 720, посчитает в compile-time
WriteLine(Macro.Fact(6));

// Выведет 720, но посчитает в рантайме
def x = 6;
WriteLine(Macro.Fact(x))
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.