Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Что-то мне так не показалось. Скорее уж популярно псевдологическое: "кто не следует за большинством, тот совершает глупость". Разницу не чуешь?
если уж делать выводы на основании популярности и распространенности, то это утверждение вполне логично. А то я здесь видел немало размышлений о том, что использование малораспространенных языков придает некой "элитарности" и прочих непонятно-мистических вещей.
На самом деле те, кто поумнее, больше думают о качествах собственно языка, а не его популярности или модности. Но почему-то каждый раз, когда речь идет о конкретных фичах, всё завершается криками "да это просто язык для элиты, всяким гоям не понять"
ГВ>Вот интересный момент. Когда радетели следования за большинством начинают пинать меньшинство (просто в силу количественных показателей), это самоутверждением не считается. В обратной ситуации сразу же крик про "самоутверждение". Как думаешь, в чём тут дело?
наверно в том, что делать выводы на основании некой "элитарности" — глупо. см предыдущее сообщение
мэйнстрим же, при всей избитости этого понятия, не содержит откровенно неудачных практик — иначе он не стал бы мэйнстримом.
если возникает необходимость делать обработку исключений в зависимости от некоторых условий (продолжить, прервать работу), то здесь просто напрашивается паттерн "стратегия". и никаких проблем
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Beam, Вы писали:
B>>Ensure — это аналог try-finally в других языках
VD>Что очень неудобно, надо признать.
Что неудобно? Использовать try-finally при работе с ресурсами?
Странные Вы вещи говорите, однако ...
И возвращаясь к теме. Так что надо делать в Nemerle, чтобы не натыкаться в макросах на продемонстрированные "грабли"?
Здравствуйте, IT, Вы писали:
IT>Из этого примера хорошо видно, что анонимный делегат и замыкания в C# — это не более чем синтаксический сахар. Хотя, надо признать, весьма полезный.
Угу я тоже знаю людей программирующих на C++, но думающих в терминах ассемблера
Иногда от этого есть польза, но в большинстве случаев только вред.
Здравствуйте, VladD2, Вы писали:
VD>У тебя в корене не правльные посылы. Идея писать код в рассчете на побочные эффекты возникющие спантанно сама по себе ущербна.
Идея писать код без учета т.н. exception safety не менее ущербна.
VD> Логика болшинства приложений и так сложна, чтобы усложнять ее пдобным контролем.
Именно поэтому писать exception safety код очень сложно и этим часто пренебрегают. Или даже не догадываются о том, что написанный код не является exception safety.
VD>К тому же закладываться или не закладываться здесь в общем-то не так важно. Важно другое. Важно, что ты уже не можешь читая код делать предположение о его последовательности. Так читая код на C# я могу быть уверненым, что длинное выражение что бы не вычилсялось всегда попадет в переменную, если оно стоит с права от присонения ей значения. И я всегда уверен, что управление из этого вражения перейдет на следующую строку, а не убежит черти куда.
Такие рассуждения еще можно применять к C (и то без учета всяких longjmp-ов) или к Виртовскому Паскалю. Но вот по отношению к современным языкам, в которых бросание исключений является основным способом информирования о любых ошибках, такие рассуждения звучат, по меньшей мере, наивно.
Для разминки, уверен ли ты, что переменная dataRows всегда получит причитающееся ей значение в таком примере:
А теперь представь, что makeDataSpecificExtension это блок в SmallTalk или Ruby. Выполненый из него return прерывает данное выражение точно так же, как и выброшенное где-нибудь в load() исключение. Поэтому, если использующий блоки кода фрагмент написан в соответствии с принципами exception safety, то ему безразлично, был ли он прерван исключением или нелокальным return-ом.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, IT, Вы писали:
IT>Нет, не приходило. Лисп является тем функциональным ископаемым, на котором построены все остальные, могущие похвастаться, что обладают тем, чего нет в мейнстриме. А мейнстрим сейчас медленно, но уверенно переваривает и впитывает из этого всё лучшее.
Нет после лиспа уже было много вещей которых в нем нет и вряд ли уже будут.
И вообще пока мейнстрим будет давится и с отрыжками переваривать функциональщину, новое може появится совсем в другом месте
VD>Интересно сколько нужно времени и сил, чтобы такими очевидными вещам прониклись современные "ОО-программеры"? И интересно какого черта это не видят ни в МС, ни в Сан?
Ну это легко подcчитать. Из даты начала рекламной компании Nemerle на rsdn вычесть дату первого относительно большого обсуждения функциональщины здесь же
VD>Собственно этим и отличается динамический язык от статического. С одной стороны чуть проще, так как подобные хаки не требуют специальных вызовов вроде Convert.ToDouble(elem) (все приводится автоматом),
Ну наконец-то . Полностью согласен, за это и любят динамические языки.
VD>но с другой постоянно можно получить рантайм-ошибку. Это приводит к юнит тестированию на каждый чих и т.п.
Тоже верно, просто каждый для себя делает свою оценку этих плюсов/минусов, на основе своего опыта. Теоретизировать на эту тему смысла нет.
И еще замечу такую странность , те кто реально программирует на динамических языках — этот недостаток не считают фатальным (в сравнению с получаемыми упрощениями). А те кто только теоритически рассуждает — считают фатальным.
Для реальной работы роль играет не токо на скоко в языке есть те или иные возможности, но и на скоко качетсвенны и функциональны IDE для них, а в этом плане с мегабаблом вкладываемым MC в VS и .Net тягаться уже сложнее.
Здравствуйте, Сергей Туленцев, Вы писали:
VD>>В общем, исключения совершенно нормальное и полезно средство бработки нештататных ситуаций. Но вот основную логику приложения на них делать ни в коем случае не стоит. Это чревато многими проблемами. Тут тебе и усложнение отладки. И неконтролируемая передача управления. Хот даже тут бывают исключения. Но они обычно ближе к хакам, а те сами не желательны.
СТ>Никто не говорит, что на них надо делать основную логику работы приложения.
+1
СТ>Есть у нас некий анализатор (функция верхнего уровня). Она может парсить логи. Логи хранятся в файлах и состоят из записей |entries). СТ>Так вот, предположим, что в процессе работы parse-log-entry ей встретилась запись неправильного формата (malformed entry). Она и знать не знает о том, что ей делать в таком случае, потому выбрасывает исключение. parse-log-file тоже не знает, что делать, и пробрасывает его дальше (прерывая тем самым обработку файла в милллон записей). То же и с analyze-log, плюс еще теряется информация о том, какой именно из тысячи файлов мы только что обрабатывали. И вот наконец, дело доходит до верхнего уровня, который знает про "политику партии", что же далать в таких случаях. Но, как я уже говорил, поздняк метаться. Восстановиться мы уже не сможем. А могли бы. Например, пропустить эту запись. Или исправить формат записи и попробовать прочитать еще раз.
Данный пример, имхо, как раз не очень показателен. По крайней мере, реализация parse-log-entry с расчетом на перехват исключений и иницирования иного parse-log-entry в C++ будет слишком дорогим решением с учтом стоимости try/catch на каждую из миллионов строк логов. Более разумно здесь было бы использовать коды возврата из parse-log-entry, как более дешевый вариант.
Хотя сложный парсинг файлов как раз иногда требует организации нескольких вложенных циклов с разными условиями выхода из них, а в некоторых случаях и продолжения с точки прерывания какого-либо внутреннего цикла. Здесь локальная логика на исключениях может сильно упростить жизнь.
Например, мне требовалось производить разбор write-ahead-log файлов, каждый из которых состоит из страниц фиксированного размера. Каждая страница снабжается служебной информацией + контрольная сумма, и содержит часть описания транзакции. Транзакция может занимать несколько последовательно идущих страниц. Каждый write-ahead-log файл (у меня они называются trace-файлы) имеет ограничение на размер. Если транзакция не поместилась полностью в один trace-файл, то она продолжается в следующем файле.
При извлечении описания транзакции из таких trace-файлов нужно учитывать разные условия, как то: повреждение одной из страниц (несовпадение контрольной суммы), отсуствие какой-либо из страниц транзакции, преждевременное завершение trace-файла. Для алгоритма чтения trace-файлов все это, штатные ситуации. А на более верхнем уровне об этом вообще не нужно знать, нужно всего лишь знать, удалось ли прочитать очередную транзакцию или же просмотр завершен. Использование транзакций в этом случае мне показалось довольно простым решением реализации логики чтения подобных файлов:
/* Это самая высокоуровневая функция чтения описания транзакции. */bool
reverse_loader_t::next(
const oess_1::char_t * & image,
oess_1::uint_t & image_size,
trace_file_number_set_t & used_traces )
{
try
{
if( !m_is_current_file_open )
try_open_next_file();
/* Вот здесь идет основной алгоритм поиска. */
find_trx();
image_size = m_image_len;
image = &m_image[ 0 ];
used_traces = m_used_traces;
return true;
}
catch( const end_of_trace_ex_t & )
/* Данное исключение всего лишь свидетельствует об
окончании всех trace-файлов и означает, что больше
ничего не найдено. */
{}
return false;
}
void
reverse_loader_t::find_trx()
{
// Перебираем все страницы в цикле.
// Игнорируем битые страницы и транзакции.
// Вылетаем только по исключениям.while( true )
{
// Поиск должен начинаться заново.
reinit_search();
try
{
find_first_trx_page();
pop_up_trx();
return;
}
// Эти исключения в данном контексте вполне уместны.
// На следующей итерации мы просто начнем поиск заново
// полностью проигнорировав все, что уже успели найти.catch( const broken_page_ex_t & )
{
/* Битая страница всего лишь означает начало
поиска следующей транзакции. */// Ошибочную страницу нужно пропустить, чтобы
// не инициировать бесконечный цикл.
go_to_next_page();
}
catch( const broken_trx_ex_t & )
{
/* Битая транзакция всего лишь означает начало
поиска следующей транзакции. */
}
}
}
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Курилка, Вы писали:
К>>Задача хорошего языка — легко и удобно выражать мысли программиста так, чтобы их понимал компьютер. Или у тебя есть какие-то другие идеи?
VD>У меня другие. Компьютер без проблем понимает тупой язык вроде ассемблера. Так что я пишу код для других людеф и для себя в частности. Ну, а то что этот язык понимает и компьютер (точнее компилятор) это уже частности.
VD>Это я к тому, что клавное в языке выразительность для программиста.
А читать, значит, написанное мы не будем, так?
Или тупой ассемблер у тебя == мыслям программиста?
Здравствуйте, Сергей Туленцев, Вы писали:
СТ>поздняк метатться, стек то размотан уже.
СТ>На всякий случай: умного мужика зовут Pieter Seibel, и пример был подслушан на его выступлении на тему своей книги (Practical Common Lisp)
А, ну это понятно. Просто ни в CL ни в ST стек не разрушается при поиске обработчиков.
Здравствуйте, FDSC, Вы писали:
FDS>И что, это намного хуже и сложнее? И наверняка быстрее работает, чем перехват повторно вызывающихся нелокальных возвратов.
И первый и второй вариант твоей программы не правильные. У тебя и там и там 2 ошибки в коде и 2 ошибки в дизайне. Что на на таких примерах можно продемонстрировать я не понимаю.
Здравствуйте, Дарней, Вы писали:
ГВ>>Что-то мне так не показалось. Скорее уж популярно псевдологическое: "кто не следует за большинством, тот совершает глупость". Разницу не чуешь? Д>если уж делать выводы на основании популярности и распространенности, то это утверждение вполне логично.
Вот именно. Если делать делать выводы на основании популярности и распространённости.
<< Под музыку: silent >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, Сергей Туленцев, Вы писали:
СТ>>поздняк метатться, стек то размотан уже.
СТ>>На всякий случай: умного мужика зовут Pieter Seibel, и пример был подслушан на его выступлении на тему своей книги (Practical Common Lisp)
ANS>А, ну это понятно. Просто ни в CL ни в ST стек не разрушается при поиске обработчиков.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Вот именно. Если делать делать выводы на основании популярности и распространённости.
осталось еще понять, что кроме популярности есть второй фактор — время. И если за n>10 лет язык остался широко известен в узком кругу фанатов, то делать некоторые выводы из этого таки можно.
Здравствуйте, Дарней, Вы писали:
ГВ>>Вот именно. Если делать делать выводы на основании популярности и распространённости.
Д>осталось еще понять, что кроме популярности есть второй фактор — время. И если за n>10 лет язык остался широко известен в узком кругу фанатов, то делать некоторые выводы из этого таки можно.
Eiffel, например. Совсем таки не элитарный язык, а непосредственный конкурент Java и C#, да еще и появившийся гораздо раньше. Оказался в заднице благодоря маркетингу.
Из операционнок таким же характерным примером является OS/2.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Eiffel, например. Совсем таки не элитарный язык, а непосредственный конкурент Java и C#, да еще и появившийся гораздо раньше. Оказался в заднице благодоря маркетингу.
ну что ж, непомерную жадность можно наверно и к области маркетинга отнести. Хотя по моему, это больше вопрос здравого смысла и специального образования маркетолога здесь не требуется
а вообще я про него мало что знаю, кроме того факта, что там есть инварианты — и это конечно плюс, хотя вряд ли решающий
что еще в нем есть интересного? есть ли какие-то серьезные преимущества перед C#, к примеру?
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Сергей Туленцев, Вы писали:
Д>если возникает необходимость делать обработку исключений в зависимости от некоторых условий (продолжить, прервать работу), то здесь просто напрашивается паттерн "стратегия". и никаких проблем
И как тебе этот паттерн вернёт управление в parse-log-entry?
В лисповских кондишнах рестарты изначально есть как механизм обработки ситуации, тогда как в "традиционных" подходах, если мы "провалились" по исключению, то обратного пути нет.