LINUX.ORG.RU

Альфа-версия Rust 1.0

 


2

6

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

Тем не менее, апгрейд в линии от альфа-версии до финальной версии может вызвать мелкие несовместимости (Sync/Send changes, переименование uint/int в usize/isize), но все проблемы планируется решить до выпуска 1.0.

Основные изменения со времени предыдущего релиза:

  • улучшенная поддержка массивов и подобных им контейнеров в языке: DST
  • унификация трейтов и замыканий в виде unboxed closures: теперь замыкания - это просто объекты, реализующие определенные трейты

Полный список изменений с подробным их описанием по ссылке:

>>> Подробности

★★★★★

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

try/catch вообще не дает оверхеда, можно хоть обмазаться ими,

Зависит от реализации исключений. Хотя я бы тоже хотел видеть их в расте...

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

Зависит от реализации исключений. Хотя я бы тоже хотел видеть их в расте...

А я чем дальше, тем больше склоняюсь к тому, что они не нужны. Нужен механизм работы с Result - монады, макросы, whatever.

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

Кстати, в D вообще есть условная компиляция по произвольному условию?

static if (compile-time-evaluated-condition) { // code here }

Экономия мизерная, зато однообразие нарушается

А соотношение логики к «шуму» - ухудшается :) Однообразие должно быть в семантике, в синтаксисе от него не слишком много пользы.

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

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

void foo(S, T)(T arg)
    if (isSomeString!S)
{
    auto s = to!S(arg);
}

И для кода конкретно этой функции не важно, для преобразования вызывать from_str или from_byte_array или from_int. Это не её дело, знать такие вещи.

Как аналогичные вещи предполагается делать на Rust?

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

static if (compile-time-evaluated-condition) { // code here }

Про static if знаю, но в С++ можно директивы препроцессора извне передавать. В D есть для этого механизм? Только не дебаг уровень и не версию, а именно условие для такого if.

А соотношение логики к «шуму» - ухудшается :)

Иногда «многословие» не вредит. Скажем, в С++ не надо указывает брейк в свитче, а в D требуется явно писать continue. Многословнее, но спасает от ошибок.

Хотя в данном случае, мне просто!не!нравится!такой!синтаксис.

Кстати, в D правда используются конструкции «>>>=», " !<>=" и т.д.?

Как аналогичные вещи предполагается делать на Rust?

В расте шаблоны (дженерики) работают иначе. Произвольные методы вызывать нельзя. Поначалу это меня тоже раздражало. Делать придётся примерно вот так:


trait ToString {
    fn to_str(&self) -> String;
}

fn foo<T:ToString>(value : T) {
    let a = value.to_str();
}
То есть надо указать, что функция может принимать любой тип, который реализует трейт ToString. Если бы трейт был стандартным, то для стандартных типов уже была бы реализация. Добавлять поддержку для своих типов легко.

Если не хватает гибкости - придётся обратиться к макросам.

Кстати, В С++ шаблоны вынуждены содержаться в хедерах. В D ведь полноценные модули, по идее. Может реализация шаблона быть скрытой?

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

В D есть для этого механизм? Только не дебаг уровень и не версию, а именно условие для такого if

Нет, по крайней мере не в формате -DMYDEBUG=43. Обычная практика - иметь модуль вида CTFlags.d который генерируется системой сборки и содержит нужные данные. Вообще WB считает, что если нужно задать что-то круче -version=MyCoolVersion, то у вас проблемы в коде :) У меня нет мнения на этот счёт.

Делать придётся примерно вот так

В моём примере String тоже является параметром шаблона и может быть любым совместимым пользовательским типом. Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

Кстати, в D правда используются конструкции «>>>=», " !<>=" и т.д.?

Никогда не видел в живом коде. Code review в стандартную библиотеку оно бы точно не прошло.

В D ведь полноценные модули, по идее. Может реализация шаблона быть скрытой?

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

(«скрытой» в смысле private может быть, конечно. Но не extern)

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

В моём примере String тоже является параметром шаблона и может быть любым совместимым пользовательским типом. Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

trait ToString<S> {
    fn to_string(&self) -> S;
}
fn foo<S, T: ToString<S>>(arg: T) {
    let s = arg.to_string();
}
numas13
()
Ответ на: комментарий от Dicebot

Тут же вроде бы используется жёсткая привязка по типу результата. Меня интересует, можно ли изменить именно это (с системой traits в целом знаком, она ок)

Так?

trait ConvertTo<X: ?Sized> {
    fn to(self: &Self) -> X;
}

