Здравствуйте, Дарней, Вы писали: Д>лучще приведи пример кода, где не жить не быть — но без нелокальных возвратов обойтись нельзя
Да нет такого кода. Но смысл я понял.
Там, где дотнету приходится делать два метода: FindFirst и Apply, смоллток обходится одним. Просто потому, что решение о том, продолжать итерацию или выйти "изо всего" принимается в "делегате".
В более сложных случаях давайте вспомним, как мы делали поиск по дереву. Конечно же рекурсия; и конечно же надо было обязательно оборудовать ее проверкой на продолжение и сохранением найденного элемента...
Если бы нелокальный возврат существовал бы в дотнете, это работало бы как-то так:
public interface IRecursible<T>: IEnumerable<IRecursible<T>>;
public static void ForEach<T>(T root, Action<T> action)
where T: IRecursible<T>
{
action(root);
foreach(T child in root)
ForEach(child, action);
}
Это мы так один раз объявили служебный метод. Его можно применять чтобы, например, выводить все дерево:
Тривиально, не правда ли? А теперь давайте кого-нибудь найдем:
public static MyItem FindFirstStartingWith(MyTtem root, string start)
{
ForEach(root,
delegate(MyItem t)
{
if (t.Name.StartsWith(start))
super return t;
}
);
}
Здесь я применил "новый" оператор super return, чтобы намекнуть на нелокальный возврат (в отличие от обычного return, который все равно приведет к ошибке компиляции из-за несовпадения типа получившегося анонимого делегата с Action<MyItem>).
На что стоит обратить внимание?
1. Все очевидно. Если знать, что такое супер-ретён.
2. Никакой нелокальности с точки зрения пользователя нет. Код — немногим хуже банального foreach.
3. При этом все-таки возврат может случиться с произвольной глубины стека — ведь Apply вызывает себя рекурсивно...
4. Мы обошлись без написания специального метода поиска в дереве, типа вот такого:
public static bool FindFirst(T root, Predicate<T> condition, out T result)
where T: IRecursible<T>
{
if(condition(root))
{
result = root;
return true;
}
foreach(T child in root)
{
if (FindFirst(child, condition, out result))
return true;
}
return false;
}
public static MyItem FindFirstStartingWith(MyItem root, string start)
{
MyItem result;
if (FindFirst(root, delegate(MyItem t) { return t.Name.StartsWith(start);}, out result))
return result
else
return null;
}
5. На самом деле в данном случае не нужен весь этот лишний мусор в виде FindFirst. И ForEach тоже не нужен. ForEach уже сделан. Им и надо пользоваться в таких случаях:
public static IEnumerable<T> IterateThrough<T>(T root)
where T: IRecursible<T>
{
yield return root;
foreach(T child in root)
foreach(T grandchild in IterateThrough(child))
yield return grandchild;
}
public static void PrintAll(MyItem root)
{
foreach(MyItem item in IterateThrough(root))
Console.WriteLine(item.Name);
}
public static MyItem FindFirstStartingWith(MyItem root, string start)
{
foreach(MyItem item in IterateThrough(root))
if (item.Name.StartsWith(start)
return item;
return null;
}
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали: VD>Ненадо переводить. return в С-подобных языках не анлогичен ^ в Смолтоке. Потому ты и начал им хвастаться. Вот только на поверку окалось, что его отличия — это то что опытные программисты так не любят в goto.
Да нет Влад. Ты преувеличиваешь. Злоупотребить крышкой в смолтоке очень трудно:
Опасность номер 1: для разработчиков библиотеки.
У тебя есть некоторый код, который вызывает переданный тебе делегат. Этот делегат может оказаться с "миной". Ее эффект на твой код сравним с исключением: управление передается не на следующую инструкцию, а стреляет вверх по стеку. Со всеми finally, разумеется, хоть и безо всяких catch.
В принципе, тебе и так надо писать код, который не приводит твои объекты в неконсистентное состояние от вылета исключения. Специально затачиваться на него не стоит — выше по стеку стоит соответствующий кэтч, который там написан с должным смыслом.
Можно специально затачиваться на случай, когда тебе передали "крышку", которая хочет вернуться в такое место, которого в стеке уже нет. Это — уже вполне настоящее исключение, которое ты опять же можешь обработать, а можешь не обрабатывать, в зависимости от того, чего ты имел в виду.
Опасность номер 2: для пользователя.
Можно попробовать передать блок с крышкой вверх по стеку, где его выполнение — гарантированная засада. Это ошибка, которую бы лучше ловить. В принципе, есть еще много спопобов случайно сделать ошибку такого рода. Хотя, возможно, такие вещи стоило бы отслеживать на уровне компилятора — ескейп анализ, и сразу говорим: "братан, крышку можно передавать только вниз по стеку, как и ссылки на локальные переменные. Вверх — низзя". Не дожидаясь, пока тестеры на это наступят.
Причем в большинстве случаев такого не случится, потому как анонимные блоки редко когда вообще передаются наверх. Это уже хардкорный код типа комбинаторов предикатов, в реальных проектах нужный только в 1% случаев.
А в 99% случаев семантика крышки ясна как божий день, и ни малейшего затруднения с пониманием, куда перейдет управление, у тебя не будет. А ведь только это и представляет проблему.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
VD>>Еще раз. У регекстов нет возможности превратить их в черный ящик. Возможно если бы это было возможно, то и использование их было бы более обширно. Создали бы библиотеку стандартных регексов и пользовались бы ими по имени. S>Гы-гы. S>
Здравствуйте, FDSC, Вы писали:
FDS>Я его тут скомпилировал. Прикол в том, что он у меня не работает: выдаёт exception. То ли у меня руки кривые и я его неправильно скомпилил, то ли не знаю что
Приведи текст исключения.
FDS>Хм, на самом деле, было бы неплохо, если бы это описывалось в документации. Первое, что мне в голову пришло — это именно анализ дерева.
В документации все не опишешь. Примеры там есть в общем-то. Но ёжику понятно, что на все вопросы не отвитешь. Так что проще задавать вопросы на форумах.
FDS>Видать, я жуткий бюрократ . А в каком их форуме задавать?
Пока что в Декларативно программировании.
FDS>Спасибо (вы ответили сразу на три моих вопроса), но не вечно же у вас спрашивать,
К сожалению, вечно действительно не получится. Хотя жаль.
FDS>кода проблемы появляются , а со спецификацией я бы сам разобрался
Думаешь у нас форум по донету лишний? На нем каждый день море вопросов. А ведь и по шарпу и по дотнету есть все спецификации.
FDS>Когда мне надо сопоставлять с образцом, я запихиваю образцы в массив (вместе с указателями на функции) и в цикле проверяю.
Ты просто плохо понимаешь о чем говоришь. Это надо прочувствовать.
FDS>В Delphi функции то же могут использовать всё, что объявлено перед ними (исключая переменные других локальных функций)
В Дельфи перед ними можно объявить только параметры внешних функций. В общем, это вещи не сравнимые.
FDS>Ага, а если нет интергации с MS VS (1. не могу скачать последнюю версию непомню уже чего, 2. нефига не понимаю и т.п., в общем у меня не работает даже "простая" интеграция с VS, точнее работает, но на половину )
А что не так?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, FDSC, Вы писали:
FDS>VladD2 говорит 100% правильно — так всё и есть. Спроси у любого. Лучше скажи, как вы в SmallTalk избегаете ошибок, связанных с неструктурным переходом. Вот это будет интересно послушать.
Как, как. Пишут небольшие приложения в одиночестве или пытаются не использовать подобные вещи (запрещать их). А возможно просто не видят проблем во все, а потом удивляются почему в очередной раз пришлось искать ошибку два часа.
В свое время когда мы писали на плюсах был четкий кодекс правильного поведения в который входили такие как не очищать ресрусты кроме как в конструкторах оберток. Не возиться с куказетеляи без оберток. Не использовать goto. И таких "не" было море. В принципе, привыкаешь и проблемы вроде как не лезут изо всех щелей. Вот только на контроль этих "не" уходит нехилая часть мога и времени.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
ИМХО, всё просто. По словам IT получается, что следование за большинством требует наличия "элементарной логики и здравого смысла" в большей степени, нежели следование за меньшинством. Если учесть, что эти самые "элементарная логика и здравый смысл" присущи умным людям, то можно предположить, что следующие за меньшинством менее умны, тем те, кто следует большинству. Ну и далее сводим к сказанному мной: "кто не следует майнстриму, у того нет ума". Если ты заметил, я не пытался дословно процитировать IT, я всего лишь метафорически обозначил тип такого высказывания. Возможны были и другие метафоры, но мне показалось важным выделить субъектную направленность, мол, те, кто следует большинству в большей степени нагружают свой "логический аппарат". А замена "большинства" на "майнстрим" смысла не меняет, ведь именно большинство составляет майнстрим, не правда ли? Ну или "майнстрим" может использоваться как синоним "большинства".
Вот так, или примерно так.
PS.: Дело, разумеется, не в минусе. А вот обвинение во лжи мне кажется безосновательным.
<< Под музыку: silent >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, FDSC, Вы писали:
FDS>>>Он считается некорректным, потому что со сслыкой на опыт невозможно спорить по причине того, что опыт у всех разный. ГВ>>Не подсказывай. FDS>Просто надоело читать, как один задаёт вопрос, а другой на него не хочет отвечать
Это ты погорячился, погорячился.
<< Под музыку: silent >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, vdimas, Вы писали:
V>У того, о чем речь
о чем идет речь? Не забывай, что здесь много веток обсуждения.
V>ставлю на то, что в личной беседе ты бы не рискнул вставить этот и ему подобные обороты
Здравствуйте, FR, Вы писали:
FR>Плохие программисты могут быть неплохими бизнесменами, я как минимум пару таких знаю.
вероятно, они одновременно могут быть также плохими каменщиками, авторемонтниками или гинекологами.
Но я не думаю, что нужно перечислять все области, в которых у человека нет талантов.
Хороший бизнесмен — этого уже вполне достаточно.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Заблуждение. Если бы хоть 6% программистов (60% от всех Хороших Програмистов ) поднимали свои стартапы, то был бы тайфун стартапов.
у тебя крайне завышенные оценки количества Хороших Программистов (не путать с теми, которые с маленькой буквы)
ГВ>Угу. Типа стартап — это писать то, что тебе в кайф, а деньги сами в карман сыплются.
ага. если ты действительно умеешь делать свое дело, то это так и есть.
Ну а если не умеешь... это уже отдельный вопрос.
ГВ>Заблуждение.
правда?
ГВ>Заблуждение. Гламурное к тому же.
а давай без подонковской лексики?
ГВ>Ага, а параллельно для хорошего програмиста не составит никаких проблем выполнять функции бухгалтера, директора, администратора и т.п.
когда (если) в этом возникнет необходимость, деньги на бухгалтерию, администрацию и так далее уже будут
само по себе производство продукта — оно, знаешь ли, появилось задолго до всех этих замечательных изобретений
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Если ты заметил, то слово "учёный" я в кавычки не брал.
Проблема в том, что ученых намного меньше, чем "ученых". Возможно, даже на порядки. И бОльшая часть тех, кто называет себя учеными, относится на самом деле совсем к другой категории.
VladD2,
VD>>>Ага. А в С++ нет проблем goto, обращения к неинициализированным переменным и т.п. Достаточно послушать фанатов С++, чтобы убедиться что те у кого такие проблемы встречаются — это просто криворукие ламеры.
E>>Собственно, так и есть.
VD>Кто бы спорил. Ты один из них и есть.
VladD2,
LCR>>Ммм.. Нет, конечно. Но и твоя, и моя оценка субъективна.
VD>Серьезно? Когда тебя называт ламером и недоумком, то это не нравится просто от того, что твоя оценка субъективна?
Да. "Ударили по щеке, подставь другую", "Возлюби врага своего" и т.п. — в общем-то это не пустые слова, и нужно обладать определённой внутренней силой, чтобы поступить правильно и нивелировать агрессию оппонента. Раздуть конфликт может и дурак.
Увы, этот разговор всё равно мало чего изменит. Потому не хочу на него тратить ни моё, ни твоё время. Извини.
Здравствуйте, Дарней, Вы писали:
ГВ>>Если ты заметил, то слово "учёный" я в кавычки не брал. Д>Проблема в том, что ученых намного меньше, чем "ученых". Возможно, даже на порядки. И бОльшая часть тех, кто называет себя учеными, относится на самом деле совсем к другой категории.
М-м-м... Следуя такой модели аргументации, я могу предположить, что следующим номером будет обсуждение на тему того, что не всякое зерно одинаково полезно, что не всякий амбар одинаково хорош, что не всякая мышь одинаково прожорлива, а некоторые крысы уничтожают мышей и потому могут быть полезны. Далее мы перейдём к обсуждению способов ловли мышей, пород кошек и моделей картофелеуборочных комбайнов.
Понятно, что я ошибаюсь, ибо имеется бесконечное количество тем, связанных с этим
сообщением исключительно общей лексикой. Слова, то есть, похожи.
<< Под музыку: silent >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Дарней, Вы писали:
ГВ>>Угу. Типа стартап — это писать то, что тебе в кайф, а деньги сами в карман сыплются. Д>ага. если ты действительно умеешь делать свое дело, то это так и есть. Д>Ну а если не умеешь... это уже отдельный вопрос.
В отдельных случаях, возможно, так оно и есть.
Д>>>Да, хороших программистов мало. Но у плохих всё равно нет никаких шансов поднять свой стартап, поэтому их не стоит вообще принимать в рассмотрение. ГВ>>Заблуждение. Д>правда?
Правда. Владелец успешного стартапа и хороший программист — совсем не одно и то же. В смысле, это может быть один и тот же человек, но сие совсем не обязательно.
ГВ>>Заблуждение. Гламурное к тому же. Д>а давай без подонковской лексики?
Где ты её нашёл?
<< Под музыку: silent >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!