LINUX.ORG.RU

Не баг, а фича

 


0

2

Какие вещи в программирования изначально появились как эдакая недоработка, но потом приобрела `статус фичи`?

Вот как мне кажется (на достоверность не претендую) например лисп - ребятам просто лень было доделывать. Динамическая типизация - разумеется товарищи типа Гвидо и Мацумото знают о преимуществах статической - но её просто сложно сделать, `и так пойдёт`.

Что ещё есть?

Перемещено JB из talks

★★★★★

Последнее исправление: Debasher (всего исправлений: 1)

XOR - на нем зиждется практически вся криптография

mov AX, BX в эпоху дос, в частности младшие биты

x*x

x**x

goto

основные принципы ООП

anonymous
()
Ответ на: комментарий от monk

Можешь переменным числом аргументов считать любую коллекцию.

Я к слову достаточно заинтересовался, чтобы сделать без макросов: http://is.gd/iEGg04 .

Макрос нельзя сохранить в переменной или передать аргументом в функцию.

При чем здесь это?

$x$(.zip($xs))* — это во что превращается? Например, для (1..4), (5..8).

(1..4).zip(5..8) , очевидно же. Для (1..4), (5..8), (9..12) будет (1..4).zip(5..8).zip(9..12).

nonimous
()
Ответ на: комментарий от monk

Функция max тоже принимает только два аргумента?

Конечно. Если нужен максимум от последовательности вызывай max на итераторе последовательности - [x, y, z, t].iter().max(). Функционально эквивалентно, и язык не замусоривается лишними концепциями.

nonimous
()
Ответ на: комментарий от DarkEld3r

std::initializer_list
сахара для слайсов

Ну это сахар просто, и сейчас можно использовать Vec с тем же успехом, аргумент-то остается один. Я под переменным числом аргументом понимал какой-нибудь лисповский &optional/&rest или printf.

nonimous
()
Ответ на: комментарий от nonimous

Ну это сахар просто, и сейчас можно использовать Vec с тем же успехом

И создавать вектор каждый раз? Не слишком оптимально. А с сахаром было бы удобно - в слайс можно и вектор превратить (дешевая операция) и просто набор значений передать не создавая вектор лишний раз.

Аналог variadic template тоже было бы интересно иметь, но тут и правда хз как красиво сделать.

DarkEld3r ★★★★★
()
Ответ на: комментарий от nonimous

Ты что-то придумываешь, он ни слова не сказал про зависимые типы, мы тут про лишп и эрланг говорим.

Я не выдумываю. Языки с динамической типизацией - это, с математической точки зрения, лямбда-п-омега (зависимые типы + операторы над типами, параметрического полиморфизма нет) с подтипированием и refinement-типами.

Скорее, расскажи об этом ребятам из Agda и Idris, а то они мучаются со своей камасутрой в то время как лоровский аноним открыл способ сделать зависимые типы через динамику.

камасутра возникает от того, что они чекают зависимые типы статически, при компиляции. Если чекать динамически, в рантайме - камасутры никакой нет.

А еще лучше открой TaPL и прочитай на первой странице, про то, что в динамических языках типов в математическом понимании нет

Как видно ты сам тапл не читал, иначе такую ересь бы не нес. Впрочем, для упоротых статикодебилов отсутствие даже базовых знаний довольно-таки характерная вещь.

anonymous
()
Ответ на: комментарий от nonimous

Если коллега решит изменить максимальное значение, для меня ничего не изменится, т.к. я уже буду отрабатывать ошибку Overflow, даже в коде calc(3) + calc(4). Если коллега решит добавить новый тип ошибки в CalcError, компилятор выдаст ошибку в моем коде, т.к. не все варианты enum-а будут отрабатываться.

В суровой реальности будет въебенена заглушка на месте проверки, и все.

Сравни

Ну код в точности совпадает (если опустить несущественные различия в синтаксисе).

monk уже сознался, что в нормальном коде ему нужно явно проверять значения на numberp перед использованием.

Еще раз - я если сверху по коду проверил, то мне уже проверять ничего не нужно, смело пишу calc(x)+calc(y). а вот тебе, с типами, придется каждый раз этот вырвиглаз писать.

anonymous
()
Ответ на: комментарий от nonimous

Ты еще не открыл для себя параметрический полиморфизм?