impl ConvertTo<String> for i32 {
    fn to(self: &i32) -> String { self.to_string() }
}

impl ConvertTo<f32> for i32 {
    fn to(self: &i32) -> f32 { 0f32 }
}

fn main() {
  let x: String = (123i32).to();
  println!("{}", x);
  let x: f32 = (123i32).to();
  println!("{}", x);
}
tailgunner ★★★★★
() автор топика
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от Dicebot

Обычная практика - иметь модуль вида CTFlags.d который генерируется системой сборки и содержит нужные данные.

То есть, в принципе, можно.

А могут спецификации версии быть вложенными? Как-то так:

version(DigitalMars)
{
    version(full)
    {
        // ...
    }
}

Никогда не видел в живом коде. Code review в стандартную библиотеку оно бы точно не прошло.

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

но они в D слишком мощные для этого, ничего лучше обычных исходников не придумали пока.

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

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

Нужен механизм работы с Result - монады, макросы, whatever.

Одно другому не мешает.

А я чем дальше, тем больше склоняюсь к тому, что они не нужны.

Почему?

Даже в хаскеле какая-никакая обработка исключений имеется. Использовать ведь никто не заставляет. В стандартную библиотеку их и правда лучше не тащить, а дальше уже можно были бы выбирать что больше подходит. Разве какие-то фичи от этого пострадают?

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

Нужен механизм работы с Result - монады, макросы, whatever.

Одно другому не мешает.

Исключения мешают простоте рантайма.

А я чем дальше, тем больше склоняюсь к тому, что они не нужны.

Почему?

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

Даже в хаскеле какая-никакая обработка исключений имеется

Разве? КМК, там именно возврат значений из функций. Впрочем, Хаскель в любом случае не указ - в нем ленивость, сборка мусора и вообще он академическая игрушка %)

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

А могут спецификации версии быть вложенными?

Да, внутри блока версии может быть любой корректный код.

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

Для этого fat pointer же нужен, считай тот же interface, только неявно. Так себе преимущество, играет роль только там, где важен ABI.

Я вообще склоняюсь к мнению, что нужно легализовать WPO как единственный полноценный вариант компиляции, с полным доступом ко всем исходникам. Это заманчиво большим количеством оптимизаций, а ABI важен только для публичных библиотек.

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

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

Я отчасти согласен. Исключения имеют смысл только для десктопных приложений и то зачастую в ущерб корректности. На серверах просто нет такой вещи как исключительная ситуация - либо это можно обработать и нужно это сделать быстро (иначе DoS), либо сервер горит и лучше вообще ничего не делать.

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

А что тут значит знак вопроса? И зачем нам этот трейт?

"?Sized" значит «реализация Sized не обязательна» (по умолчанию она почему-то требуется). Но для приведенного фрагмента это указание не нужно (осталось от попыток сделать преобразование к str).

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

Исключения мешают простоте рантайма.

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

исключительных ситуаций тупо не бывает - все ситуации равноправны.

Вот разбираем мы сложный формат, например. Хотя бы ODT. То есть надо распарсить несколько файлов и т.д. Логика по разбору сложная, при этом есть невосстановимые ошибки. Протаскивать через кучу слоёв возврат ошибки - делать код более громоздким. Тем более, что для половины функций он не имеет значения - будет просто ранний возврат. Осключения здорово избавляют от лишнего кода и повышают читаемость в таких случаях.

и вообще он академическая игрушка %)

Ну если на мейнстрим равняться, то там вообще сплошь исключения.

Даже в Го и то их можно перехватить, вроде, хотя везде постулируется, что они отказались от исключений.

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

монады

Только вот в расте их нет.

Я об этом несколько раз написал. Но можно и без монад - был proof-of-concept «монадического do».

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

а ABI важен только для публичных библиотек.

Не только. Не все хотят раскрывать исходники.

Да и С благодаря стандартному ABI является «клеем» во всех FFI.

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

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

Надо же, а мужики разработчики tomcat, mongodb, cassandra, jasperreports, mariadb и пр. то не в курсе.

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

Исключения мешают простоте рантайма.

Почему? Есть ведь реализации, которые не несут оверхед

Они не несут оверхеда по времени выполнения, но рантайм всё равно сложнее, если должен нести в себе поддержку исключений. Ну и когда они таки сроабатывают, это другие накладные расходы.

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

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

Ну если на мейнстрим равняться, то там вообще сплошь исключения.

Весь этот мэйнстрим растет из CLU, которому уже 40+ лет. Кроме того, есть как минимум один мэйнстримный язык без исключений... Си!

