Re[8]: Не пора ли нам перейти на D
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.07 13:11
Оценка: 7 (2)
Здравствуйте, Nuzhny, Вы писали:

N>И это простой и понятный пример? Множество скобок и др. символов лично для меня не вполне читабельны. Все программы на Немерле так выглядят?


Ну, давай сравним с оригиналом.
Возмем саму функцию (на D):
template factorial(int n : 1)
{
    enum { factorial = 1 }
}

template factorial(int n)
{
    enum { factorial = n* factorial!(n-1) }
}

и на Nemerle:
Factorial(n : uint) : ulong
{
    | 0 | 1 => 1
    | _     => n * Factorial(n - 1)
}

Могу переписать ее более "понятно" для тех кто привык только к С++:
Factorial(n : uint) : ulong
{
  if (n == 0 || n == 1) 1
  else n * Factorial(n - 1)
}

Она правда корректна по сравнению с оригиналом (где в случае n < 1 будет зацикливание), но все же.
Где здесь какие-то лишние скобочки или еще что-то?

Теперь думаем что мы получили и как можем использовать. А получили мы рекурсивый шаблон на D. Использовать этот шаблон мы может только во время компиляции. Вычисляться он будет в режиме интерпретации.

На Nemerle мы получили просто функцю. Мы можем вызвать ее в программе как любую другую. Теперь чтобы вычислить эту функцию во время компляции мы просто помещаем ее вызов в макрос:
macro CompileTimeFactorial(n : uint)
{
    def res = Util.Factorial(n);
    <[ $(res : ulong) ]>
}

в котором мы производим вычисление и помещаем результат вычисления код генерируемый макросом.

В обличии от D или C++ мы вольны произвести в макросе вычисления любой сложности. Так если у нас уже есть нужная функция которую нужно вычислить во время компиляции, то мы просто вызваем ее в макросе и получаем требуемый результатм.
То есть для нас нет разницы между кодом программы и метакодом. В D же и в С++ мы вынждены писать метакод на птичьех языках которые сильно отличаются от того языка что мы вынуждены применять в реальной программе.

Что тут непонятного? Возможно:
<[ $(res : ulong) ]>

да, это новое для D/C++-программиста. Но объяснить это не так то и сложно.
Это способ сгенерировать код. Подобных средств в D и С++ попросту нет. Потому и сравнивать тут нечего.
<[ ]> — это аналог строкового литерала в C++, но в отличии от С++ внутри этого литерала получается не страка, а выражение которое можно подставить в программу. Другими словами <[ ]> выделяет участки кода которые интерпретируются компилятором не как исполняемый код, а как заготовка для генерации кода.
$ — позвляет состалься в этой заготовке на переменные из внешнего кода. Так что мы, например, может написат так:
<[
if ($x)
SomeCall();
else
$x
]>
и значение "x" будет подставлено в те места где пы указали $x. Толко значнеие "x" будет интерпретироваться как участок кода. Так что если мы подставляем некий литерал, то нам нужно указать компилятору, что его нужно преобразовать в код. Так $(res : ulong) говорит, что значение из внешней (мета-) программы нужно преобрзовать в литерал (в компилируемой программе).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.