Здравствуйте, AleksandrN, Вы писали:
AN>Первое сообщение в этой теме сделано в 2012 году и за это время только 3 редактора появилось. Но в них и близко нет возможностей современных IDE, например — перехода к объявлению функции и поиска мест, где она используется. Так и не сделан контроль версий.
Ну, это не аргумент. Скажем для Немерла или Нитры тоже не хватает ресурсов качественную ИДЕ замутить. Но не от того, что языки плохие, а из-за того, что тупо нет людей готовых выделить средства.
Но вот я за недельки сбацан на них новый ДСЛ и таки душа радуется. Ни на каких Шарпах или СыПлюсПлюс такое за такие сроки не возможно сделать. А если вложить денег, то можно такие вещи не за неделю делать, а за пару дней.
Дракон это — тупо рисовалка блок-схем. Сделать к ней финтифлюшки вроде навигации более чем можно. Вопрос лишь в том, что за задачи он позволит решать (хоть с ними, хоть без них). Наверно есть класс задач, который он решит. Но согласен с Синклером — это точно не про корректность программ и не про AI.
AN>Это не способствует удобству работы и уменьшению числа ошибок.
+1
AN>В статье и комментариях много говорится про то, что goto это плохо, но посмотрим на
AN> goto item_677;
Опять каша в мыслях. Сгенерированный код смысла читать нет. Генерировать можно и ассемблер, и Си, и MSIL. Это низкоуровневый язык генерации. Тебя ж не смущает, что в машкодах и ассемблере нет структурных операторов? Ты же их не читаешь? Собственно и генерацию можно улучшить. Просто блок-схемы они тяготеют к goto и проще на них отображаются. Но при некотором старании можно и в if-ы переписать. Почти любые goto можно в if-ы переписть. Возьми любой декомпилятор — это оно и есть.
Проблема Дракона не в этом. Проблема в том что ты написал выше. Нужно много экранов для описания вполне простых вещей. Т.е. выразительность блок-схем на сложных алгоритмах хромает.
Вот потому лично я тяготею к DSL-ям. Где выразительность рвет все пределы дозволено.
AN>В этом коде goto применяется. Противоречие со статьёй.
В Драконе их нет. Так что не гони.
AN>А теперь, сравним с кодом, написанным традиционным способом
AN>AN>int String_Compare(
AN> const struct String* left,
AN> const struct String* right
AN>)
AN>{
AN> int result = 0;
AN> for ( int i = 0; i < left->Length && i < right->Length && !result; i++)
AN> result = left->Buffer[ i ] - right->Buffer[ i ];
AN> if ( !result )
AN> result = left->Length - right->Length;
AN> // Что бы возвращаемый результат был в том же виде, что и у сгенерированной функции.
AN> if ( result < 0 )
AN> result = -1;
AN> else if ( result > 0 )
AN> result = 1;
AN> return result;
AN>}
AN>
Откровенно говоря тоже говнокод. Я бы это написал как-то так:
Compare(xs : string, ys : string) : int
{
| (x : tailX, y : tailY) when x != y => x - y // строка состоит из символов префиксов и продолжения и префиксы не равны
| (x : tailX, y : tailY) when x == y => Compare(tailX, tailY) // тоже самое но префиксы равны, продолжаем рекурсивно...
| ([], _ : _) => 1 // xs содержит пустой список, а ys - нет.
| (_ : _, []) => -1 // наоборот
| ([], []) => 0 // все символы равны и списки пусты
}
Вот это как-то ближе к идеалу. Сводим все к рекурсии и абстракции списка. А твой императивный говнокод читается не лучше дракона, хотя он и пушистее. Вопрос ведь не в занимаемой площади на экране, а в том насколько просто код понять.
Ну, а от объемов позволяет избавиться банальное процедурное программирование. Вводим именованную функцию и она может скрыть любой по сложности алгоритм.