Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> V>Но если в языке нет break, continue, return, то без goto порой >> получается тот самый синтаксический оверхед и лишняя "искусственная" >> запутанность кода. >> Вот в ML и Haskell нет ни break ни return ни continue ни goto — ну по >> крайней мере в прямом смысле
C>Зато есть запутанность кода...
Не хочу ничего говорить по поводу у кого что запутано, но в любом случае, такие суждения лучше выносить только когда знаешь язык.
Потому что иначе могут схватить за руку.
Здравствуйте, eao197, Вы писали:
V>>Пролог — был как ядро в системе распознавания смысла текстов в одной тематической области. Обработка была на С++, связь по COM на VB, а интерфейс GUI на Дельфи.
E>Мне как-то пришлось наблюдать за развитием нескольких систем, ядро которых было написано на Prolog-е, а внешние интерфейсы к различным устройствам и пр. -- на C++. После того, как Prolog-разработчики решили открыть свое дело и покинули тот колектив, одна система зачахла сама по себе, а вторая была полностью переписана на C++ и успешно продолжила свое существование.
E>Хотя, возможно, там Prolog применялся не по месту, а как инструмент, которым очень хорошо владели основные разработчики.
Любой "устаканивнийся" алгоритм на Прологе (если это слово вообще применимо) можно переделать на императивном языке (пользуясь представлением о том, как Пролог-машина достигает целей). Правда, изменять этот императивный алгоритм будет весьма непросто. Зато на Прологе макетировать/отрабатывать весьма удобно. Если быстродействие устраивает, можно ничего никуда не переписывать.
Здравствуйте, GlebZ, Вы писали:
GZ>Честно говоря, полезнее будет GZ>
GZ>if (!something)somethingDo();
GZ>
GZ>Если у тебя особый случай, то лучше обособить в отдельную процедуру.
Это что, лекция по структурному программированию?
---------
Как один из факторов целесообразности декомпозиции в каждом конкретном случае, стоит кол-во связей, которые порождает декомпозиция. В общем, нафига тело цикла из 5 строк выносить во внешнюю процедуру, если это тело может использовать до 10 переменных/параметров и быть использовано однократно?
Здравствуйте, vdimas, Вы писали:
E>>Хотя, возможно, там Prolog применялся не по месту, а как инструмент, которым очень хорошо владели основные разработчики.
V>Любой "устаканивнийся" алгоритм на Прологе (если это слово вообще применимо) можно переделать на императивном языке (пользуясь представлением о том, как Пролог-машина достигает целей). Правда, изменять этот императивный алгоритм будет весьма непросто. Зато на Прологе макетировать/отрабатывать весьма удобно. Если быстродействие устраивает, можно ничего никуда не переписывать.
Проблема была не в том, что быстродействие не устраивало или еще чего-то технического. Проблема была в том, чтобы нанять или подготовить специалистов достаточного уровня знаний, чтобы продолжить развитие уже существующего кода на Прологе. Дешевле оказалось просто переписать.
ИМХО. Когда я изучал Пролог в уневере, то довелось заглянуть в исходники одной a-la экспертной системы. С тех пор мне кажется, что пролог -- это хороший способ шифрования собственных мыслей -- никто, кроме автора их уже не прочитает. Да и автор тоже, если нить рассуждений забудет
Но настаивать на этом утверждении не буду, т.к. очень вероятно, что я просто видел примеры плохих программ на Прологе.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, vdimas, Вы писали:
V>Это что, лекция по структурному программированию?
Никоим образом. Мысль вслух.
V>--------- V>Как один из факторов целесообразности декомпозиции в каждом конкретном случае, стоит кол-во связей, которые порождает декомпозиция. В общем, нафига тело цикла из 5 строк выносить во внешнюю процедуру, если это тело может использовать до 10 переменных/параметров и быть использовано однократно?
Иногда смысл всей программы состоит из 5 строк, или даже в одной.
В данном случае у нас два несвязанных вопроса.
1 — стоит ли выносить процедуру, если у нее получается 5 строк.
2 — что делать если у тебя получается 10 параметров.
Что касается 10 переменных/параметров, то если ты такое получил, значит в этом есть смысл и его можно выносить в отдельную структуру. Это кстати и ограничивает связи.
Что касается 1 пункта, то можно выносить и одну строку в отдельную процедуру, даже если нет повторного использования, но зато получаем более читабельную главную процедуру.
Ну и на 3, вынужден сказать что связи важны для разных сущностей(классы, компоненты). На уровне процедуры, наличие большого количества связей не оказывает такого влияния, поскольку собраны и подконтрольны в одном месте. Все это некриминально, пока это можно читать.
Здравствуйте, eao197, Вы писали:
E>Но настаивать на этом утверждении не буду, т.к. очень вероятно, что я просто видел примеры плохих программ на Прологе.
Это точно, лучше не настаивать. После одного хорошего подхода к Прологу, начинаешь легко читать текст, и перестаешь понимать как это можно реализовать в других языках. Сфера применения для Пролога достаточно узкая, но зато ведение такой программы(а после 2 дней трепыхания начинаешь его понимать с полуслова) очень удобна.
Здравствуйте, Cyberax, Вы писали:
>> Когда iterator.hasNext() = false
C>В данном примере все просто. А если этот поток используется в десяти C>местах в программе (т.е. если это log-файл)? Когда следует закрывать его?
Пример с одним поток слишком прост. Нужно рассмотреть два потока с перекрывающимся, но не идеинтичным, временем жизни.
Другое дело, что смысла в таком примере особого нет
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Пример с одним поток слишком прост. Нужно рассмотреть два потока с перекрывающимся, но не идеинтичным, временем жизни.
ANS>Другое дело, что смысла в таком примере особого нет
Не обязательно. Вполне можно представить себе процесс A, который записывает данные в файл для процесса B, а после записи стартует B. Если процесс A не позаботится о корректном закрытии и флушировании файла, то B может вообще ничего не прочитать.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, Cyberax, Вы писали:
>>> Когда iterator.hasNext() = false
C>>В данном примере все просто. А если этот поток используется в десяти C>>местах в программе (т.е. если это log-файл)? Когда следует закрывать его?
ANS>Пример с одним поток слишком прост. Нужно рассмотреть два потока с перекрывающимся, но не идеинтичным, временем жизни.
да легко
как раз монады такие вещи очень лихо формализуют
просто идет инверсия и хэндл сверху отдается внутрь — вообще странно, это даже в ООП-мире успело появиться в виде стандартного паттерна — inversion of control (dependency injection)
Здравствуйте, reductor, Вы писали:
>>>> Когда iterator.hasNext() = false
C>>>В данном примере все просто. А если этот поток используется в десяти C>>>местах в программе (т.е. если это log-файл)? Когда следует закрывать его?
ANS>>Пример с одним поток слишком прост. Нужно рассмотреть два потока с перекрывающимся, но не идеинтичным, временем жизни.
R>да легко R>как раз монады такие вещи очень лихо формализуют R>просто идет инверсия и хэндл сверху отдается внутрь — вообще странно, это даже в ООП-мире успело появиться в виде стандартного паттерна — inversion of control (dependency injection)
С IoC возможна такая ситуация:
---++++++++++
-******____!!
тире — это типа нет открытых файлов.
+ и * — открытые файлы.
_ — это когда файл д.б. закрыт, но еще живёт
!! — это сработала финализация.
R>вообще вариантов куча даже без этого.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Pzz, Вы писали:
Pzz>>Я как-то был поражен, зайдя в знакомую контору, и обнаружив, что там Pzz>>собралась толпа программистов, и обсуждеает, как им выкрутиться из Pzz>>очередной нетривиальной проблемы, которую поставил перед ними C++. Как Pzz>>эта проблема содержательно соотносилась с решаемой задачей, я так и не Pzz>>понял...
К>Не факт, что это язык поставил проблему. Может быть, проблема была в архитектуре, а специфика мировосприятия программистов перевела её на рельсы кодирования.
Переведи...
"Москва слезам не верит"
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, reductor, Вы писали:
>>>>> Когда iterator.hasNext() = false
C>>>>В данном примере все просто. А если этот поток используется в десяти C>>>>местах в программе (т.е. если это log-файл)? Когда следует закрывать его?
ANS>>>Пример с одним поток слишком прост. Нужно рассмотреть два потока с перекрывающимся, но не идеинтичным, временем жизни.
R>>да легко R>>как раз монады такие вещи очень лихо формализуют R>>просто идет инверсия и хэндл сверху отдается внутрь — вообще странно, это даже в ООП-мире успело появиться в виде стандартного паттерна — inversion of control (dependency injection)
ANS>С IoC возможна такая ситуация:
ANS>---++++++++++ ANS>-******____!!
ANS>тире — это типа нет открытых файлов. ANS>+ и * — открытые файлы. ANS>_ — это когда файл д.б. закрыт, но еще живёт ANS>!! — это сработала финализация.
Нет никаких файлов со стороны клиентского кода — есть стандартные интерфейсы в виде тех же итераторов или чего угодно.
Ну и состояния системы без оглядки на всякие файлы и прочее — не царское это дело.
Логическое ядро системы не должно вообще оперировать такими сомнительными понятиями как файл, база данных или сетевое соединение.
Все эти вещи должны быть снаружи и инжектиться в виде стандартных интерфейсов тех же коллекций или наоборот вытягиваться внешними сервисами в виде тех же стандартных интерфейсов.
Как-то так.
Со скидкой на оо-buzzwords
В том же хаскеле вообще скорее немыслимо это все слить воедино — монады все равно "кексик послайсят" и все само разделится на элементарные части (дико клевый между прочим побочный эффект от них).
R>>вообще вариантов куча даже без этого.
ANS>"Поднимите мне веки"
всякие каналы и lightweight continuation-based процессы. да мало ли
способов заменить много физических действий одним логическим существует больше, чем языков программирования
Здравствуйте, AVC, Вы писали:
К>>Не факт, что это язык поставил проблему. Может быть, проблема была в архитектуре, а специфика мировосприятия программистов перевела её на рельсы кодирования.
AVC>Переведи...
Давным-давно один человек (не буду тыкать пальцем ) придумал, что печать страницы с переменной информацией можно представить как вычислительную сеть, промежуточные узлы которой — счётчики, слушатели com-порта и т.п., главный источник — фотодатчик на конвеере, главный приёмник — модуль рендеринга страницы.
Изначально задумывалось, что сеть асинхронная (часть данных может приходить загодя, или вообще в ином темпе, чем осуществляется печать; кроме того, одновременно сосуществуют до четырёх задач печати — обычно изолированных друг от друга, но, может быть, и пересекающихся).
Поэтому каждый узел сам занимается рассылкой извещений. Соответственно, каждый из них защищает себя мьютексом.
Предполагалось, что сеть сначала развёртывается, затем работает, затем задача останавливается и сеть прибивают.
Но жизнь внесла свои коррективы: возможна такая ситуация, что сеть начали прибивать (со стороны приёмника в сторону передатчиков), а в это время один из передатчиков — внешний по отношению к задачам — заряжает туда данные. И в некотором месте они сталкиваются. Беда в том, что сталкиваются две лавины: если одну из них заблокировать, то получим дедлок. А если одну лавину обломить и затем повторить попытку ещё раз — не факт, что и эта попытка будет успешна. В самом худшем случае сеть просто рвалась, создавая объектов-вдов (которые принимали данные, но никуда их не отправляли — и стремительно выжирали память).
Так вот. На низком уровне — стоял вопрос: как бы так грамотно сделать, чтобы разослать данные потребителям, выйдя из-под мьютекса (но не порушив самого себя). Да ещё всё осложняется, что мьютекс рекурсивный, то есть,
не гарантирует, что в момент рассылки объект не заблокирован.
А сделать глобальный мьютекс на всю систему (типа, умерла так умерла, рассылаем так рассылаем) — нельзя, потому что лавина — штука медленная, и пока одна задача работает, остальные три будут куковать.
Как вариант, можно делать отложенное выполнение рассылки — тогда придётся отслеживать, жив ли объект-приёмник. Чтобы указатель на него в очереди был валидным, требуется контроль живучести — например, на подсчёте ссылок. Тогда приёмник должен различать, был ли он демонтирован (и теперь просто доживает последние миллисекунды) или он очень даже функциональный.
Видите, как архитектурный просчёт (выбор избыточной и плохо контролируемой модели, а затем забыли юз-кейс свёртывания-развёртывания на лету) свалился до уровня вопросов "какие подфункции и как вытащить из-под мьютекса" и даже "как бы так сделать трёхступенчатую деструкцию объектов (узлов сети / COM-объектов / С++-объектов)", и чтобы это было детерминированным (проблема объектов-вдов) и в то же время не совсем ручками (приветствуются GC и RAII).
Засада, правда, в том, что не только архитектуру менять, но и "в основном работающий" код переписывать — нельзя. Первая бета прошла, по срокам не впишемся.
(Это ещё и характеризует баг менеджмента — но тут уж нам ничего не поделать).
Здравствуйте, reductor, Вы писали:
R>В том же хаскеле вообще скорее немыслимо это все слить воедино — монады все равно "кексик послайсят" и все само разделится на элементарные части (дико клевый между прочим побочный эффект от них).
О, кстати! Покажи, как монады могут кейс послайсить. А то что-то нету ясности в голове.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, reductor, Вы писали:
R>>В том же хаскеле вообще скорее немыслимо это все слить воедино — монады все равно "кексик послайсят" и все само разделится на элементарные части (дико клевый между прочим побочный эффект от них).
К>О, кстати! Покажи, как монады могут кейс послайсить. А то что-то нету ясности в голове.
Ну как, даже простейшай операция типа | readFile "file" >>= reciever | уже порождает разделение на два очевидных компонента и дает понять, что мухи — отдельно.
Логически какая бы ситуация не произошла, на reciever она не влияет даже если мы это перепишем как привыкли
можно конечно навесить на это errorHandler и таки потом пропихнуть куда нужно бесполезную информацию, но это будет так дико выглядеть, что хочешь не хочешь, а ясность придет. сама. и не уйдет.
В случае с более обширными вещами и эффекты могут быть интереснее
Вообще, подозреваю, монады могут быть формализмом чуть ли не для всех идиом, что программирование придумало до них. А не только для состояний, деструктивных апдейтов и ввода-вывода.
А то вот лично у меня по поводу глобальных переменных всегда была непонятка — что они выражают вообще такое и какая связь между модулями, которые ее вместе используют. И меня это всегда здорово напрягало, когда я не мог себе объяснить почему я сам сделал так, а не иначе. Или еще хуже — когда не мог решить как сделать.
А сейчас вот не думаю, хожу в каске и хихикаю, да тряпки жгу.
Здравствуйте, GlebZ, Вы писали:
GZ>А в чем тут баг менеджмента?
В том, что довели до беты, а потом взялись тестировать по-настоящему. Ну и поправки к спецификациям в последний момент — как образ жизни.
Я бы сейчас на пушечный выстрел не подошёл к той идее, которую закладывали ещё аж в 1997 году. Слишком много тонких мест в ней. Впрочем, если бы тогда её не воплотили — не факт, что узнал бы об этих тонких местах вообще.
Это я так, на жизнь жалуюсь. Вроде бы конкретную проблему пофиксал — но удовольствия никакого: как будто собственные шерстяные носки бельевой верёвкой заштопал.
Здравствуйте, vdimas, Вы писали:
V>>>Соответственно, в тех языках, где нет break, continue и return вполне можно можно использовать goto, если использовать ег ос той же "аккуратностью", какую мы получаем в случае break, continue, return.
VD>>Да, да. Полностью согласенж. Если писать с должной акуратностью, то х86-ассемблер лучший язык программирования.
V>х86-ассемблер — #авно полное, по сравнению со многими другими (Dec, MC68XXX, PICXX) но речь шла не об этом.
Ну, давай поспорим какой из ассеблеров лчший из языков программирования. Мне вот x86 нравится. У него код из далека выглядит стройнее. Такие три колоночки... очень эстетично знаете ли.
V>Но если в языке нет break, continue, return, то без goto порой получается тот самый синтаксический оверхед и лишняя "искусственная" запутанность кода.
Не, не. Не отвлекайся. Давай уж поговорим о превосходстве Дековского ассемблера над разумом.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Ну, давай поспорим какой из ассеблеров лчший из языков программирования. Мне вот x86 нравится. У него код из далека выглядит стройнее. Такие три колоночки... очень эстетично знаете ли.
А мне forth-ассемблеры нравились, знаешь ли... Очень удобно было производить манипуляцию битами и при этом вся мощь собственного фреймворка прямо в строках программы на ассемблере.
V>>Но если в языке нет break, continue, return, то без goto порой получается тот самый синтаксический оверхед и лишняя "искусственная" запутанность кода.
VD>Не, не. Не отвлекайся.
Я??? Это ж ты толкнул про ассемблеры. А я про goto. Во многих ассемблерах, кстати, goto тоже вещь не тривильная. Не всегда можно вот так запросто сделать jump (jmp, jp, etc). Иногда только через приседания.
VD>Давай уж поговорим о превосходстве Дековского ассемблера над разумом.
Удачная разработка — она и в африке удачная разработка. Говоря об удачности ассемблера имеют ввиду, разумеется, удачную систему команд проца.