и именно о нем и идет речь. Это пример прерывания вычисления выражения с передачей управления в другое место.
S>: S>Опасность номер 1: для разработчиков библиотеки. S>У тебя есть некоторый код, который вызывает переданный тебе делегат. Этот делегат может оказаться с "миной". Ее эффект на твой код сравним с исключением: управление передается не на следующую инструкцию, а стреляет вверх по стеку. Со всеми finally, разумеется, хоть и безо всяких catch. S>В принципе, тебе и так надо писать код, который не приводит твои объекты в неконсистентное состояние от вылета исключения. Специально затачиваться на него не стоит — выше по стеку стоит соответствующий кэтч, который там написан с должным смыслом. S>Можно специально затачиваться на случай, когда тебе передали "крышку", которая хочет вернуться в такое место, которого в стеке уже нет. Это — уже вполне настоящее исключение, которое ты опять же можешь обработать, а можешь не обрабатывать, в зависимости от того, чего ты имел в виду.
У тебя в корене не правльные посылы. Идея писать код в рассчете на побочные эффекты возникющие спантанно сама по себе ущербна. Логика болшинства приложений и так сложна, чтобы усложнять ее пдобным контролем.
К тому же закладываться или не закладываться здесь в общем-то не так важно. Важно другое. Важно, что ты уже не можешь читая код делать предположение о его последовательности. Так читая код на C# я могу быть уверненым, что длинное выражение что бы не вычилсялось всегда попадет в переменную, если оно стоит с права от присонения ей значения. И я всегда уверен, что управление из этого вражения перейдет на следующую строку, а не убежит черти куда. По этому, кстати, очень плохо когда пишут return на одной строке:
if (ля-ля-ля) return;
Человек читающий такой код может не заметить его и не верно понять логику. Ветвление управления яуляется очень важным в импертивном коде чтобы на него смотреть сквозь пальцы.
По этому, пдобные "крышки" в середине выражений — это очень порочная практика, и есл ей еще и хвастаются, то это или откровенно не высокий уровень программиста, или очень плохие традиции в ЯП.
S>Опасность номер 2: для пользователя. S>Можно попробовать передать блок с крышкой вверх по стеку, где его выполнение — гарантированная засада. Это ошибка, которую бы лучше ловить. В принципе, есть еще много спопобов случайно сделать ошибку такого рода.
Видимо это и есть то достоиство выделющее Смолток и что так сильно воспевают его поклонники. Для меня любая возможность сделать ошику — это плохо. И чем от большего числа ошибок уберегает меня ЯП, тем лучше для меня. В идиале ЯП вообще не должен позволять делать случайные ошибки. Глупости лучше делать явно. И наличие в ЯП возможностей потенциально приводящих к пробемам — это очень плохо. Это и есть те саые грабли из-за которых я охладел к С++ в свое время.
S> Хотя, возможно, такие вещи стоило бы отслеживать на уровне компилятора — ескейп анализ, и сразу говорим: "братан, крышку можно передавать только вниз по стеку, как и ссылки на локальные переменные. Вверх — низзя". Не дожидаясь, пока тестеры на это наступят.
Вообще-то невозможность передачи блока кода в другие части программы — это вообще очень плохо. А исключения и того хуже. Так что защита конечно нужна, но я бы вообще отказался от таких возможностей которые приводят к таким проблемам.
К тому же проанализировать возврат из выражения вообще нельзя. Так что решение все равно будет избыточным, хотя и очень не простым в реализации.
S>Причем в большинстве случаев такого не случится, потому как анонимные блоки редко когда вообще передаются наверх.
Еще разок взгляни вверх этого сообщения и сходи по ссылочке. Этот пример был приведен как мега-крутость. Так что грабли не то что бы редки. Они даже круты.
S> Это уже хардкорный код типа комбинаторов предикатов, в реальных проектах нужный только в 1% случаев.
Нда, Синклер, отстал ты от жизни. Как только в руки приличного программита попадает ляюба он начинает исползовать ее на право и на лево. А уж в Смолтоке традиции этого дела уже давнии. Ты думаешь, чтоем они хвастаются то?
S>А в 99% случаев семантика крышки ясна как божий день, и ни малейшего затруднения с пониманием, куда перейдет управление, у тебя не будет. А ведь только это и представляет проблему.
Понимаш ли в чем дело. Твои проценты это залихватское высасывание из пальца. Рельно же кто-то будет остерегаться делать какие-то опасные действия или просто писать трудный в чтении код, но другие (что амечательно продемонстрировал Andrei N.Sobchuck
) будут не только класть грабли в код, но и годро демонстрировать это на форуме. Мол, смотрите как круто! По этому я считаю, что грабли из ЯП надо удалять, а не поощрять их добавление. Именно по этому нелокальные возвраты запрещены в большинстве сорвеменных языков и именно по этому на исключениях очень не советуют строить логику приложения.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, FDSC, Вы писали:
P>>b. массив данных по прежнему может быть разных типов, главное есть итератор do: , принимающий лямбду.
FDS>Ерунда, это без разницы, если все типы поддерживают один и тот же интерфейс. Это сделать не сложно. Другое дело, что придётся писать небольшой класс-обёртку (один) для стандартных типов, что бы они то же поддерживали этот интерфейс.
Смолток язык динамически типизированный, да еще в добавок с утиной типизацией. Так что положить то массив можно и обработать можно, но вот надежность у такого кода будет ниже плинтуса потому как до выполнения даже бог не сможет предскзать смогут ли объекты обработоать посылаемые им сообщения (взов методов). Ты же смотришь с позиции языков со статической типизацией. В общем-то и в C# можно положить все что угодно приведя это дело к object. Но вот с обработкой действительно будут проблемы. Прийдется или проверять типы динамически, например:
void Do(object obj)
{
IMyInterface myInf = obj as IMyInterface;
if (myInf != null)
{
ЧтоТоДелаем(myInf);
return;
}
string str = obj as string;
if (myInf != null)
{
ДелаемЧтоТоДругое(str);
return;
}
if (obj is int)
ДелаемЧтоТоСовсемДругое(str);
}
или дергать методы через рефлексию.
Первый способ в C# не удобен и не уневерсален, второй — медленнен.
В Немерле, кстати, первый случай реализуется довольно удобно:
void Do(object obj)
{
| myInf is IMyInterface => ЧтоТоДелаем(myInf);
| str is string => ДелаемЧтоТоДругое(str);
| obj is int => ДелаемЧтоТоСовсемДругое(str);
| _ => () // ничепго не делаем.
}
P>>c. условие проверки такое: все хорошо если в массиве есть 2 смежных элемента , из которых второй равен первый*2. Обращаю внимание что типы чисел в массиве данных разные.
FDS>Без проблем, если есть интерфейсы. Просто без проблем...
Да без проблем и без интерфейсов. Например, следующий код берет массив и умножает его элементы на два без учета конкретного типа.
using System;
using System.Console;
using Nemerle.Utility;
def ary = array[2 : object, 1.2F, 2.3D, "5"];
// Map() конвертирует (отображает) один массив в другой преобразуя элементы с
// помощью переданной ему функции (в данном примере лямбды).
def lst = ary.Map(elem => Convert.ToDouble(elem) * 2.0);
WriteLine(lst.ToString(", "));
Вот только одна проблема. Надежность такого кода зависит от ветра в поле. Достоточно поместить в массив хотя бы один элемент не конвертируемый в double и привет.
Например:
using System;
using System.Console;
using Nemerle.Utility;
// По умолчанию Немерле считает смешивание разных отипов в коллекциях ошибкой.
// Чтобы подсказать тип элементов мы уточняем тип первого из них.
// Далее Немерле сам догадывается, что все остальные типы нужно привести к object.
// Таким образом мы получаем массив object-ов хранящий ссылки на объекты разных типов.
def ary = array[2 : object, 1.2F, 2.3D, "x5"];
def lst = ary.Map(elem => Convert.ToDouble(elem) * 2.0);
WriteLine(lst.ToString(", "));
приведет к ислючению в рантайме потому как х5 не преобразуется в double.
Собственно этим и отличается динамический язык от статического. С одной стороны чуть проще, так как подобные хаки не требуют специальных вызовов вроде Convert.ToDouble(elem) (все приводится автоматом), но с другой постоянно можно получить рантайм-ошибку. Это приводит к юнит тестированию на каждый чих и т.п.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>>>Оказывается — это паттерн-матчинг с алгебраическми типами, дернутыми из ML нам так помог, а не макросы. Ты меня разочаровываешь. IT>>От вас же, просвящённых, только пока и слышно: мы знаем что такое pattern matching, поэтому мы умные. G>Ну я понимаю, что некоторые тут чувствуют себя неудобно, когда рядом кто-то шибко умные слова говорит, паттерн-матчинг там или карринг. Прям свербит, хочется в харю очкастым умникам дать, правда? Но ничего, это пройдет.
В харю хочется дать за демагогию, хамство и бахвальство. Это правда. И вряд ли это когда-нибудь пройдёт.
Что касается умных слов, то с этим на RSDN всегда было всё в порядке. Такие люди всегда welcome и их есть на RSDN, в том числе и среди функциональщиков. А вот за сочетанием шибко умных слов с тем, за что иногда хочется дать в харю, как правило нет ничего, только один трёп. На деле такие очкарики оказваются с целым букетов жизненных комплексов, с каким-нибудь крайне сомнительным профессиональным бэкграундом и без единого проекта за душой, о котором не стыдно было бы рассказать окружающим. Настоящему профессионалу нет надобности скрываться за маской умника очкарика и уж тем более мокать в дерьмо своих коллег, чтобы доказать самому себе, что он пока ещё не является полным ничтожеством и неудачником. Вместо этого профи всегда найдёт чему поучиться у других.
IT>>Так вот. Мы будем рассказывать людям что такое pattern matching и как он работает, они тоже будут становиться умными, а вы будете потихоньку превращаться в Неуловимых Джо. G>А тебе не приходило в голову, что мы, очкастые умники, чти-нибудь еще умное за это время выучим, пока вы с паттерн-матчингом разбираетесь?
Нет, не приходило. Лисп является тем функциональным ископаемым, на котором построены все остальные, могущие похвастаться, что обладают тем, чего нет в мейнстриме. А мейнстрим сейчас медленно, но уверенно переваривает и впитывает из этого всё лучшее.
Но даже если вы и откопаете что-то новое, то сразу же прибежите сюда и начнёте опять нам рассказывать о преимуществах своего интеллекта. И как результат проболтаетесь Алтернатива одна — умнеть и переться от собственной крутости в одиночестве. Но в эту альтернативу я не верю. Очкастому умнику для демонстрации размеров своего головного мозга нужна аудитория.
IT>>Хотя, время ещё есть одуматься, засунуть свой сарказм подальше и начать сеять доброе и вечное вместе с нами
G>Ой, какой кошмар — не успеем, и поезд уйдет — IT c Владом все-превсе расскажут про паттерн-матчинг, и все в форуме "философия" сразу станут умными, а "мы" останемся в дураках.
Испугался? Не надо так сильно бояться. Тем более, что вы останетесь не в дураках, а превратитесь в Неуловимых Джо.
G> Ну и напугал ты меня. Времени-то много осталось, до ухода поезда?
Вот сейчас тебе назло пойду и расскажу FDSC как работают замыкания. Это будет хоть и небольшое, но всё же сокращение времени до ухода твоего поезда
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, FDSC, Вы писали:
FDS>Честно говоря, я вообще не понимаю, зачем в Nemrle введены ref и out параметры,
Это как раз просто. Немерле позволяет использовать библиотеки дотнета и создавать библиотеки для других языков. Так как C# язык в дотнете особенный (флагманский, все под него подстраиваются), то Немерле обязан воспроизводить любой интерфейс который только можно создать на C#. Ну, и не надо забывать про то что Немерле многое взял у C# просто с целью быть более понятным для мэйнстрим-программистов которые как раз в основном работают на C#, С++ или Яве.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Gaperton, Вы писали:
G>О сколько нам открытий чудных. Оказывается — это паттерн-матчинг с алгебраическми типами, дернутыми из ML нам так помог, а не макросы. Ты меня разочаровываешь.
Ага. А надо этого стыдиться? Взяли из МЛ самое лучшее. Поправили форму и встроили в один из самых популярных на сегодня языков. Макросы тоже дернули. Так же по ходу дела их доработали и очеловечили. Тоже плохо?
Чувствую какую-то нездоровую зависть. Может чем яд испускать и демонстрировать свою крутость на право и на лево помог бы тем же начинающим понять те самые вещи которые тебе так нравятся в ФЯ?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, squiz, Вы писали:
S>Кстати, по поводу компилятора: это только у меня так что hello.n собирается 3-4 сек. ? На той же машине 1.2M солюшн ребилдится за макс 1 сек. полностью...
Чтобы компилятор загружался быстрее нужно пргнать по его сборкам ngen. Уверен что поиск по словам NGen и Nemerle.dll по нашему сайту даст нужный результат.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>Просто удивительно, но количество желающих применить ко мне аргументацию с позиций физической силы резко уменьшилось до нуля после года занятий в "качалке".
Да, современные стеройды рулят. Арнольду пришлось их жрать лет 10 подряд.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, squiz, Вы писали:
MS>>И ты должен это учитывать, несмотря на всякие "преведы" уважаемого Влада (извини, Влад, но слово "отвичаю" я приравниваю к слову "превед" в твоей лексике — пожалуйста, избегай впредь падонковщины, иначе я буду причислять тебя к неуважаемым мною падонкам). Такие дела.
S>Никогда не замечал за ним падонковского языка. Он просто много пишет и быстро а посему много опечаток
Не обращай внимания. Это такой вариант демагогии — докапывания не до слов оппонента, а до самого оппонента или до его проявлений. Вот у меня удобно до опечаток докопаться находя в них тайный смысл и даже падонковщину. Ребята просто упражняются в демагогии пользуясь гостеприимством.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
в рамках этого форума частично обсуждаем. FDS>Не получается понять синтаксис языка: что ни напишу, компилятор всё время ругается . Подожду пока выйдет какая-нибудь нормальная документация...
Это потому что язык строгий и многое контролирует. Вот только сообщения об ошибках не всегда качественные. Над этим еще надо работать.
Здравствуйте, FDSC, Вы писали:
FDS>Ага, на C# я начал программировать вообще ничего не читая
Правильно. Это потому что у тебя был опыт с Дельфи. Оба языка алголоподобные и исповедуют общую идеологию — компонентную.
А Немерле кроме нее еще исповедует функциональный подход. Вот его то как раз понять не просто.
FDS> и когда я что-то в нём не знаю, обычно оказывается, что это что-то сделано так, как я думаю, а не как-то по другому. Сколько можно читать документацию, в которой, к тому же, некоторые примеры раза по три повторяются...
Мое мнение — надо трясти. То есть надо взять простую задачку и попробовать решить на языке. По началу писать на Немерле как на C#. Ну, возможно с небольшим отклонением вроде выовда типов. Далее потихоньку начинаем добавлять фичи которых нет в Шарпе. Для начала локальные функции. Далее еще что-то. Каждый раз делая это обращаешся к статье. Каждое новое обращение будет давать все более и более целостную картину. И ты сам не заметишь как со временем ты будешь все больше и больше писть на Немерле нежели на C#++.
Я уже видел это на примере двоих человек. Плюс сам прошел через это.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, FR, Вы писали:
FR>Судя по тому как плаваешь в тех же замыканиях тебе нужно вообще подучить базовые понятия функционального программирования, лучшая книга по моему "Функциональное программировани" Филда и Харрисона
По-моему, все эти книги только хуже сделают. Не видел ни одной доходчивой для императивщика. Сам помню опупение вызываемое чтением подобного бреда.
Мое мнене лучше просто пробовать. Пробовать по чуть-чуть и каждый раз подчитывать информацию по изучаемому вопросу.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>В общем, исключения совершенно нормальное и полезно средство бработки нештататных ситуаций. Но вот основную логику приложения на них делать ни в коем случае не стоит. Это чревато многими проблемами. Тут тебе и усложнение отладки. И неконтролируемая передача управления. Хот даже тут бывают исключения. Но они обычно ближе к хакам, а те сами не желательны.
Никто не говорит, что на них надо делать основную логику работы приложения. Просто обычно работа с исключениями происходит так: где-то в самом низу что-то сломалось и оттуда вылетает исключение, и летит вверх по стеку вызовов, потому что никто не знает, что с ним делать. И вот оно наконец долетает до верхнего уровня, который знает, как можно было бы починить ситуацию, но — поздняк метатться, стек то размотан уже.
Есть у нас некий анализатор (функция верхнего уровня). Она может парсить логи. Логи хранятся в файлах и состоят из записей |entries).
Так вот, предположим, что в процессе работы parse-log-entry ей встретилась запись неправильного формата (malformed entry). Она и знать не знает о том, что ей делать в таком случае, потому выбрасывает исключение. parse-log-file тоже не знает, что делать, и пробрасывает его дальше (прерывая тем самым обработку файла в милллон записей). То же и с analyze-log, плюс еще теряется информация о том, какой именно из тысячи файлов мы только что обрабатывали. И вот наконец, дело доходит до верхнего уровня, который знает про "политику партии", что же далать в таких случаях. Но, как я уже говорил, поздняк метаться. Восстановиться мы уже не сможем. А могли бы. Например, пропустить эту запись. Или исправить формат записи и попробовать прочитать еще раз.
На всякий случай: умного мужика зовут Pieter Seibel, и пример был подслушан на его выступлении на тему своей книги (Practical Common Lisp)
Здравствуйте, FDSC, Вы писали:
FR>>Судя по тому как плаваешь в тех же замыканиях тебе нужно вообще подучить базовые понятия функционального программирования, лучшая книга по моему "Функциональное программировани" Филда и Харрисона
FDS>Вы правы, уже подумал на эту тему. Спасибо за совет.
Кроме книжек можно ещё поиграться с Рефлектором и посмотреть как реализуется захват контекста замыканиями. Особенно, еслм нет проблем с самим C# и с делегатами. Например, вот такой кой на C# 2.0:
class Class1
{
delegate int FooTest(int p);
int _classField = 1;
int Foo(int parameterField)
{
int localField = 2;
FooTest test = delegate(int localFunctionParameter)
{
return _classField + parameterField + localField + localFunctionParameter;
};
return test(3);
}
}
разворачивается компилятором в примерно следущее:
class Class1
{
private delegate int FooTest(int p);
int _classField = 1;
[CompilerGenerated]
private sealed class LocalClass
{
public Class1 __this;
public int localField;
public int parameterField;
public int LocalFunction(int localFunctionParameter)
{
return __this._classField + parameterField) + localField) + localFunctionParameter;
}
}
private int Foo(int parameterField)
{
LocalClass class1 = new LocalClass();
class1.parameterField = parameterField;
class1.localField = 2;
class1.__this = this;
return class1.LocalFunction(3);
}
}
Из этого примера хорошо видно, что анонимный делегат и замыкания в C# — это не более чем синтаксический сахар. Хотя, надо признать, весьма полезный.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.