тут нужен variable-arity полиморфизм, параметрический ничем не поможет никак а в хачкиле такого полиморфизма нет

anonymous
()
Ответ на: комментарий от nonimous

Т.е. ты не только пишешь юниттесты в двойном объеме, но еще и подробную документацию на каждую двухстрочную функцию. И эти люди еще утверждают, что динамические языки позволяют писать код быстрее, лол.

Вот только что ты назвал причину, по которой грамотно использовать статическую типизацию могут _исключительно_ люди, которые хорошо умеют писать на динамике.

Классические статикодебилы же пишут вырвиглазное говно без юнит-тестов и документации в надежде что «мамой клянусь статические гарантии». На практике, конечно же, нету никаких статических гарантий, вместо них уже упомянутое type Name = String и куча багов.

anonymous
()
Ответ на: комментарий от DarkEld3r

Например, Result(T, Error) в расте отлично работает.

Но он очень неудобен и превращает код в адъ и погибель.

anonymous
()
Ответ на: комментарий от tailgunner

Вообще-то ограничения на типы операндов - это часть алгоритма. Ну, разве что у тебя алгоритм сложения кубометров с милями.

Проблема в том, что система типов динамики сильно выразительнее статики в большинстве языков, в результате надо не просто получить ограничения на типы - но и выразить его в рамках очень неудобного и ограниченного формализма. Вот здесь-то проблема и возникает. В случае же агд с идрисами все, конечно, лучше - здесь ограничения на выразительность практически сняты и можно выразить все то же самое, что и в динамике (ну, почти, сложные контракты, связанные с состоянием, например, все равно так же просто выразить не удастся). Да вот только потом с верификацией этого добра геморроя не оберешься. В динамике такой проблемы нет.

anonymous
()
Ответ на: комментарий от DarkEld3r

Во вторых, есть тип Result<T, E>

А если больше двух вариантов ошибки либо успешного результата?

anonymous
()
Ответ на: комментарий от nonimous

Успокойся, вот написал: http://is.gd/C3wvHA

Взял и написал нетипизированный макрос. Отличная история! Статика во всей красе.

Так вполне себе аналог, кроме одного принципиального различия - все типы ресолвятся в компайлтайме, ошибки типизации ловятся сразу, и генерируемый код оптимизируется под текущий тип.

Дурашка, ты вообще видел во что превращается отладка со значительным использованием макросов в типизированном языке, особенно когда нету инструментов для отладки самих макросов, а сама макросистема прилетела прямиком из 70-х, как будто полвека развития и не бывало?

anonymous
()
Ответ на: комментарий от tailgunner

Ты и сам знаешь, что ограничения не такие.

А какие?

anonymous
()
Ответ на: комментарий от Debasher

Ох.

Ваше утверждение: Динамическая типизация появилась в лиспе как бага, которую никто не исправил. Истина: Динамическая типизация появилась в лиспе по сознательному решению разработчиков.

Утверждение 1 не тождественно утверждению 2, следовательно ваше утверждение ошибочно.

Gentooshnik ★★★★★
()
Ответ на: комментарий от DarkEld3r

Очень удобно, да.

Как ни странно - гораздо удобнее, чем парсить километры блевотных логов тайпчекера.

anonymous
()
Ответ на: комментарий от anonymous

Языки с динамической типизацией - это, с математической точки зрения, [..]
Как видно ты сам тапл не читал, иначе такую ересь бы не нес.

Цитирую по переводу:

Еще одно важное свойство вышеуказанного определения - упор на классификацию термов (синтаксических составляющих) в соответствии со значениями, которые они порождают, будучи вычисленными. Систему типов можно рассматривать как статическую (static) аппроксимацию поведения программы во время выполнения. (Более того, типы термов обычно вычисляются композиционально (compositionally), то есть тип выражения зависит только от типов его подвыражений.)
Иногда слово «статический» добавляется явным образом - например, говорят о «языках программирования со статической типизацией», чтобы отличить тот анализ, который производится при компиляции и который мы рассматриваем здесь, от динамической (dynamic) или латентной (latent) типизации в языках вроде Scheme, в которых теги типов (type tags) используются для различения видов объектов, находящихся в куче. Термин «динамически типизированный», по нашему мнению, неверен (его следовало бы заменить на «динамически проверяемый»), но такое употребление уже общепринято.

