Re[15]: Насколько важен синтаксис языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.09.06 19:54
Оценка:
Здравствуйте, FDSC, Вы писали:

VD>>Вот макросы — это способ сделать это не просто лучше, а почти идиально. Правда в компайлтайме, но все же.


FDS>Идеально?


Ага. Причем я в данном случае выступаю не как пользователь с некими предпочтениями, а как создатель конкурирующего продукта отказавшегося от своих подходов оценив подходы использованные в Немерле.

Реализация у макросов Немеле не супер, но очень даже нечиго. А идеология вообще лучшая из виданного мной. Есть конечно некоторые компромисы, но они лично для меня очевидны.

FDS>Я именно их и смотрел (и там, и там). Первым делом. Но создалось впечатление, что они пытаются научить языку по примерам. Я так и не нашёл ничего похожего на спецификаию C#.


Так и есть, но спецификация совершенно не обязательна для изучения языка.

FDS>Например, где найти ответ на вопрос, как работает это:

FDS>
FDS>    def F2(x: int): int -> int
FDS>    {
FDS>        def FC(y: int): int
FDS>        {
FDS>            2*y + x
FDS>        }
FDS>        FC
FDS>    }
FDS>    def F1(x: int): int
FDS>        {
FDS>                F2(x)(5)
FDS>    }
FDS>F1(5)
FDS>

FDS> и работает ли вообще? Как это будет воспринято компилятором?

За исключением того, что программа не использует значение функции F1 и ничего не выводит, она совершенно корректа. Далает она следующее. Функция F2() возвращает другую функцию которая производит вычисления над своим параметром y и значением параметра x захваченным замыканием. Далее производится вызов этой функии с передачей ее значения.

Вот только можно было бы опустить типы параметров. Все и так очевидно. Так что вот такой код:
using System.Console;

def F2(x)
{
  def FC(y) { 2 * y + x }

  FC
}

def F1(x) { F2(x)(5) }

WriteLine(F1(5))

выведет 15. А такой:
using System.Console;

def F2(x)
{
  def FC(y) { 2 * y + x }

  FC
}

def F1(x) { F2(x)(5) }

WriteLine(F1(100))

естественно 110.

Смысла он не имеет, но демонстриует одно из важных свойств языка — вычисления над фукнциями. Практически все тоже самое, но более грамоздко можно сделать и на C# 2.0. Вот аналогичный код:
using System;

delegate int MyDelegate(int x);

class Program
{
    static MyDelegate F2(int x)
    {
        MyDelegate FC = delegate(int y) { return 2 * y + x; };

        return FC;
    }

    static int F1(int x) { return F2(x)(5); }

    static void Main()
    {
        Console.WriteLine(F1(100));
    }
}


Думаю, вряд ли тот кто понимает последний код не поймет предыдущие варианты.

FDS>Или, например, я не нашёл ответ на вопрос: могу ли я во время компиляции выделить макросом кусок уже разобранного nemerle кода и выполнить с ним специфические действия (например, проверку на освобождение ресурсов или на диапазон выходных значений по заданным входным и выходным)?


Такие вопросы можно задать на форуме. Если вопрос действительно интересен, то отвечу — можно. Хотя это и не тривиально.

FDS> Могу ли я во время компиляции выполнить некоторые операции программы пользователя в штатном режиме (что-то вроде встроенного ЮТ)? [и как мне это сделать и где это описано]


Хм. До окончания компиляци кода копилируемого приложения нет. Так что выполнить его невозможно. Юнит-тесты можно вмонтировать в код сборки или даже незаметно создать еще одну сборку с юнит-тестами.

В общем, макросы — это код который выполняется во время компиляции другого кода. Другой код исполнить можно толко если его докомпилировать.

FDS>Может это и есть где-то, но я не заметил


На такие вопросы ответы в документации найти невозможно в принципе. Но их можно задать на форуме.

FDS>Если я макросом генерирую другой макрос, как мне избавиться от квазицитирования,


Насколко я знаю макросом нельзя сгенерировать другой макрос.

FDS>Почему это:

FDS>
FDS>macro m(x: int)
FDS>{
FDS>    for (mutable i = x - 1; i >= 0; i--) 
FDS>    {
FDS>        <[
FDS>            System.Console.WriteLine("ss {0}", $x);
FDS>        ]>
FDS>    }
FDS>//    <[()]>
FDS>};