Даже в Го и то их можно перехватить, вроде

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

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

Но можно и без монад

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

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

Костылями много что можно. Но лучше не надо.

Костыли - наше всё. Опробованные, хорошо локализованные костыли - фундамент software engineering.

Будем надеяться, HKT появится в языке скорее рано, чем поздно.

Вполне очевидно, что в 1.0 их не будет, а когда они появятся... всё равно понадобится синтаксический сахар - такой же monadic do.

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

Ну и когда они таки сроабатывают, это другие накладные расходы.

И кого это волнует, если их использовать правильно (то есть именно как исключения)?

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

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

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

которому уже 40+ лет.
есть как минимум один мэйнстримный язык без исключений... Си!

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

Перехватить, обработать и продолжить работу невозможно.

Я тоже так думал. Однако, всё это возможно:

Recover is a built-in function that regains control of a panicking goroutine. Recover is only useful inside deferred functions. During normal execution, a call to recover will return nil and have no other effect. If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution.

А так как recover возвращает значение, то так даже можно пробрасывать информацию. Прямо как с обычными исключениями.

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

Ну и когда они таки сроабатывают, это другие накладные расходы.

И кого это волнует, если их использовать правильно (то есть именно как исключения)?

Тех, кого интересуют предсказуемые программы.

Вот мы делаем долгую работу, парсим всякие данные и в любой момент может случится невосстановимый облом. Зачем нам замусоривать интерфейс и реализацию пробросом «ошибки»?

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

Я считаю, что исключения - это просто ещё один полезный инструмент

Естественно. И если они есть в языке, следует хорошо подумать, прежде чем отказаться от их использования. Но в случае с Rust вопрос в том, а стоит ли _добавлять_ этот инструмент.

которому уже 40+ лет.
есть как минимум один мэйнстримный язык без исключений... Си!

Какие забавные взаимнопротиворечивые аргументы.

В чем противоречие? 40 лет назад в CLU начаты эксперименты, и мы можем сравнить опыт потомков CLU с опытом от еще более старого Си.

А так как recover возвращает значение, то так даже можно пробрасывать информацию. Прямо как с обычными исключениями.

Окей. Но там же:

«The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values».

Т.е. инструмент ограниченного внутреннего использования. Как longjmp в Си. А в интерфейсах - возврат пары значений.

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

Тех, кого интересуют предсказуемые программы.

Сам в своих аргументах не путаешься? Сначала апеллируешь к накладным расходам, потом к корректности.

Такие аргументы напоминают мне противников unsafe - «какой ужас, ансейфом можно всё испортить, а раз можно, то значит так и будет!».

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

Тем не менее, функции, которые могут позвать panic никак не отмечаются. Почему же ты не воюешь против такой неявности?

А «интерфейс» бывает разным. Одно дело, если это публичная либа со скудной документацией (а то и вообще без неё) и другое, когда интерфейс внутренний. Реально не понимаю как можно спорить с наличием ситуаций когда есть какая-то «длительная обработка» и нас вполне устроит результат «не удалось». Который очень удобно пробрасывать исключениями через несколько уровней.

Даже в С++ nothrow есть. Что помогает оптимизировать, кстати. В расте ничего подобного нет и не планируется?

Проброс ошибки, конечно, следует как-то подсахарить, но это не проблема.

Проблема. Сахар весь мусор не скроет. Ну или перестанет отличается по «неявности» от исключения.

В чем противоречие?

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

Т.е. инструмент ограниченного внутреннего использования. Как longjmp в Си. А в интерфейсах - возврат пары значений.

Ну и что мешает сделать так же в расте? Не использовать исключения в стандартных либах и прописать рекомендации?

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

Сам в своих аргументах не путаешься?

Нет.

Сначала апеллируешь к накладным расходам, потом к корректности.

Не вижу, где я апеллировал к корректности, но да, иногда накладные расходы влияют на корректность (реальное время). Ты же вроде из Sociomantic Labs?

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

Тем не менее, функции, которые могут позвать panic никак не отмечаются.

panic! - это аварийное завершение. Ошибка во входных данных не должна вызывать этого.

Почему же ты не воюешь против такой неявности?

А я и против исключений не воюю. Я просто считаю, что всё, что делается в Си++ (Java, Ada и вплоть до CLU) исключениями, можно сделать на ADT и макросах без потери читабельности кода.

Даже в С++ nothrow есть. Что помогает оптимизировать, кстати. В расте ничего подобного нет и не планируется?

Нет. В Rust нет исключений и оптимизации ничего не мешает.

