Здравствуйте, 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))