nonimous
()
Ответ на: комментарий от nonimous

Я не вижу, как переменное число аргументов может сосуществовать с нормальной системой типов.

Ну это же проблемы исключительно ущербных систем типов, в нормальных все ок:

> (require typed/racket)
> map
- : (All (c a b ...)
      (case->
       (-> (-> a c) (Pairof a (Listof a)) (Pairof c (Listof c)))
       (-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c))))
#<procedure:map>
> 

anonymous
()
Ответ на: комментарий от Gentooshnik

Динамическая типизация появилась в лиспе как бага, которую никто не исправил.

Я не говорил бага, тут слово `недоработка`. Если его поставить вместо слово `бага` - утверждения не обязательно будут противоречить друг другу.

Debasher ★★★★★
() автор топика
Последнее исправление: Debasher (всего исправлений: 1)
Ответ на: комментарий от anonymous

Но он очень неудобен

Чем?

и превращает код в адъ и погибель.

Как правило, в «адъ и погибель» код превращают не типы, а программист. Result к месту весьма удобен, если уж мы хотим обойтись без исключений. В любом случае, я отвечал на следующее:

В языках со статической типизацией приходится извращаться: если значение меньше нуля, значит это код ошибки (Си) или после операции проверяй флаг ошибки (Си++).

DarkEld3r ★★★★★
()
Ответ на: комментарий от tailgunner

справедливости ради - далеко не все системы типов поддерживают подобную ad-hoc перегрузку в том же хаскеле не выйдет, например

anonymous
()
Ответ на: комментарий от anonymous

В суровой реальности будет въебенена заглушка на месте проверки, и все.

Ясно-понятно.

Еще раз - я если сверху по коду проверил, то мне уже проверять ничего не нужно, смело пишу calc(x)+calc(y). а вот тебе, с типами, придется каждый раз этот вырвиглаз писать.

Ты продолжаешь путать, мне придется один раз сделать match и достать свободные от Result<..> значения. Дальше я могу их использовать свободно без проверок, зная, что у меня там внезапно :overflow вместо числа не будет. В динамикопетушне ты никогда не можешь быть уверен, что тебе вместо числа этот :overflow не прилетит, и вынужден проверять типы вручную.

nonimous
()
Ответ на: комментарий от anonymous

Со статическим языком мне не нужно покрывать в юнитестах все множество входных значений, как и не нужно вручную искать все места вызова, после изменения какой-то функции.

nonimous
()
Ответ на: комментарий от anonymous

А если больше двух вариантов ошибки либо успешного результата?

А в чём проблема? Так оно обычно и бывает:

enum Error {
    A,
    B,
    C,
    // ...
}

type Result<T> = ::Result<T, Error>;

