От: | Oyster | https://github.com/devoyster | |
Дата: | 05.04.06 08:03 | ||
Оценка: | 160 (12) |
Немного о Nemerle (для тех, кто не знает)
Nemerle — это (относительно) новый язык для платформы .NET (под FW 2.0), синтаксис которого похож на C#. Но в нём имеются и некоторые возможности отсутствующие в C# напрочь. А именно:
Удобная работа с лямбдами и туплами
Сопоставление по образцу
Автоматический вывод типов (т.е. язык позволяет очень редко указывать тип выражений явно, при этом статическая типизация сохраняется)
Синтаксические макросы (убедительная просьба не путать с макросами Си)
Как видно, очень многое в язык пришло из мира функционального приграммирования. Последний пункт говорит о том, что на Nemerle мы можем писать довольно мощный метакод (код, создающий другой код). При этом код не выглядит громоздким (и не является таковым) благодаря наличию квази-цитирования.
Больше про Nemerle можно почитать в теме Изучаем макросы NemerleАвтор: VladD2— там описано, как поставить его себе на машину и использовать + немного написано о самом языке. Я использую для работы набор шаблонов проектов для студии
Дата: 18.02.06Автор: Oyster. Также те, комы не лень разгребать километровые посты, могут узнать много полезного о Nemerle в форуме Философия программирования.
Дата: 06.03.06
using System.Console;
using Oyster.Units;
using Oyster.Units.Macros;
def m1 = Cgs.Mass(1); // 1 грамм
def m2 = Si.Mass(m1); // Автоматическое преобразование в килограммы. В результате получаем 0.001 кг
WriteLine($"Mass in SI: $m2, in CGS: $m1");
def l1 = Cgs.Length(100); // 100 см
def l2 = Si.Length(l1); // Автоматическое преобразование. Результат - 1 м
WriteLine($"Length in SI: $l2, in CGS: $l1");
def t1 = Cgs.Time(1); // 1 с
def t2 = Si.Time(t1); // Тоже 1 с, т.к. единицы измерения времени в системах СИ и СГС совпадают.
WriteLine($"Time in SI: $t2, in CGS: $t1");
// Теперь немного более сложный пример. Предыдущие величины (масса, длина, время) являются
// базовыми (ортами) в обеих системах единиц. Здесь же мы имеем дело с производными величинами -
// скоростью, енергией и мощностью
def v1 = Cgs.Velocity(10); // 10 см/с
def v2 = Si.Velocity(v1); // Результат преобразования - 0.1 м/с
WriteLine($"Velocity in SI: $v2, in CGS: $v1");
def e1 = Si.Energy(0.0001); // 10e-4 Дж.
def e2 = Cgs.Energy(e1); // e2 = 1000 эрг
WriteLine($"Energy in SI: $e1, in CGS: $e2");
// Это - пример работы с внесистемными единицами. В данном случае мощность переводится из ваттов
// в лошадиные силы
def p1 = Si.Power(1000); // 1000 Вт
def p2 = Ext.Power(p1); // 1.35962 лс
WriteLine($"Power in SI: $p1, in Ext system: $p2");
// Пример работы с простейшими арифметическими действиями
def a1 = Si.Acceleration(1); // 1 м/с2
def a2 = Cgs.Acceleration(a1 + Cgs.Acceleration(200)); // 1 м/с2 + 200 см/с2 = 300 см/с2, как и должно было быть
WriteLine($"Acceleration: a1 = $a1, a2 = $a2");
// Сила
def f1 = Si.Force(10); // 10 Н
def f2 = Cgs.Force(f1*2); // 10 Н * 2 = 2000000 дин
def f3 = Si.Force(m1*l2/(t1*t1)); // 1 г * 1 м / (1 с * 1 с) = 0.001 Н
// А вот так уже не скомпилируется - не та размерность
//def f4 = Si.Force(m1*l2/t1);
// Вот что выдаёт ncc:
// Main.n(122,10,122,18): error : each overload has an error during call:
// Main.n(122,10,122,18): error : overload #1, method Oyster.Units.Si.Force..ctor(value : System.Double) : void
// Main.n(122,10,122,18): error : in argument #1 (value) of Oyster.Units.Si.Force, needed a System.Double, got _N_TempUnitType5439: _N_TempUnitType5439 is not a subtype of System.Double [simple require]
// Main.n(122,10,122,18): error : overload #2, method Oyster.Units.Si.Force..ctor(value : Oyster.Units.AbstractUnitType_1_1_-2_0_0_0_0) : void
// Main.n(122,10,122,18): error : in argument #1 (value) of Oyster.Units.Si.Force, needed a Oyster.Units.AbstractUnitType_1_1_-2_0_0_0_0, got _N_TempUnitType5439: _N_TempUnitType5439 is not a subtype of Oyster.Units.AbstractUnitType_1_1_-2_0_0_0_0 [simple require]
WriteLine($"Force: f1 = $f1, f2 = $f2, f3 = $f3");
// Здесь ошибка компиляции - пытаемся складывать енергию, массу и скорость
//WriteLine($"ERROR = $(e1 + e2 + v1 + v2 + m1 + m2)");
// Вот что выдаёт ncc (точнее, мой макрос):
// Main.n(135,52,135,64): error : Expression { e1 + e2 [+] v1 } can't be compiled because units are having different dimensions.
// Здесь происходит преобразование на лету. В результате имеем 0.0002 Дж - результат имеет тот же тип,
// что и левый операнд
WriteLine($"Result = $(e1 + e2)");
// Здесь выводится единица, т.к. e1 и e2 содержат одно и то же значение, но выраженное в разных
// системах единиц
WriteLine($"Result = $(e1/e2)")