Проброс ошибки, конечно, следует как-то подсахарить, но это не проблема.

Проблема. Сахар весь мусор не скроет.

Это не мусор, а равноправная часть программы. Скрывать его не нужно.

благодаря проблемам С раст и нужен.

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

Т.е. инструмент ограниченного внутреннего использования. Как longjmp в Си. А в интерфейсах - возврат пары значений.

Ну и что мешает сделать так же в расте?

В Rust ты можешь абузить для этого вышеупомянутый panic!.

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

Так чем он конкретно лучше чем ним?

Вот свежая и относительно адекватная (за исключением поверхностности, но на то она и «Quick») статейка по этому поводу:

http://arthurtw.github.io/2015/01/12/quick-comparison-nim-vs-rust.html

http://www.reddit.com/r/programming/comments/2scodb/a_quick_comparison_of_nim...

https://news.ycombinator.com/item?id=8883791

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

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

http://www.reddit.com/r/programming/comments/2s70mm/thoughts_about_rust_from_...

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

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

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

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

Какие кроссплатформенные тулкиты сейчас предпочтительнее для Rust?

https://crates.io, но пока слишком рано говорить о «предпочтительны» - версии в лучшем случае вида 0.x.x.

Нужен GUI и 3d.

AFAIK, из GUI есть только https://github.com/jeremyletang/rgtk (на crates.io отсутствует); 3d - биндинги к OpenGL и несколько самопальных тулкитов.

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

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

https://www.youtube.com/watch?v=n2UrjogA0j0 - https://github.com/PistonDevelopers/conrod/blob/master/examples/all_widgets.rs

Из оберток над OpenGL мне более-менее понравился gfx-rs - он хоть как-то пытается адаптировать OpenGL к особенностям ржавчины.

Томаков glium попроще, но это просто небольшая обертка над OpenGL, что бы не возиться самому руками с unsafe вызовами.

В прочем, для своих поделок я использую небольшие квадратноколесные велосипеды, потому что мне нужна нормальная работа под android и OpenGL ES, а вышеназванные проекты с этим имеют сложности. Обширный функционал мне пока все равно не нужен.

Для создания окна, контекста, ввода-вывода и т.п. есть обертки над glfw и sdl и есть glutin, который целиком на ржавчине и довольно сносно работает.

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

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

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

Это типа он зопейсал в блокнотик.

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

https://github.com/TeXitoi/rust-mdo

Проглядел как-то. Блин, а с виду почти что надо. Немного подпилить тут и там и, возможно, сможет помочь избавиться от нагромождения unwrap-try! в некоторых местах. Хотя бы, как временное решение, пока чего-то официального не выкатят.

Интересно, насколько оно сказывается на производительности и т.п. Как будет время, поробую поиграться с этим :) .

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

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

Есть любители - целые полчища...

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

Если тебе зачем-то нужен do-синтаксис, ты делаешь что-то не так

Для начала, мне нужен язык, умеющий делать эффективные компактные программы, желательно без рантайма. У тебя нет? Ты делаешь что-то не так.

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

Как легко понять, это относится к

fmdw> ты делаешь что-то не так

А про то, что do-синтаксис не нужен, расскажи в Haskell Cafe или где там собираются хаскеляторы.

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

не знает как рассахаривается do

А про то, что do-синтаксис не нужен, расскажи в Haskell Cafe или где там собираются хаскеляторы.

Со мной, думаю, многие согласятся. Без do можно писать короче и быстрее. Нашлось с ходу: https://www.haskell.org/haskellwiki/Do_notation_considered_harmful

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

не знает как рассахаривается do

Хотя мне это и не нужно, я знаю. Телепай лучше.

Без do можно писать короче и быстрее

Только никто не пишет.

Нашлось с ходу: https://www.haskell.org/haskellwiki/Do_notation_considered_harmful

Судя по истории страницы, написано это в 2007 году. И, похоже, с тех самых пор игнорируется.

Ну да ладно... какое именно утверждение о Rust ты пытаешься доказать?

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

Хотя мне это и не нужно, я знаю.

Прелестно, так что тебе мешает сделать аналог Maybe тогда?

Только никто не пишет.

Как я люблю такие обобщения. Достаточно одного, совершенно любого контрпримера, чтобы заклеймить собеседника мир-дверь-мячом. Контрпример: вот мой последний проект:

┌[pts/3: ~/Sync/proj/WFC]
└% wc -l Main.hs
115 Main.hs
┌[pts/3: ~/Sync/proj/WFC]
└% grep -cE '[= ]do[\n ]' Main.hs
0
fmdw
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.