fn get_value() -> Result<i32> {
// ...
Естественно, код будет завернут в модуль (пусть будет my), так что общий результат (Result<T, E>) не будет путаться с локальным (my::Result<T, my::Error>).

DarkEld3r ★★★★★
()
Ответ на: комментарий от nonimous

Систему типов можно рассматривать как статическую (static) аппроксимацию поведения программы во время выполнения.

Вот в динамике и есть статическая аппроксимация, про время же построения этой аппроксимации в процитированном куске, как видно, ничего не написано. Даже пишут, специально для тех кто в танке:

Термин «динамически типизированный», по нашему мнению, неверен (его следовало бы заменить на «динамически проверяемый»)

То есть система типов и там и там. И там и там она определяет некое статическое отношение между множеством подтермов данной программы и множеством типов. Просто строится это отношение в разные моменты времени и разными способами.

А теги - это штука совершенно ортогональная, вот, например, у меня есть refinement тип (and integer? (> x 3)), но никакого соответствующего тега нет.

anonymous
()
Ответ на: комментарий от anonymous

Как ни странно - гораздо удобнее, чем парсить километры блевотных логов тайпчекера.

Уж извини, но не поверю. Пройтись по всем местам, которые компилятор покажет всяко удобнее, чем грепать и думать как бы заменить, чтобы лишнего не зацепить.

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

Проблема в том, что система типов динамики сильно выразительнее статики в большинстве языков, в результате надо не просто получить ограничения на типы - но и выразить его в рамках очень неудобного и ограниченного формализма. Вот здесь-то проблема и возникает.

Нет никакой проблемы. Статические системы типов давно уже достаточны для удобного решения практических задач. А то, что динамические системы типов более выразительны - проблема разве что для тех, кто сопровождает такой выразительный код.

Да вот только потом с верификацией этого добра геморроя не оберешься. В динамике такой проблемы нет.

Правда, верификации тоже нет. Или ты о верификации на этапе выполнения? Это нафиг никому не нужно.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Взял и написал нетипизированный макрос. Отличная история! Статика во всей красе.

Перестань сочинять, очень даже типизированный: http://is.gd/Z0zXd6 .

Дурашка, ты вообще видел во что превращается отладка со значительным использованием макросов в типизированном языке, особенно когда нету инструментов для отладки самих макросов, а сама макросистема прилетела прямиком из 70-х, как будто полвека развития и не бывало?

Лiл, апологеты CL и динамики рассуждают о правильных макросистемах. Тут по крайней мере результат макроэкспаншена через тайпчекер проходит.

nonimous
()
Ответ на: комментарий от anonymous

И для каждой комбинации ошибок надо делать свой AnotherYobaError?

Если ты хочешь выделить отдельную логическую группу ошибок, то да. Заодно и придётся в нужных местах все варианты обработать, ну или явно проигнорировать. Если хочется, то можно использовать имеющиеся или более общие ошибки. В чём проблема? Кстати, новые имена для категорий ошибок как раз не нужны.

DarkEld3r ★★★★★
()
Ответ на: комментарий от tailgunner

Правда, верификации тоже нет.

Правильно. Это и есть главный плюс.

Или ты о верификации на этапе выполнения? Это нафиг никому не нужно.

Как показывает практика, никому как раз не нужна верификация времени компиляции. Слишком много затрат. По-этому в 99% случаев оно не применяется, а когда и применяется (если задача требует) - то при помощи специальных пруверов вроде ACL2, естественно, с зависимыми типами (и вообще с типами) ничего общего не имеющими.

А то, что динамические системы типов более выразительны - проблема разве что для тех, кто сопровождает такой выразительный код.

Да нет, никакой проблемы как раз нет.

Статические системы типов давно уже достаточны для удобного решения практических задач.

Это ложь, конечно. Слабые системы типов вроде хаскеля никаких интересных гарантий получить не дают, только ограничить возможность сложения слонов с бегемотами (а такие ошибки и так элементарно отлавливаются с околонулевыми затратами). Зависимые типы теоретически могли бы давать профит - но тут см. выше, во-первых слишком много затрат и по-этому подобная верификация вообще сугубо нишевое явление, во-вторых типы в данном случае неудобный инструмент и потому практически не применяются. Гетто внутри гетто.

anonymous
()
Ответ на: комментарий от anonymous

ты вообще видел во что превращается отладка со значительным использованием макросов в типизированном языке, особенно когда нету инструментов для отладки самих макросов, а сама макросистема прилетела прямиком из 70-х

Чисто из любопытства: много таких языков?

И что тебе не нравится в растовых макросах? Кстати, какие-никакие «инструменты» для отладки есть.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Как правило, в «адъ и погибель» код превращают не типы, а программист. Result к месту весьма удобен, если уж мы хотим обойтись без исключений.

Ну напиши мне код с твоим result так, чтобы он в адъ и погибель не превратился. Без монад, без оборачивания в try и прочего вырвиглазного говнища. Чтобы a+b выглядело не сложнее, чем a+b.

Чем?

Тем, что простой и понятный код превращается в перегруженное ненужными деталями говно. Обработка ошибок должна происходить отдельно от кода, а не быть размазанной толстым слоем говнища по всем потрохам.

anonymous
()
Ответ на: комментарий от nonimous

Ты продолжаешь путать, мне придется один раз сделать match и достать свободные от Result<..> значения. Дальше я могу их использовать свободно без проверок, зная, что у меня там внезапно :overflow вместо числа не будет.

Молодец, ты просто переложил разворачивание Result через match на call-site.

В динамикопетушне ты никогда не можешь быть уверен, что тебе вместо числа этот :overflow не прилетит

Конечно же могу.

anonymous
()
Ответ на: комментарий от nonimous

Со статическим языком мне не нужно покрывать в юнитестах все множество входных значений, как и не нужно вручную искать все места вызова, после изменения какой-то функции.

С динамическим тоже не нужно, представь себе. Если твоя ф-я на одном тесте сработала, значит ошибок вроде «ждали жирафа пришел бегемот» там нет.

anonymous
()
Ответ на: комментарий от DarkEld3r

Уж извини, но не поверю. Пройтись по всем местам, которые компилятор покажет всяко удобнее, чем грепать и думать как бы заменить, чтобы лишнего не зацепить.

Поиск всех вызовов намного проще, чем парсинг говна тайпчекера, особенно учитывая тот факт, что тебе тайпчекер ошибку может выдать как угодно далеко от места, где она случилась, а греп - будет идеально точен.

Ну и кроме того никто не мешает просто запустить тесты и тебе по очереди выдаст все места с возможной ошибкой, только точнее чем типы и с более внятным описанием, чего не так.

anonymous
()
Ответ на: комментарий от anonymous

Как показывает практика, никому как раз не нужна верификация времени компиляции. Слишком много затрат.

Когда верификация нужна, нужна именно верификация времени компиляции. А так да, на практике хватает просто проверки типов.

А то, что динамические системы типов более выразительны - проблема разве что для тех, кто сопровождает такой выразительный код.

Да нет, никакой проблемы как раз нет.

Если есть код - есть и проблема, даже две. Вторая - в том, что «giving people dynamic languages doesn't mean that they write dynamic programs», так что для _использования_ всех чудес динамической типизации нужно постараться.

Слабые системы типов вроде хаскеля никаких интересных гарантий получить не дают, только ограничить возможность сложения слонов с бегемотами (а такие ошибки и так элементарно отлавливаются с околонулевыми затратами)

В Хаскеле они отлавливаются компилятором, а в динамике для этого приходится работать руками. Впрочем, если ты работаешь руками быстрее, чем работает компилятор Хаскеля... окей, у тебя different tradeoff.

тайпчекер ошибку может выдать как угодно далеко от места, где она случилась

Есть языки и помимо Хаскеля.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от nonimous

Перестань сочинять, очень даже типизированный:

И какой же у него тип? Пример типизированных макросов - TH, например.

Лiл, апологеты CL и динамики рассуждают о правильных макросистемах.

lil ну так в расте и есть макросистема уровня общелиспа, хотя даже хуже. Кусок неюзабельного говна.

Тут по крайней мере результат макроэкспаншена через тайпчекер проходит.

Отлично, чо. Удачи тебе парсить ошибки типов в нагенеренном макросами говнокоде.

anonymous
()
Ответ на: комментарий от anonymous

статическая аппроксимация в динамике

Ну это вообще пушка.

То есть система типов и там и там.

Ты читать не умеешь что ли? Ясно же написано, никакой типизации в динамике не бывает, бывает проверка тегов. Но я для тебя даже лучше цитату нашел:

Безопасность языка - это не то же самое, что статическая безопасность типов. Безопасности языка можно достичь при помощи системы типов, но можно добиться ее и с помощью проверок на стадии выполнения, которые отлавливают бессмысленные операции при попытке их исполнения и останавливают программу или порождают исключение. К примеру, Scheme является безопасным языком, несмотря на отсутствие статической системы типов.

или вот

Заметьте, насколько проверка метки в этом примере похожа на проверку метки во время выполнения в динамически типизированных языках вроде Scheme. В этом смысле можно сказать, что типовое вычисление «включает в себя» бестиповое или динамически типизированное вычисление.

nonimous
()
Ответ на: комментарий от anonymous

Ну напиши мне код с твоим result так, чтобы он в адъ и погибель не превратился.

Ты хочешь странного - «напиши с Result так чтобы без Result». Написать, чтобы не превращать в «адъ и погибель» легко: а + б. Тут result не нужен. Если хочется, то можно исключения кидать - тоже будет а + б. Result хорош для построения «апи нижнего уровня», а пользовательский код уже будет решать, что лучше - кидать исключения, паниковать или протаскивать и обрабатывать ошибки.

Обработка ошибок должна происходить отдельно от кода, а не быть размазанной толстым слоем говнища по всем потрохам.

Иногда (а может и довольно часто) имеет смысл обработать ошибку сразу.

То, что в расте нет нормальных исключений - другой вопрос. Мне это тоже не нравится и за отказ от исключений не агитирую.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Если ты хочешь выделить отдельную логическую группу ошибок

Нет, не хочу. У меня, допустим, есть 10 ошибок, каждая ф-я может бросить некую комбинацию нескольких из них. Делать 2^10 типов?

anonymous
()
Ответ на: комментарий от LongLiveUbuntu

Баг

Не баг. Наследование не всегда нужно, виртуальные функции тоже. Но это старый и бессмысленный холивар. Лучше про разыменование расскажи - как лучше сделать, по твоему.

DarkEld3r ★★★★★
()
Ответ на: комментарий от tailgunner

Вторая - в том, что «giving people dynamic languages doesn't mean that they write dynamic programs», так что для _использования_ всех чудес динамической типизации нужно постараться.

Для использования статической, представь себе, тоже.

В Хаскеле они отлавливаются компилятором, а в динамике для этого приходится работать руками.

В динамике для этого достаточно один раз запустить свеженаписанную функцию. Я в любом случае ее запущу - не важно есть у меня типы или нет. И это не считая тестов, которые тоже будут - опять-таки, есть у меня типы или нет. Таким образом, затраты 0 (ноль). С типами затраты не ноль.

Есть языки и помимо Хаскеля.

Речь о языках с нелокальным выводом типов, конечно.

anonymous
()
Ответ на: комментарий от anonymous

особенно учитывая тот факт, что тебе тайпчекер ошибку может выдать как угодно далеко от места

Это ещё с какой стати? Если мы не говорим про плюсовые шаблоны или тотальный вывод типов хаскеля, то всё нормально будет.

а греп - будет идеально точен.

Ну-ну.

Ну и кроме того никто не мешает просто запустить тесты

Мешать могут (и будут) не полные входные данные. Не знаю как ты делаешь, но у меня обычно следующая ситуация: изначально пишется тест, который, разумеется, не покрывает все случаи. Есть сoverage-билд по результатам которого тесты тоже дописываются, на практике, не настолько активно как хотелось бы. Баги всё-равно бывают и по результатам тесты дописываются, опять же.

По моему, если добавилась дополнительная ошибка, то поправить отвалившуюся компиляцию с её обработкой намного проще.

DarkEld3r ★★★★★
()
Ответ на: комментарий от nonimous

Ты читать не умеешь что ли?

Проблемы, видимо, у тебя. Я же процитировал тебе кусок где четко и ясно говорят, что система типов есть и в статике и в динамике. Вопрос исключительно в том, когда происходит тайпчек. У тебя даже жирным выделено.

К примеру, Scheme является безопасным языком, несмотря на отсутствие статической системы типов.

Правильно, статической - нет, динамическая (динамически проверяемая) - есть. Что тебе тут непонятно? Как ты умудряешься читать предельно ясный текст и делать из него совершенно противоположный тому, что хотели сказать авторы, вывод?

В этом смысле можно сказать, что типовое вычисление «включает в себя» бестиповое или динамически типизированное вычисление.

то есть система типов в динамическом языке является одной из статических систем типов (является частным случаем статическим, включается в их множество). Снова - что тебе тут неясно?

anonymous
()
Ответ на: комментарий от anonymous

камасутра возникает от того, что они чекают зависимые типы статически, при компиляции. Если чекать динамически, в рантайме - камасутры никакой нет.

Анонимус, ты прекрасен. Я рыдаю.

hateyoufeel ★★★★★
()
Ответ на: комментарий от DarkEld3r

Ты хочешь странного - «напиши с Result так чтобы без Result».

Нет, я тебя не просил бе result, я просил без ада и погибели. Но то как ты перефразировал уже само по себе какбы намекает, что result = адъ и погибель.

Иногда (а может и довольно часто) имеет смысл обработать ошибку сразу.

Я не говоря про _время_ обработки ошибки (с точки зрения control-flow). Я говорю, где это будет _в коде_.

anonymous
()
Ответ на: комментарий от anonymous

ну так в расте и есть макросистема уровня общелиспа, хотя даже хуже. Кусок неюзабельного говна.

Почему хуже? Ну и покажи примеры правильных макросов, правда интересно. Если что, растовые макросы не кажутся мне идеальными, так что тем интереснее - вдруг я чего-то не видел.

DarkEld3r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.