Представлен (https://blog.rust-lang.org/2016/11/10/Rust-1.13.html) релиз языка программирования Rust 1.13 (http://www.rust-lang.org), развиваемого проектом Mozilla, обеспечивающего автоматическое управление памятью и предоставляющего средства для высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime. Параллельно с Rust совместно с компанией Samsung развивается экспериментальный браузерный движок Servo (https://www.opennet.me/opennews/art.shtml?num=44712), написанный (https://github.com/servo/servo/) на языке Rust и отличающийся поддержкой многопоточного рендеринга web-страниц и распараллеливанием операций с DOM (Document Object Model).
В состав нового выпуска принято 1448 изменений от 155 разработчиков. Основные новшества (https://github.com/rust-lang/rust/blob/stable/RELEASES.md#ve...):
- Представлен новый оператор "? (https://github.com/rust-lang/rfcs/blob/master/text/0243-trai...)", позволяющий упростить построение конструкций для обработки ошибок. Оператор "?" проверяет возвращаемое функцией значение и если результат отличается от корректного завершения (Ok), осуществляется выход из функции с возвратом полученного кода ошибки (Err).Например, вместо кода:
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
теперь можно указать:
f.read_to_string(&mut s)?;
Ok(s)
Функционально "?" также может использоваться как замена макроса "try!", например, вместо "try!(try!(try!(foo()).bar()).baz())" можно написать "foo()?.bar()?.baz()?";- Обеспечен постоянный мониторинг изменения производительности через регулярный запуск тестов из набора rustc-benchmarks для актуальной кодовой базы с публикацией результатов на сайте perf.rust-lang.org (http://perf.rust-lang.org/), что позволяет оперативно выявлять все регрессивные изменения. Пример графика (http://perf.rust-lang.org/graphs.html?start=2016-08-25T01...), отражающего оптимизации добавленные в процессе разработки ветки 1.13.
- Проведена большая работа по увеличению производительности компилятора. Включение наработок по нормализации кэша во время трансляции, позволило при генерации промежуточного кода LLVM IR вместо повторных вычислений задействовать ранее рассчитанные значения. В некоторых ситуациях данная оптимизация сократила время сборки при включении отладочного режима на 40%.
Ускорена компиляция исполняемых контейнеров (crate), содержащий большое число inline-функций (#[inline]). Промежуточное MIR-представление подобных функций теперь сохраняется и используется во время генерации LLVM IR для всех вызовов из crate-контейнера. В некоторых ситуациях ускорение сборки может достигать 50%.
- В пакетный менеджер Cargo внесены изменения, направленные на увеличение безопасности, а также добавлены новые опции "--all-features" и "--message-format";- Обеспечена (https://github.com/rust-lang/rfcs/blob/master/text/0873-type...) возможность использования макросов для определения типов;
- В разряд стабильных переведена новая порция функций и методов.
Напомним, что язык Rust сфокусирован на безопасной работе с памятью и обеспечении высокого параллелизма выполнения заданий. При этом Rust обходится без использования сборщика мусора или runtime, что делает возможным создания на Rust библиотек, которые могут выступать в роли прозрачной замены библиотекам для языка Си. Для распространения библиотек на языке Rust, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo (http://blog.rust-lang.org/2014/11/20/Cargo.html), позволяющий получить нужные для программы библиотеки в один клик. Для размещения библиотек введён в строй репозиторий crates.io (https://crates.io/).По структуре язык Rust напоминает C++, но существенно отличается в некоторых деталях реализации синтаксиса и семантики. Автоматическое управление памятью избавляет разработчика от манипулирования указателями и защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Rust поддерживает смесь императивных, процедурных и объектно-ориентированных методов с такими парадигмами, как функциональное программирование и модель акторов, а также обобщённое программирование и метапрограммирование, в статических и динамических стилях.
URL: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
Новость: http://www.opennet.me/opennews/art.shtml?num=45481
>Rust напоминает C++, но существенно отличается в некоторых деталях реализации синтаксиса и семантики. Автоматическое управление памятью избавляет разработчика от манипулирования указателями и защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п.
>избавляет
>защищаетПочему-то в этой хвалебной оде языку Rust скромно умалчивается слово:
>опускает
производительность.
Потому что тут говорится про отличия от C++
Тут говорится про отличие от предыдущей версии. Но для утешения можете приврать чтонить.
Это очень даже отличие, и очень даже существенное.
Потому что это и дураку понятно.
Тише едешь - дальше будешь. Поэтому тырпрайз предпочтет неторопливую, но надежную яву высокопроизводительным крестам, -- крестам, которые будут нести разрабы, получая и закрывая ежедневно пачки тикетов, связанных со stack overflow.
И где ты был, когда всем делали прививки от Изенболы? Бесплатно, между прочим...
Судя по твоей обиженной речи, сам Изя тебе и сделал прививку.
>> защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п.
>>избавляет
>>защищает
> Почему-то в этой хвалебной оде языку Rust скромно умалчивается слово:
>>опускает
> производительность.А можно поподробнее -- как именно вы повышаете производительность обращением к областям освобожденной памяти и выходами за границы буфера?
Убирая проверки из рантайма. И по возможности реализуя их для debug сборки.
> Убирая проверки из рантайма. И по возможности реализуя их для debug сборки.C каких это пор вдруг компайлтайм == рантайм?
А Раст может узнать все размеры не выполняя программу? Чудеса. А если не все, то такое и для C/C++ есть: статический анализатор.
> А Раст может узнать все размеры не выполняя программу?А чего это вы перескочили на "все размеры"? Естественно, не все. И что? Отказаться от возможности сделать что-то во время компилирования из таких вот религиозных соображений?
>Чудеса.
Конечно чудеса, когда при проектировании языка учитывают современные возможности компиляторов и наработки в этой сфере. Только вот называются эти "Чудеса" -- 'владения', 'временные указатели' и 'время жизни', которые полностью контролируются програмистом и которые как раз и позволяют сделать "автоматическое" управление памятью и действительно убрать таким макаром целый ряд ошибок.
> А если не все, то такое и для C/C++ есть: статический анализатор.
И это, конечно же, заслуга структуры языка, особенно у слаботипизированного Си! Ви таки делаете мне смешно! А скажите-ка любезные, каким образом вы сможете проверить анализатором в сишной программе время жизни чего-либо или владения, если это не предусмотренно самим языком?
Кстати, походу мало кто из ярых "защитников истинного Си" понимает, какую титаническую работу проделали в гцц по части анализа кода и варнингов-рекомендаций. Запустили бы для сравнения какой нибудь Turbo/Borland C(++)/Watcom C -- а то привыкли к хорошему и воспринимают, как само собой разумеющееся ... да еще и на сторонние статистические анализаторы, которые появились *рен знает сколько лет после компиляторов кивают, типа "мы ежики, тоже летать умеем!" :).
Во-первых стандартный способ обхода массивов в rust - через итераторы, никаких проверок там нет.Во-вторых, если без обращения по индексу все-таки не обойтись и компилятор не может оптимизировать это место (как показывают тесты, очень большое "если"), можно поставить ключевое слово "unsafe" и применить арифметику указателей. В будущем с первого взгляда будет понятно, где искать баг, при этом все остальные преимущества rust (модули, cargo, и т.п.) сохранятся.
И в итоге любой нетривиальный алгоритм будет состоять из unsafe'ов чуть менее чем полностью.
> И в итоге любой нетривиальный алгоритм будет состоять из unsafe'ов чуть менее чем полностью.Или анониму следует объяснить что такое "нетривиальность" в его понимании или же найти тут http://benchmarksgame.alioth.debian.org/u64q/program.php?tes... или тут http://benchmarksgame.alioth.debian.org/u64q/program.php?tes...
ансейфы.
> И в итоге любой нетривиальный алгоритм будет состоять из unsafe'ов чуть менее
> чем полностью.Нет. Просто нужно использовать соответствующие парадигме программирования техники.
... и забыть о производительности.
> ... и забыть о производительности.А все почему? А потому что вброс^W гладиолус!
Или тут
http://benchmarksgame.alioth.debian.org/u64q/program.php?tes...
http://benchmarksgame.alioth.debian.org/u64q/program.php?tes...
ансейф невидимым шрифтом спрятан?
На benchmarksgame ссылаться - как на дистроватч.Синтетика, подкреплённая неадекватностью: https://habrahabr.ru/post/119579/
> На benchmarksgame ссылаться - как на дистроватч.Я ссылаюсь на код, который, как не крути, писался в первую очередь с целью "выжать все".
> Синтетика, подкреплённая неадекватностью: https://habrahabr.ru/post/119579/
Как будто без хабра никто об этом не знает.
PyPy кстати вроде никогда особо не блистал на игрищах, т.к. питоно-код был слишком заточен под CPython.
Вас hearthbleed видимо ничему не научил.
https://cve.mitre.org/data/downloads/allitems.html — посмотрите просто ради интереса, какая часть уязвимостей связана с этом самом супероптимизирующем подходе с отсутствием проверок границ.
Покажите реализацию SSL на божественном русте и без hearthbleed'a
> и модель акторовДоколе это будет кочевать из новости в новость о rust?
>> и модель акторов
> Доколе это будет кочевать из новости в новость о rust?Fractalide implements the actor model using the Rust programming language.
https://github.com/fractalide/fractalide
>>> и модель акторов
>> Доколе это будет кочевать из новости в новость о rust?
>
> Fractalide implements the actor model using the Rust programming language.
> https://github.com/fractalide/fractalidePykka is a Python implementation of the actor model, which makes it easier to build concurrent applications
https://github.com/jodal/pykkaТеперь в каждой новости о питоне тоже можно про акторы писать?
Я бы назвал это новостью об компиляторе Rust, чем о самом языке.Отличие между C++ и Rust: в C++ в начале разрабатывается стандарт, а уже потом пишутся компиляторы. В Rust же в начале пишется компилятор, а уже в будущем возможно будет стандарт.
Языковс формальным процессом стандартизации мало. В этом плане с++ скорее исключение.> в C++ в начале разрабатывается стандарт, а уже потом пишутся компиляторы
Нет. Во-первых, обычно первая реализация фичи появляется вместе с пропозалом. Иначе фичу скорее всего не примут в стандарт. Во-вторых, компиляторы реализуют будущий стандарт в процессе разработки. Да, на полную реализацию с++11 у компиляторов ушло значительное время уже после выхода стандарта. Но это потому что релиз был более чем мажорный. К моменту выхода с++14 и гцц, и шланг его практически уже реализовали.
в rust в начале пишется RFC. Но, в отличие от C++, RFC тут рассматриваются и принимаются непрерывно, а не раз в пару лет. Отсюда и гораздо более быстрый прогресс.
> Отличие между C++ и Rust: в C++ в начале разрабатывается стандарт, а уже потом пишутся компиляторы.Ха-ха. Сначала был Страуструп, который писал компиляторы. И написав очередную версию компилятора он переиздавал свою книженцию. Сначала он релизил компилятор, потом переиздавал книженцию. А первый стандарт появился в 1998 году, то есть лет через пятнадцать после Си с классами.
Поэтому не надо тут сказок рассказывать о великом C++. Его десятилетиями вгоняли в сколько-нибудь вменяемую модель развития. Ему скорее стыдиться надо этого, и гордиться там нечем.
Если первопроходцам надо стыдиться, то вы вообще должны были от стыда умереть ещё в яслях.
Этих "передовых" языков типа Rust и Go появляется нынче каждый день вагон, все они обещают скорость сей и простоту питона, но по факту там под капотом везде try!(try!(try!(foo()).bar()).baz()) , от которого любой человек впервые видящий этот код, но имеющий нормальный опыт разработки на более распространённых языках охреневает "что это? нафига? что делает этот синтаксический сахар? зачем такая вложенность? зачем повторно бросать уже брошенное исключение?", потому что это шило нечитаемо. Если в этих поделках от С что-то и осталось, то только всякие замороченный указатели с переподвыпердом, но никак не "вменяемая модель развития".
Тот же самый "вогнанный в модель" Go спустя достаточно много лет пропихивания под капотом содержит весьма невнятные методы с односимвольными переменными, кучей ремарок TODO с бросанием исключений "unsupported" и весьма скудными комментами по коду. В каком нибудь Qt за такой говнокод расстрел с баном, а у хипстеров ничего, вполне мейнстрим.
Ну с сей никто не уйдет как минимум потому что у него весьма обширная кодовая база. Ни один адекватный разработчик не станет переписывать быстрый отлаженный код, на менее эффективном Rust, тем белее в большом проекте. Ну а комментарии местных анонимов вообще не стоит принимать во внимание, их юношеский максимализм в связи с отсутствием серьезных проектов за плечами, позволяет им переписывать свои хелловорды на модные языки хоть каждый день...
Ну в дропбоксе, мозилле, фейсбуке и даже в самсунге конечно работают только школьники, у которых единственная цель — покрасоваться в новостях. Особенно учитывая что двое из перечисленных переводят свои главные проекты на раст — вот выпердрёжники-то! Тормозить же будет от проверки при обращении по индексу массива! И ведь сохранисть старую кодобазу и писать на расте только новые хэловорды нельзя.Ме кажется не стоит своё низкое культурное развитие приравнивать к сложности/нечитаемости/ненужности языка.
Это крупные игроки они располагают приличным финансовым капиталом и могут позволить себе экспериментировать, MS вообще все подряд скупает и закапывает, просто потому что может.
Так что твой аргумент, не аргумент, вот когда linux kernel перепишут на Rust тогда и расскажешь мне о серьезном применении ржавого. Ну а насчет низкого культурного развития, это похоже на неудачный вброс импульсивного анона, ибо необоснованно вообще никак. Ну и о школьниках я ничего не писал, ибо не привык мыслить стереотипами.
Что за мания переписывания? Кто-то предлагает завтра же выкинуть старый код из-за нового языка в проекте или что? Кто и зачем будет переписывать десятилетние нагромождения линукса?Та же мозилла внедряет его частично — см. quantum. Но нет, видимо пока на нём не перепишут всё легаси двадцатилетней давности, это так, игрушка не для сириус продакшена.
> Ну в дропбоксе, мозилле, фейсбуке и даже в самсунге конечно работают только
> школьники, у которых единственная цель — покрасоваться в новостях.В крупных коммерческих компаниях всё не так. Они вкладывают деньги в новые идеи, из которых выстреливает дай боже одна из десяти, причём половина из них - выстреливает на пиаре.
> Особенно учитывая
> что двое из перечисленных переводят свои главные проекты на раст —
> вот выпердрёжники-то!Если в компании сложилась мощная команда разработчиков именно на этом языке - так оно обычно и эволюционирует. Вот у нас в компании мощная команда скалистов: угадайте, на что переписываются старые демоны?
> Тормозить же будет от проверки при обращении по индексу массива!
Между прочим, могли бы сделать, как в Ocaml: флаг сборки, отключающий эти проверки в рантайме. При разработке собирать и тестировать с проверкой индексов, а при запуске на продакшене под большой нагрузкой - запускать версию без проверок (когда убедились, что таких проблем нет). Что им помешало так сделать - не понятно.
> И ведь сохранисть старую кодобазу и писать на расте только новые хэловорды нельзя.
О. Обычно происходит так: сначала пишутся на новом языке только новые части. И некоторым API они начинают взаимодействовать со старым кодом. Потом оказывается, что старый код стоит между двумя новыми частями. Новые части регулярно ломают совместимость со старым кодом на старом языке, а все обвинения летят в старый код, и компания решает от этого старого кода избавляться: "ребята, перепишите старый код на вашем крутом новом языке, вы так хорошо себя зарекомендовали, и вообще такие молодцы"!
> Ме кажется не стоит своё низкое культурное развитие приравнивать к сложности/нечитаемости/ненужности языка.
Ну так ведь речь не о ненужности Rust. У него есть потенциал, ещё не понятно, выйдет ли что-нибудь из него. Но PR уже идёт вовсю, как мы видим.
Речь лишь о том, как смешно мнение анонимов без опыта и кругозора, которые аппелируют лишь к тому, что "большие компании уже пихнули его в продакшен".
Мало ли что они там пихнули? Я знаю компании, которые себе лисп в продакшен пихнули (ну тот самый, тормознутый, со скобочками). И неплохо выстрелили, что интересно.
А хороший блин пост получился! Это ж блин в гранит надо! :)
Молдца freehck!
> При разработке собирать и тестировать с проверкой индексов, а при запуске на продакшене под большой нагрузкой - запускать версию без проверокЭто тупо. Ведь входные данные будут другими, следовательно никаких гарантий со стороны компилятора быть не может.
Я считаю, что будущее программирования всё-таки не за лексическим анализом, как в Rust, а за более развитыми системами типов. Впрочем, возможно, первое является частным случаем второго - в теории я не силён.
> Но PR уже идёт вовсю, как мы видим.
ЧСХ, ничто не мешает прикрутить тот же borrow checker к компилятору C/C++ и получить ту же самую безопасность (которую, к слову, никто так и не пруфанул научно: где статьи, доказательства, вот это всё?).
Рантаймовые проверки и вовсе можно реализовать средствами самого языка.P.S. Причина взлёта Rust не в пиаре. Дело в том, что львиная доля потенциальных дыр в коде реально отлавливается. Это факт.
>> При разработке собирать и тестировать с проверкой индексов, а при запуске на продакшене под большой нагрузкой - запускать версию без проверок
> Это тупо. Ведь входные данные будут другими, следовательно никаких гарантий со стороны
> компилятора быть не может.Ну не совсем. Бывают случаи, когда уместно сделать именно так.
Например, Вы пишете реализацию нового метода расчёта газодинамического течения на эйлеровской сетке. Сначала Вы обкатываете несколько решений на маленьких сетках, и вылавливаете все возможные проблемы метода. Затем начинаете расчёт реальных сетках, а там уже сотни миллионов ячеек могут быть, и вам постоянные проверки индексов так вдарят по мордасам, что мало не покажется.
Я замерял, из-за проверки индексов производительность падала на два порядка. Так что отключать подобные проверки смысл имеет большой.
> Я считаю, что будущее программирования всё-таки не за лексическим анализом, как в
> Rust, а за более развитыми системами типов.Поддерживаю. За этим Вам прямая дорога в Ocaml. Системы типов мощнее Хиндли-Милнера ещё не придумали.
> P.S. Причина взлёта Rust не в пиаре. Дело в том, что львиная
> доля потенциальных дыр в коде реально отлавливается. Это факт.Ну а кто ж спорит. Вполне может оказаться, что Rust после C - это рай. Но с другой стороны Scala после Java - это тоже рай, хотя синтаксис там ну ой...
Пока на языке не напишут некоторой критической массы кода, полезных open source проектов и т.д., я лично поостерегусь делать выводы о языке.
> Так что отключать подобные проверки смысл имеет большой.Ты не уловил посыл. В общем случае, если ты отключил проверки, то ошибки не исключаются. Ты не можешь конечным числом тестов на этапе разработки доказать их (ошибок) отсутствие.
> Вам прямая дорога в Ocaml
Haskell более по душе. Там тоже HM.
> Системы типов мощнее Хиндли-Милнера ещё не придумали.
>> Так что отключать подобные проверки смысл имеет большой.
> Ты не уловил посыл. В общем случае, если ты отключил проверки, то
> ошибки не исключаются. Ты не можешь конечным числом тестов на этапе
> разработки доказать их (ошибок) отсутствие.Да, совсем не исключаются. Это уже только детальным анализом алгоритма.
Но и мой посыл в другом: иногда лучше кое-как и сегодня, нежели хорошо и никогда.>> Вам прямая дорога в Ocaml
> Haskell более по душе. Там тоже HM.Ой, мы тут не подружимся. Я не воспринимаю Haskell: умолчательная ленивость - это слишком уж академично.
И кстати там не чистый HM. Там его расширили классами типов. И если для HM есть строгая теория, доказывающая корректность этого разолвера, то вот для этого расширения мне не известны доказательства корректности. Если они есть, поправьте меня пожалуйста.
>> Системы типов мощнее Хиндли-Милнера ещё не придумали.
> http://www.idris-lang.org/Ну хоть пару слов скажите в затравку. Моё время тоже не резиновое.
> умолчательная ленивость - это слишком уж академичноМожно seq везде писать.
> Ну хоть пару слов скажите в затравку. Моё время тоже не резиновое.См. последний пример в Examples у них на сайте. Копипастой/переводом не занимаюсь.
> И кстати там не чистый HM. Там его расширили классами типов. И
> если для HM есть строгая теория, доказывающая корректность этого разолвера, то
> вот для этого расширения мне не известны доказательства корректности. Если они
> есть, поправьте меня пожалуйста.А в чём проблема? Любой класс типов можно рассматривать как обобщающий тип. Разница лишь в том, что конкретизировать класс типов можно не в любой тип, а только в тот, для которого определены требуемые для данного класса типов функции.
Но это не важно, потому что в правилах вывода типов не используется конкретизация типов вообще, только обобщение.Иными словами, HM + классы типов - это подмножество HM.
ИМХО.
> Я не воспринимаю Haskell: умолчательная ленивость - это слишком уж академично.Зато на самом деле очень удобно, если научиться этим пользоваться (я пока умею не до конца, правда).
Ну и в ghc 8 запилили {-# LANGUAGE Strict #-}.
> И если для HM есть строгая теория, доказывающая корректность этого разолвера, то вот для этого расширения мне не известны доказательства корректности.
Вы именно о выводе типов? Если да, то в худшем случае вывод типов просто никогда не завершится (что возможно для rank-n polymorphism вообще, если я правильно помню, и для некоторых условий на несужающиеся инстансы типов, что включается расширением UndecidableInstances, в качестве частного случая).
Если уж прям так припёрло обращаться к массивам па значению, можно либо пойти посчитать всё на фортране (и работать будет гарантированно быстрее), либо воспользоваться ансейфом с методам get_unchecked и даже адресной арифметикой (для желающих разные версии дебага и релиза — оператор [] прекрасно перегружается). Ещё есть версия брать слайсы от массивов (баундчекинг будет срабатывать ровно 1 раз).А отключать их нельзя по той причине, что все разговоры об этом сводятся к кейвордам "безопасность" и "hearthbleed".
> Ну с сей никто не уйдет как минимум потому что у него
> весьма обширная кодовая база. Ни один адекватный разработчик не станет переписывать
> быстрый отлаженный код, на менее эффективном Rust, тем белее в большом
> проекте.Кстати, в связи с этим есть мнение, что хороший язык, который хочет пойти в продакшен, должен реализовывать хорошую поддержку cffi с простым и понятным синтаксисом.
Сишный ABI прост как палка и просто прикручивается куда угодно.
Другое дело что чтобы комфортно работать с ним из другого языка со своими концепциями и стилем уже требуются дополнительные телодвижения.
> try!(try!(try!(foo()).bar()).baz())
> зачем такая вложенность?
> зачем повторно бросать уже брошенное исключение?Кстати да, это интересный вопрос.
Обычно это делается так (пример на Ocaml)try foo () |> bar |> baz
with exn -> exn_handler_codeИ какая бы из функций конвеера ни бросила отсключение, его обработает exn_handler_code.
Поясните кто-нибудь, зачем тут вложенные try?
Потому что в расте и нету исключений. try! — это макрос для тех, кому лень на каждый вызов возвращающий Option/Result писать unwrap/unwrap_or или матчить руками. Для того оператор ? и ввели.
> Потому что в расте и нету исключений. try! — это макрос для
> тех, кому лень на каждый вызов возвращающий Option/Result писать unwrap/unwrap_or или
> матчить руками. Для того оператор ? и ввели.О. Это несколько неудобно. Исключения, конечно, механизм медленный, но при большой глубине стека они сильно выигрывают как по выразительной силе, так и по скорости.
Исключения какие-то. Тяжело без монадического Either :)
>> ... в C++ в начале разрабатывается стандарт, а уже потом пишутся компиляторы. В Rust же ...neon1ks, Вы ничего не перепутали?
В Цпп сложилась такая ситуация: множество компаний делают свои компиляторы языка C++, потом комитет по стандартизации собирает полезные новшества + заявки от участников комитета и прочих пользователей языка => появляется новая версия стандарта. См. [ https://ru.wikipedia.org/wiki/C%2B%2B#.D0.A0.D0.B0... ]или, ещё лучше, см. сюда: [ https://isocpp.org/std/the-life-of-an-iso-proposal ].
Значит заблуждался.
Синтаксис ужаснейший просто.
> Синтаксис ужаснейший просто.Согласен, налепили уже столько говна, что С++ кажется не таким и страшным.
Так кажется только до тех пор пока не попробуешь. Ну а некоторые ограничения быстро отбрасывают "горе-девов", которые рвутся имплементить что-либо после просмотра хеллоу-ворлда, вместо того что бы прочитать спецификацию.
А спецификация у языка Раст не на 1500 страниц, как у С++? Единственная известная мне спецификация, которую при желании реально прочесть за раз от корки до корки - это у Go. Буквально несколько дюжин страниц.
Может ты просто мало языков знаешь? Посмотри на Component Pascal.Спецификация на Go 25.5k слов, 3k строк
Спецификация на CP 1.5k слов, 0.3k строкРазница на порядок и не в пользу go.
И это мы еще не берем эзотерику вроде brainfuck.
Эзотерику мы не берём и правильно. А Component Pascal где-то также распространён как и Go? Если бы да, то и я бы о нём знал. Но теперь буду знать, спасибо. Ведь интересно сравнить те языки, которые по тем или иным причинам пробились.> Спецификация на Go 25.5k слов, 3k строк
> Спецификация на CP 1.5k слов, 0.3k строкТак, Go: https://golang.org/ref/spec и CP: http://www.oberon.ch/pdf/CP-Lang.pdf
В CP-Lang.pdf 32 страницы - так что никак ни 300 строк, а$ pdftotext CP-Lang.pdf - | wc
2321 11097 700942.3k строк.
Да, у меня в прошлом посте неверные цифры. Скорее всего из-за копирования текста с неотрендеренного полностью pdf. Тем не менее спецификация его действительно короче чем у go.
Неужто о семействе языков pascal ни разу слышать не приходилось?
Именно Component не помню. Об Обероне, конечно, да. А на VHDL и писать время от времени приходится. Аду как минимум читать, т.к. свободный симулятор GHDL на ней написан.
Мне кажется, что в последнее время создатели новыхнедоязыков, употребив наркотические средства, придумывают синтаксис, который читаем и понятен только им. Такими темпами скоро будет: f a &t *f = | &a ^ !g | .. : str -> { ok(a?) }
И ты тоже мало языков знаешь. Вот тебе реальный пример кода на J, одном из потомков APL:>([:{: ]#~ (=|.&.>)) <@":"0 /:~(0:-.~[:,>:/**/)~(i.100)-.~i.1000
Посмотри в какие годы появились эти два языка.
Наркоманский код, ужас просто...
Дело привычки и знания синтаксиса. Мне после perl крайне неудобно работать с идентификаторами без сигилов, которые сразу указывают на тип. А у тех, кто не знаком с такой удобной штукой, обилие $ @ & % вызывает отвращение, им привычней добавлять к идентификатору короткие слова вроде array, list, map. При этом те же {} вместо begin end им почему-то кажутся нормальными, хотя это тоже "наркоманские" символы, но к ним привыкли и их значение известно.
Есть ещё язык, на котором уже давно (с конца 60-ых) и всё ещё реально программируют. В основном, в области здравоохранения - MUMPS (в том числе диалект в бывшем СССР - Диамс). Но есть и игровые примеры. Читается на первый взгляд не очень просто:https://github.com/pkoper/mumtris.git
write(s,y,x)
n i,j,l,c,d
d pos(y,x)
s l=$l(s) f i=1:1:l d
. s c=$e(s,i)
. i c?1N d
.. i 'c s y=y+1 d pos(y,x) q
.. s d=$e(s,i+1) f j=1:1:c w d
.. s i=i+1
. e w c
d pos(0,0)
q
Зачем привыкать к плохому? Работа программиста - разрабатывать новый функционал и исправлять старые ошибки, а не одолевать бессонными сутками планку очередного одноразового выноса мозга. Ошибки зачастую вылазят именно из-за неоднозначности кода. Т.е. ты считаешь что он во всех ситуациях будет вести себя как тебе надо, а он в 99 отработал так, а в 1 иначе. И без 10000 часов зубрения этого ЯП ты всё равно будешь ошибаться, ошибаться и ошибаться (людям свойственно). И твой волшебный код обсыпанный "сахаром" и обмазанный известными только тебе типсами и триксами никому не нужен, потому что он несопровождаем. И Security through obscurity в исходниках не нужно.
Еще раз для танкистов. Почему {} вместо begin end или вообще пробелов/табов это читаемо, сопровождаемо итд, а тот же % вместо map, dict или как еще фантазия подскажет конкретному програмисту - уже нет? А с неоднозначностью вообще мимо. Сигил @ означает список(массив) для любого программиста на перл, в отличии от скажем прилепленой к имени буковки L или A, которые расшифровываются в List или Array только для автора кода.
> Почему {} вместо begin end или вообще пробелов/табов это читаемо, сопровождаемо итд, а тот же % вместо map, dict [...] - уже нет?Потому что человек с трудом осилил синтаксис C, и теперь мысль об освоении нового синтаксиса вызывает у него неконтролируемые приступы паники.
Хотя, в отношении раста, мне кажется ситуация ещё веселее. Там проблемой является не синтаксис, а семантика, в частности "память" как абстракция языка -- раст видит память очень по своему, что создаёт проблемы при освоении раста, необходимо научиться думать о памяти в терминах раста, понимая эти термины именно так, как задумано. Умение так думать -- это новые навыки, вырабатывать новые навыки сложно, плюс это интеллектуальные навыки, отсутствие которых приводит к тому, что "почему-то не получается писать на расте, но почему непонятно". И вот тут человек начинает выдумывать причины объясняющие это непонятно. Единственная проблема, которую он чётко видит и может сформулировать -- это непривычный синтаксис, и он с готовностью объясняет все свои неудачи непривычным синтаксисом.
Это явление, которое чем-то сродни когнитивному диссонансу. Человек всегда ищет и всегда находит объяснения происходящему, и 95% не может находится в состоянии, когда есть что-то непонятное, чему нет объяснения. И когда у такого человека нет никакой возможности придумать здравое объяснение, он придумывает первое попавшееся. Есть байка про Фрейда, который проводя публичную лекцию пригласил на сцену человека из зала, ввёл в гипнотический сон, и дал тому инструкцию: выйдя из гипнотического сна забыть про инструкцию, пройти на своё место в зале, а когда Фрейд хлопнет в ладоши, подойти к Фрейду и подарить ему свою шляпу. Инструкция сработала, всё так и произошло, но самое интересное было дальше: этого добровольца спросили, чего это он подарил шляпу Фрейду, на что тот начал нести какой-то несвязный бред о том, что он очень уважает Фрейда, и хотел как-то выразить своё уважение, и поэтому подарил шляпу.
Это байка и про Фрейда, да ещё и с гипнозом, которая может не вызывать доверия, но есть множество других демонстраций тому же явлению, и эта байка укладывается в общую картину.
Люди очень некомфортно чувствуют себя в ситуации, когда они не могут вообще никак объяснить происходящее. И в такой ситуации они придумывают бредовое объяснение и искренне в него верят, не замечая бредовости.
клоун: Сначала по поводу Фрейда. Мозг работает в условиях жесточайшего дефицита информации, поэтому додумывает недостающую информацию (воображение), строя полноценную (в рамках решаемой задачи) картину мира. Это проявляется напр. в возможности прочесть текст, в котором перемешаны буквы в словах:По рзеузльаттам илссоевадний одонго анлигсйокго унвиертисета, не иеемт занчнеия, в каокм проякде рсапжоолены бкувы в солве. Галовне, чотбы преавя и пслонедяя бквуы блыи на мсете. осатьлыне бкувы мгоут селдовтаь в плоонм бсепордяке, все-рвано ткест чтаитсея без побрелм. Пичрионй эгото ялвятеся то, что мы не чиаетм кдаужю бкуву по отдльенотси, а все солво цлиеком.
При этом мозг исходит из логичности мира. Он опирается на признак, который проще распознать, напр. на цвет букв, а не на их форму http://bespoleznyi.ru/_bl/3/17566004.png
Это высшая нервная деятельность. Дети начинают овладевать ею с 4-6 лет до 10-12 лет. Животные - никогда.
Будем ложить еду (бананы) в два ящика: в маленький ящик всегда много бананов, в большой (очень большой) всегда только один. Обезьяна всегда будет начинать с большого ящика. Кажется глупым, но в живой природе большое дерево приносит больше плодов, чем маленькое, поэтому обезьяна права.
Если оправдывать ожидания, то обучение идёт легче и быстрее, чем если обманывать их.
Как вы думаете, оператор "+" выполняет сложение, вычитание или деление с остатком? Сложение - и вы правы!
Как обратиться к 10-ому элементу массива mas? mas[10] - и вы неправы! Нужно try(unsafe(mas[10])) и это, хотя и работает, тоже неправильно. Правильно - переписать весь алгоритм чтобы не обращаться к элементу массива по индексу.
Чувствуете разницу? Это как будто вам запретили использовать букву "И" в словах, требуя заменять её на "Ы".
Ограничение бессмысленное. Почему нельзя этого делать? Почему можно делить на 1 (что бессмысленно логически), но нельзя делить на 0? Почему только деление на 0 приводит к прерыванию выполнения?
Среда разработки может без труда найти все обращения по индексу и показать все небезопасные части кода, зачем явно дописывать "unsafe" к каждому из них? Напоминает времена, когда человек, работающий удалённо на зарубежного работодателя, должен в каждом своём интернет-посте и обращении в гос. органы именовать себя "враг народа" ("Я враг народа, Иванов И.И. прошу предоставить мне справку"), а организация - "иностранный агент" ("Мы, иностранный агент, 'Голос' хотим знать поддерживаете ли вы Президента?").
Это не необходимость синтаксиса, это указание на неполноценность, которое вы должны сами явно написать.
ЯП (как и любое новое знание) должен опираться на уже известное, улучшая или упрощая, а не создавая искусственные проблемы.
В php можно обратиться к несуществующему или даже отрицательному индексу массива (NULL или элемент с конца массива соотв.). Во многих ЯП можно складывать строки с числами (получится строка, содержащая число). Или преобразовывать значения без явного приведения типа.
Это удобно и правильно. И именно такие ЯП победят. А не те, в которых тебя заставляют бегать на ходулях и убеждают что так будет удобнее. Потом. Когда привыкнешь. Когда-нибудь точно.
> Как обратиться к 10-ому элементу массива mas? mas[10] - и вы неправы!Конечно, во первых это будет во многих случаях одинадцатый элемент, во вторых, все это через одно место и правильно нужно вот так:
?- nth0(3,[1,2,3,4],X).
X = 4.
?- nth0(I,[1,3,3,7],3).
I = 1 ;
I = 2 ;
false.
?- X=[1,2,Y], nth0(1,X,1337).
false.
?- X=[1,2,Y], nth0(2,X,1337).
X = [1, 2, 1337],
Y = 1337.
> Это удобно и правильно. И именно такие ЯП победят. А не те,
> в которых тебя заставляют бегать на ходулях и убеждают что так
> будет удобнее. Потом. Когда привыкнешь. Когда-нибудь точно.Да-да, васики победили! Сколько их там из "изначальных" используются вне музея, говорите? Ах, совсем ни сколько. А что так?
клоун: Хотя кашалоты большие и тяжёлые, но суммарно в океане планктона больше. Я это к тому, что всевозможные простенькие (и не очень) веб-сайты пишут на php, а учётные системы в РФ - на 1С.Из расчётов общего объёма кода эти (и многие другие подобные) ЯП выпадают, (на github их не постят), но суммарно и программистов и кода на них написано больше.
> Из расчётов общего объёма кода эти (и многие другие подобные) ЯП выпадают,
> (на github их не постят), но суммарно и программистов и кода
> на них написано больше.Только как-то проверить это заявление никак не получится.
Да и кому интересны миллионы хелло-ворлдов? Вы бы еще предложили посчитать то, что пишется на уроках информатики.А вот если взять среднестатистического сферического^W пользователя и программы, которые он использует (сравнив хотя бы по времени активного использования программы ... или по loc/объемам кода), то я не уверен, что современный "планктон"^W бейсик перевесит.
Потому как и пых и 1С отнюдь не "сами на себе" написаны, да и браузеры с ОС, гуями, серверами и прочей инфраструктурой, необходимой для того, чтобы фоточка котика из смартфона одного пользователя добралась до экрана другого -- пока еще погрязли в отсталости и, к великому сожалению интелей и прочих, переходить на васики не собираются ;)
клоун: на 1С пишут не hello world'ы. И личный веб-сайтик он хоть и простенький, но реально работает.
Я не хочу возражать по программистской части, потому что это будет старым-добрым спором о статической сильной системе типов vs динамической слабой, о доказываемой корректности программ и прочем всяком, поэтому ограничусь математической частью.> Почему можно делить на 1 (что бессмысленно логически)
Это не бессмысленно логически. Либо продемонстрируйте, пожалуйста, систему аксиом и вывод утверждения, показывающего, что это бессмысленно.
> но нельзя делить на 0? Почему только деление на 0 приводит к прерыванию выполнения?
Потому что деления нет, есть умножение на обратное. А у нуля обратного элемента нет. Введение обратного приведет к ряду забавных вещей, которые вы, без сомнения, увидите сами, если примете такую гипотезу.
клоун: математически результат не опоеделяем, но это не означает что нужно прерывать выполнение. Можно вернуть 0 или NaN (not a number любые операции с которым дают NaN).Я заколебался каждый раз это условие писать.
> это не означает что нужно прерывать выполнениеЯ говорил про математическую сторону. Про выполнение там вообще ничего не было.
> Можно вернуть 0
Нельзя.
> или NaN (not a number любые операции с которым дают NaN).
Поздравляю, вы почти придумали монаду Maybe.
А, и ещё, кстати.
> клоунЛюбопытства ради, зачем вы это каждый раз приписываете к началу своего комментария?
клоун: Математика в программировании существует весьма условно. Так x=x+5 или x==y ("==" в сравнениях) в математике не имеют того же смысла. Запись сложных математических выражений в одну строчку тоже не приветствуется.Поэтому можно возвращать то, что удобно. NaN или 0 удобны тем, что не прерывают работу программы.
Я за то, чтобы ни одна операции не прерывала работу программы. Верните NULL, NaN, INF - любую белеберду, но не нужно заставлять людей писать try-catch повсюду. Это уже наркомания: подсел и не слезешь.
> Любопытства ради, зачем вы это каждый раз приписываете к началу своего комментария?
Все сообщения с никами "клоун Стаканчик" и "клоун" автоудаляются сразу после добавления на форум (любят меня тут).
>>([:{: ]#~ (=|.&.>)) <@":"0 /:~(0:-.~[:,>:/**/)~(i.100)-.~i.1000Не имею понятия, что здесь написано, но вставлю свои пять копеек.
Иногда ценность имеет возможность писать максимально компактно, так, чтобы как можно большая часть программы влезла в один экран. Подозреваю, что это тот случай.
Никто ж не возмущается что люди используют регулярки вместо кучи вложенных циклов.
> Мне кажется, что в последнее время создатели новыхнедоязыков, употребив наркотические
> средства, придумывают синтаксис, который читаем и понятен только им.Это как раз и есть одна из причин, зачем программисту нужна математика. Программист должен уметь справляться с символической записью. Одолевая курс матана, беря интегралы, решая дифуры или доказывая, что их невозможно решить аналитически, или размахивая расширениями полей, доказывая что данный многочлен имеет один корень в радикалах и ещё три трансцендентных, причём два из них равны -- занимаясь всей этой, казалось бы бессмысленной деятельностью, будущий программист учится пользоваться символическими языками, он учится мыслить на символических языках -- не на максимально обобщённом и неопределённом русском матерном, а на символических языках, которые максимально заточены на конкретную задачу.
Синтаксис нового языка должен быть понятен только посвящённым, иначе это не новый язык, а очередной недоклон сишечки. Ну или алгола, хотя сегодня это уже не столь актуально.
Бред.Языки программирования придумывались, чтобы упростить работу программисту (большинство). ЯП - транслятор человеческой логики в машинную. Для развлекушек с символами есть свои местечковые ЯП и нефиг переносить это в общий тренд.
НЕ бред, Haskell богат всяческими сахарными операторами и прочими особенностями, повышая тем порог вхождения новичков, он достаточно сильно абстрагирован от машины (сильнее чем си или rust), то-есть он по-сути "человечнее", и рождён этот сахар был не для того, чтобы прогнуться под особенности машины, а чтобы реализовать потребности человеческой логики, просто этот язык и его тонкости нужно знать, чтобы использовать это эффективно, и по факту это и есть упрощение переноса человеческой логики в машинную, удалясь от деталей реализации машины так далеко, как это возможно, чтобы не потерять эффективность, при этом кратко и лаконично выражая идеи человеческой логики.Позовите Васю с улицы, который никогда не программировал, или из компьютеров видел только смартфон, и покажите код, который по вашему понятен и прост, для него это будет ни чуть ни меньшей магией, которая ни с какого ракурса не выглядит просто, потому что Вася не знает языка, у него нет образных паттернов и ассоциаций, которые помогут ему понять что всё это значит.
Самый простой язык по вашему - это Forth.
PEN APPLE UGH!
И получаем на вершине стека APPLEPEN.
> Для развлекушек с символами есть свои местечковые ЯП и нефиг переносить это в общий тренд.Окей. Нефиг, так нефиг. Мозилла идёт своим трендом, а общий тренд пускай катится куда ему угодно. Меня такое положение дел вполне устраивает.
Ты в силу отстутсвия опыта конечно не поверишь, но использование неалфавитноцифровых символов(или просто [^\w]) таки упрощает работу программиста, причем как по написанию, так и по чтению кода. Точно также как они упрощают запись и чтение выражений в математике. Например, вместо громоздкой фразы "необходимо и достаточно" или "тогда и только тогда" можно написать просто "<=>" и каждый математик это поймет, точно также как ты понимаешь, когда вместо "2 плюс 2 равно четыре" пишут "2+2=4".
клоун: Ты действительно считаешь, чтоif(JumpStm *j = dynamic_cast<JumpStm*>(&stm))
удобнее, чем
if(j=stm)
Громоздкие синтаксические конструкции возникают из-за непродуманного синтаксиса.
Взять напр. математику, в ней нет необходимости добавлять проверку на ноль или исключение всякий раз когда встречается деление. И вопрос как это сделать в программировании быстро и удобно. Как в php, добавив @ перед строкой или как в С++:
#include <exception>
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
}Синтаксис явно избыточен.
А вот другой пример с заменой цикла:
for(int i=0;i<=mas.count();i++)
{
arr_element element=mas[i];
TODO
}на
forany(element,mas)
{
TODO
}Очевидно, что такая замена пошла коду на пользу. Количество синтаксиса, переменных и возможностей совершить ошибку сократилось.
> Взять напр. математику, в ней нет необходимости добавлять проверку на ноль или
> исключение всякий раз когда встречается деление.Вообще-то есть. На нулевые и вырожденные случаи постоянно проверять надо. Вы не можете сказать, что ab = cb ⇔ a = c, вы должны сказать ab = cb ⇔ a = c ∨ b = 0. Вы не можете сказать, что в комплексном векторном пространстве у оператора существует собственное значение, вы должны сказать, что в ненулевом комплексном пространстве у оператора существует собственное значение.
> И вопрос как это сделать
> в программировании быстро и удобно.Завернуть вычисление в Either-подобную монаду и писать везде >>= (ну или do).
Согласен. Лично меня из с++ заменителей больше всего привлекает D, хотя бы своим вменяемым синтаксисом, на котором приятно писать.
>Лично меня из с++ заменителей больше всего привлекает DА меня вот ничего не привлекает, останусь на C++.
>> замена макроса "try!", например, вместо "try!(try!(try!(foo()).bar()).baz())" можно написать "foo()?.bar()?.baz()?";- Это называется "безопасный язык"? В нем логических ошибок будет по три на строчку, учитывая контингент (школота), наложенную на уверенность в "безопасности".
Контингент "школота" его либо обойдёт либо будет поднимать уровень знаний. Иначе они просто будут бороться с компилятором ибо он будет больно бить по рукам за тот шит который они делают. А борьба с компилятором быстро утомит порывистого юнца если он решил что он умнее книг.
Пока что данный язык школотой используется только в комментах, потому как если б она столкнулась с ним на практике, внезапно б выяснилось, что язык этот сильно плох и вообще виновен во всём и сразу, включая залёт одноклассницы, двойку по физике и повестку из военкомата (да-да, программа ж сама не написалась так правильно, как хотел заказчик, программист тут ни при чём). Такими свойствами форумные интеллектуалы уже наделили PHP и C.
Write-only language. Читаемость соревнуется с Scala.
В отличие от скалы у него очень строгий синтаксис, не имеющий даже половины фичей скалы.
Но опять же — из подобных комментариев становится видно, как хорошо человек знаком с обсуждаемым языком, или с его аналогами с трёхэтажными макросами/шаблонами на наследованием которым не уступает жаве (причём множественным) и прочими вкусностями.
Rust поддерживает смесь императивных, процедурных и объектно-ориентированных методов
Наследование не завезли
А формальное определение ООП с которым бы все согласились уже завезли?
Пока эта парадигма у каждого своя — глупо ждать какой-то конкретики от языков с этим кейвордом в описании.
Покажи мне компактную реализацию наследования в ржавчине. Не 100500 строк как в оттранслированном коде с vala на c.
Формальное определение ООП - инкапсуляция, наследование, полиморфизм.
>> ...наследованиепока идиоматическое наследование в Rust это только - композиция.
>жаба
>инкапсуляция, наследование, полиморфизм.Нет формального определения ООП. Указанное выше справедливо для жабы, но не для всех языков.
> Rust поддерживает смесь императивных, процедурных и объектно-ориентированных
> методов
> Наследование не завезлиНаследование "дорогое". Для системного языка не подходит.
Что-то я не увидел особо желающих писать на расте для микроконтроллеров. А вот как замена крестам - многие. Кроме того никто же не заставляет везде совать классы, достаточно всего-лишь добавть немного синтаксического сахара и программисты сами разберутся где использовать наследование а где нет.
С практической точки зрения, достаточно "расширения" структур. Условно
struct Foo{
int a;
}
struct Bar extend Foo{
int b;
}
Перевести нововведение на человечий язык можно так: теперь вместо саркастичного "Да!Да!Да!Такяиповерил()" можно просто сказать "Дану?", что гораздо удобнее.
Улыбнул! :) Паря - тебе надо ЯП писать а не посты в уютненький :)
>уютненький
>постыТы вообще понимаешь, что пишешь? Кроме улыбашек что-то есть в голове?
Семён просто незаметен.
Rust украл часть нового синтаксиса нового у Swift 3.0Выглядит как ужаснищий костыль сравнимый с началами Brainfuck.
Это стабильный релиз с "?" - а так этот сахар уже более полугода живет в коде живет.
Хотя нет, вот RUST-RFC на базе которого эта фича появилась, от 2014 года!
Ещё до того как Swift 1.0 появился!https://github.com/rust-lang/rfcs/pull/204
и кстати, с чего это костыль?
А вот в вопросе "и кстати, с чего это костыль?" знак вопроса собственно обозначает вопрос, в С/С++ знак вопроса тоже обозначает вопрос Условие ? Да : Нет, но я не очень понял чего конкретно означает знак вопроса в Rust. При этом вариант ответа "Да" существует и объявлен явно, а вариант "Нет" тоже существует, но явно не объявлен. А уж в примерах с try!(.....) try! куда более информативен.
Не осилили C++, придумали Rust. Читаемость кода - просто шизец. Я согласен с теми, что писал выше, что это write-only language.К слову есть замечательное семейство языков LISP. Или тоже осилить не можете?
Помню был случай на работе. Веб-разработчики, вместо того, чтобы делать работу, начали абстрагироваться и абстрагироваться и 2 месяца убили на то, чтобы сделать корявую пародию на Twig. Запилили свой шаблонизатор, который начал превращаться в новый ЯП со страшными конструкциями.
Т.е. в организации вместо того, чтобы работать и выполнять задачи, разрабы придумали неиспользуемую write-only херню. Извините за мой франц.
Так вот. При чем тут веб-разработка, Twig и новый ЯП?
А вот при том, что тут похоже, кто-то не осилил C++, и начал городить огороды. Получился новый Perl, простите, Rust...
Ребят, надо проще быть. Учите языки, а не изобретайте. Работайте, а не страдайте хренотой.
Все уже изобретено до вас. C/C++/Lisp/SQL/HTML. Что вам еще-то надо?
> Не осилили C++, придумали Rust....
> А вот при том, что тут похоже, кто-то не осилил C++, и
> начал городить огороды. Получился новый Perl, простите, Rust...И правда, куда уж всяким Грейдонам Хорам https://github.com/graydon до Ыкспертов опеннета ...