FDS>----
FDS>macro1.n:14:1:14:25: ←[01;31merror←[0m: in argument #2 (tl) of list[System.Objec
FDS>t-], needed a list[Nemerle.Compiler.Parsetree.PExpr.Literal-], got list[int-]: c
FDS>ommon super type of types [Nemerle.Compiler.Parsetree.PExpr.Literal, int] is jus
FDS>t `System.Object', please upcast one of the types to `System.Object' if this is
FDS>desired
FDS>

FDS> даёт ошибку (приведена после черты)?

Видимо потому что нужно как-то так:
macro m(x : int)
{
  mutable result = [];

  for (mutable i = x - 1; i >= 0; i--) 
    result ::= <[ System.Console.WriteLine("ss {0}", $(x : int)); ]>;

  <[ { ..$result } ]>
}

1. Макрос обязан вернуть одно выражение. Тут же их много, так что нужно завернуть их в блок. Последняя команда как раз это и делает. В цикле же формируется список выражений которые потом помещаются в блок.
2. Параметр х является целым числом для макроса, а требуется литерал. Тут требется подсказка компилятору, что нужно преобразовать значение из переменной х в литерал. Конечно компилятор мог бы быть и по умнее. Но и так не плохо по сравению с тем что приходится вытворять в подобных случаях при других способах генерации кода.

FDS>В общем, некоторые вопросы рассеялись, когда я думал, что мне непонятно конкретно. Но всё равно, ощущение такое, что макросам нехватает целостности (строгости концепции).


С концепциями у них все в пордядке. Вот качественного описания действительно нехватает. Да и сообщения об ошибках могли бы быть по внятнее.

FDS>Локальные функции круче Хотя теперь не придётся создавать массивы.


Незнаю причем тут массивы, но я бы поставил паттерн-матчинг выше по значимости. Кслати, его очень удобно исползовать в тех самых локальных фукнциях.

VD>>2. Локальные функции.


FDS>В Delphi есть, кстати, безопаснее (хотя и менее функционально). Там, по крайней мере, нельзя написать то, что я привёл выше .


В Дельфи как локальные функции и на ёту не приближаются к этим. Эти являются замыканиями и могут использовать весе что объявлено перед ними.

А вот безопасными они как раз не являются. Дельфи вообще не безопасный язык. Если передать адрес на них извне основной функции будут еще те вылеты. В Дельфи НЭТ конечно все лучше.

FDS>Вообще говоря, непонятно, почему они безопасностью пожертвовали ради передачи вложенных функций в вызовы другим [невложенным] функциям


Где ты увилил жертву безопасности? Это Дельфи небезопасна в туче мест. А Немрле один из самых безопасных языков которые я видел.

Что ты понимаешь под термином "безопасно" и "небезопасно".

VD>>4. Вывод типов.

FDS>Так и не понял, что это даёт. Кроме экономии кода, конечно (кажется, это уже обсуждали на форуме?)

Это и дает. Лишнего в коде нет. Код становится короче и стало быть понятнее. Если нужно изнать тип чего-то, то просто подвидишь мышьку в IDE и смотришь хинт.

VD>>8. Частичное применение функций и операторов.

VD>>9. Сплайсебл-строки.
FDS>Не нашёл ни 9, ни 8. Может дадите ссылку на конкретный документ?

Все описано в статье
Автор(ы): Сергей Туленцев, Владислав Чистяков
Дата: 23.05.2006
Производительность труда программиста в основном зависит от самого программиста. Однако даже самый опытный и знающий программист мало что может без подходящего инструмента. Эта статья открывает цикл статей об одном из таких инструментов, еще мало известном среди программистов, но очень многообещающем. Язык Nemerle, о котором пойдет речь в этих статьях, на первый взгляд очень похож на слегка улучшенный C#, но привносит многое из передовых исследовательских языков. Данная статья рассказывает об отличиях Nemerle от C# (как наиболее близкого языка)и является неформальным введением в язык.
. Сделай поиск по статье на $" (бакс и ковычка) и почитай что там написано. Частичному применению посвящен отдельный раздел Частичное применение и другие операции над функциями и операторами
Автор(ы): Сергей Туленцев, Владислав Чистяков
Дата: 23.05.2006
Производительность труда программиста в основном зависит от самого программиста. Однако даже самый опытный и знающий программист мало что может без подходящего инструмента. Эта статья открывает цикл статей об одном из таких инструментов, еще мало известном среди программистов, но очень многообещающем. Язык Nemerle, о котором пойдет речь в этих статьях, на первый взгляд очень похож на слегка улучшенный C#, но привносит многое из передовых исследовательских языков. Данная статья рассказывает об отличиях Nemerle от C# (как наиболее близкого языка)и является неформальным введением в язык.
.

VD>>11. Бесплатная концевая рекурсия.


FDS>Не заметил, спасибо. Я думал, что они там все на функциональном программировании совсем свихнулись


Они дают в твое и мое распоряжение мощьные и удобные возможности. И глупо ими не пользоваться.

VD>>12. Краткий синтаксис работы со спискам и встроенные в язык списки.


FDS>А за чем они такие нужны (если их нельзя изменять)? В документации написано, что часто используются, но я так и не понял где


На этот вопрос нужно или ответить, что просто попробуй попрограммировать на этом языке и сам поймешь, или предложить почитать что-то о функциональном программировании, или написть здоровую статью. Последнее возможно, но трбует времени. Остальное можешь попробовать сам.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.