LINUX.ORG.RU

into_rust() — скринкасты по Rust. Доступно видео с RustConf 2016.

 , , , ,


7

5

into_rust() — это плод годовой работы Николаса Мацакиса, одного из основных членов команды разработчиков Rust, и представляет из себя хранилище обучающих скринкастов по данному языку программирования. Обучение строится вокруг принципа работы с памятью в Rust: владение и заимствование.

На сайте (на момент написания новости) уже представлены следующие скринкасты:

На будущее запланированы следующие темы:

  • Structs and enums;
  • Threads;
  • Traits;
  • Named lifetime parameters;
  • Aliasing and mutability.

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

Также стали доступны видеозаписи с прошедшей 10 сентября первой конференции по Rust — RustConf 2016.

Для просмотра доступны:

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

★★★★★

Проверено: Shaman007 ()

Ответ на: комментарий от eao197

(во втором случае «исключения» заменяем на «панику»)

Ну нет. Паника — это abort(3). В расте нет исключений, вместо них развесистая система типов.

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

Паника — это abort(3)

Прекрасно. Расскажите, как в Rust-е бороться с тем, что abort может быть порожден любой функцией.

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

Так же как и в плюсах — тщательным ревью.

Паника может привести к неопределённому и/или memory-unsafe поведению только в unsafe-блоках. Их нужно ревьювить в том числе с вопросом, что будет, если вот здесь запаникуем. В остальных местах выброшенная паника ведёт себя предсказуемо, дропая объекты со стека. Отдельный вопрос с транзакциеподбными объектами, типа там мьютексов. Они, например, помечаются как poisoned и любая попытка с ними работать вызывает ещё одну панику. Для своих объектов можно применять такой же подход.

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

Так же как и в плюсах — тщательным ревью.

Т.е. никак.

В остальных местах выброшенная паника ведёт себя предсказуемо, дропая объекты со стека.

А вот intelfx говорит про abort, какой же здесь дроппинг объектов? Кто из вас путается в показаниях? ;)

PS. В плюсах с этим борются вовсе не «тщательным ревью».

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

А вот intelfx говорит про abort, какой же здесь дроппинг объектов? Кто из вас путается в показаниях? ;)
A panic in Rust is not always implemented via unwinding, but can be implemented by aborting the process as well.

Но по дефолту unwinding включён и деструкторы выполняются как ожидалось, если это не паника во время паники.

PS. В плюсах с этим борются вовсе не «тщательным ревью».

0_о, а как?

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

Да, паника в Rust может дропать объекты и раскручивать стек (а может так и не делать). Я имею в виду, что паника в Rust — это состояние класса «всё, приехали», а не «поймаем и продолжим».

Обработка ошибок в Rust делается другими методами, и эти «другие методы» находят своё отражение в сигнатуре функций.

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

и эти «другие методы» находят своё отражение в сигнатуре функций.

Т.е., например, невозможность аллокации памяти отражается в сигнатуре функций?

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

Идиоматичная функция на Rust, которая может где-то сфейлиться, будет возвращать тип-сумму из результата и возможных кодов ошибок. Если ты обработаешь не все — компилятор настучит по рукам. Хотя, конечно, ничто не мешает «обработать» ошибки с помощью panic, т. е. abort.

Как в std конкретно с памятью — я не знаю.

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

В std невозможность аллокации памяти это «всё, приехали». Соб-но, на это в прикладном софте расчитывать не стоит (из-за того же OOM killer-а ты никогда это и не застанешь), а для embedded стандартная либа не используется.

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

Хотя, конечно, ничто не мешает «обработать» ошибки с помощью panic, т. е. abort.

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

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

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

Rust и есть ML

Без GC нещитово.

GC был и когда-нибудь снова будет.

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

В std невозможность аллокации памяти это «всё, приехали». Соб-но, на это в прикладном софте расчитывать не стоит (из-за того же OOM killer-а ты никогда это и не застанешь)

Получается, что если из-за ошибки в коде программист вместо буфера на 4Mb запросил буфер на 400GiB, то приложение тупо грохнется? И объяснять мы это будем тем, что мол, OOM killer, в Linux-е это обычное дело и т.д.?

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

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

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

Во-первых, это внезапно давно классическое поведение: например в том же glib, не просто поток схлопывается, а вообще abort.

Во-вторых, если ты пишешь кроссплатформенны софт, то полагаться на отлов OOM не стоит.

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

Ещё раз: там, где это ожидаемая ошибка, там использовать std не будут, и это верно не только для раста.

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

Ну как библиотека наверняка будет, но чтобы в сам ЯП...

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

Ещё раз: там, где это ожидаемая ошибка, там использовать std не будут

Это почему? Исчерпание памяти - ожидаемая ошибка везде и всегда.

P.S. ядерный OOM killer отключается настройками оверкоммита. Там, где он недопустим.

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

Какой-то детский фанатизм и максимализм, ей богу.

Но вашу мысль я понял. С такими фанатами Rust-у и врагов не нужно.

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

Исчерпание памяти - ожидаемая ошибка везде и всегда.

Ну вот я в пример привёл glib, где это не так. То есть как минимум половина софта под линукс уже не «везде и всегда».

P.S. ядерный OOM killer отключается настройками оверкоммита. Там, где он недопустим.

То есть пользователю кроме установки программы нужно ещё настраивать систему?

P.S. в целом, никто не мешает в месте, где это ожидаемая ошибка, создать поток или catch_unwind и отловить панику, но, опять-таки, полагаться на то, что это будет работать всегда и везде нельзя. Ни в расте, ни в крестах, где угодно.

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

Почему бы теперь не сходить к разрабам glib и там про максимализм не поныть? Или к линусу и про OOM спросить?

А теперь встречный вопрос: как ты обрабатываешь (точнее думаешь что обрабатываешь) OOM? Скажем, вот где-то, в довольно глубокой вложенности функции, OOM при попытке выделить вектор на пару десятков элементов. Твои действия?

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

Почему бы теперь не сходить к разрабам glib и там про максимализм не поныть?

Потому, что люди, продолжающие в XXI веке пилить C, больны? ;)

Или к линусу и про OOM спросить?

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

Твои действия?

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

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

Потому, что люди, продолжающие в XXI веке пилить C, больны? ;)

В очередной раз сказать по делу нечего, так?

В линуксе, как уже было сказано, это дело настраивается.

То есть надо просить пользователей отключать OOM для твоей программы, верно?

Так что подтюнить конкретный дистр под конкретные задачи — это нормально.

Чтобы пользователь ставил целый дистр, а не просто программу?

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

А памяти хватит чтобы ответ сгенерировать-то?

Одно дело, когда программист ошибся и выделил не 4MiB, а 400GiB. Это ошибка программиста и оно должно отловиться тестами и на код ревью. Другое дело, если реально место кончилось. Тут уже кроме как упасть вариантов быть не может (практически любое следующее действие с памятью приведёт к повторному bad_alloc).

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

В очередной раз сказать по делу нечего, так?

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

То есть надо просить пользователей отключать OOM для твоей программы, верно?

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

Под определенные задачи Linux вручную настраивают и очень сильно настраивают.

А памяти хватит чтобы ответ сгенерировать-то?

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

Это ошибка программиста и оно должно отловиться тестами и на код ревью.

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

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

Исчерпание памяти - ожидаемая ошибка везде и всегда.

Ну вот я в пример привёл glib, где это не так

Если glib в самом деле ведет себя так - она говно. Но я всё же надеюсь, что ты ошибаешься (особенно с учетом того, что glib используется в systemd).

P.S. ядерный OOM killer отключается настройками оверкоммита. Там, где он недопустим.

То есть пользователю кроме установки программы нужно ещё настраивать систему?

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

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

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

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

Т.е., например, невозможность аллокации памяти отражается в сигнатуре функций?

Проблемами OOM в Расте, вроде, ещё никто вплотную не занимался. Там сейчас есть нестабильная возможность подвесить колбэк на это дело. Со временем должны стабилизировать, а потом, возможно, и в сигнатуре отразят.

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

Почему же при обсуждении Rust-а нужно кивать в сторону древних разработок на C?

Не сказал бы, что glib древний. Да и Rust скорее замена крестам, чем сям, ИМХО.

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

Я как минимум про embedded ещё говорил выше. Да, назначение везде разное. В десктопных программах (+ боты и сервисы) обрабатывать OOM нафиг не надо, а в embedded или ядрённом коде std никто использовать и так не будет.

Разумеется придумать кейс, где может понадобиться обработать OOM можно, тут я не спорю, и обработать его можно, если сильно хочется. Я лишь к тому, что не нужно считать это обыденной ситуацией и выставлять всё так, как будто обработкой bad_alloc каждый программист ежедневно занимается.

Если вы верите в возможность отлова всех ошибок на тестах и/или код-ревью

Где я это писал?

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

Да, есть std::alloc::oom, но обработка OOM-кейса всё равно сильно сложнее, чем в тех же крестах с отловом bad_alloc.

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

Да и Rust скорее замена крестам, чем сям, ИМХО.

ИМХО, это не очень правильно с маркетинговой точки зрения. Как замена чистому C Rust хорош практически всем (может быть за исключением синтаксиса, не у всех OCaml-овский стиль вызывает восторг).

В качестве замены C++ у Rust-а есть одно неоспоримое преимущество: Cargo. Да и то оно улетучивается, если конкретная команда нашла для себя способ удобного управления зависимостями.

Все остальные штуки, если сравнивать с современным C++, можно и нужно обсуждать. И не всегда в пользу Rust-а.

Я как минимум про embedded ещё говорил выше.

Речь про middleware, это сильно далеко от embedded.

Где я это писал?

Да вот же:

Это ошибка программиста и оно должно отловиться тестами и на код ревью.

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

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

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

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

В std невозможность аллокации памяти это «всё, приехали». Соб-но, на это в прикладном софте расчитывать не стоит (из-за того же OOM killer-а ты никогда это и не застанешь), а для embedded стандартная либа не используется.

Обычный десктопный линукс замечательно работает без memory overcommit/OOM killer. Его для этого даже пересобирать не нужно, достаточно установить vm.overcommit_memory=2.

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

системного подхода к написанию exception safe кода

То есть транзакции везде? Но ведь их тоже надо осознанно писать.

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

Но я всё же надеюсь, что ты ошибаешься

https://github.com/GNOME/glib/blob/f924d0b1f7d2b019f1abb56685dcfda74266c608/g...

Там есть ещё g_try_malloc, который не абортит, а возвращает NULL.

что glib используется в systemd

в systemd стандартный malloc.

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

Ну вот с OOM killer-ом же. Хорошо, если у тебя «готовый комплекс» (правда я думаю в таких комплексах компонент явно не один и проще обрабатывать OOM внешне для компонента, а не внутри, но it depends) и ты это контролируешь, но в подавляющем большинстве случаев это ведь не так.

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

Не уверен, что на 100% понимаю, что вы подразумеваете под транзакциями. Но, скорее всего, да.

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

Все остальные штуки, если сравнивать с современным C++, можно и нужно обсуждать. И не всегда в пользу Rust-а.

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

Речь про middleware, это сильно далеко от embedded.

Что включается в middleware? Системные сервисы?

Да вот же:

И где там

верите в возможность отлова всех

?

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

Да, есть std::alloc::oom, но обработка OOM-кейса всё равно сильно сложнее, чем в тех же крестах с отловом bad_alloc.

И что? В расте зачастую обработка ошибок несколько сложнее, чем в крестах, из-за отсутствия исключений.

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

е

Обратного никто и не утверждал. Только вот теперь пользователь должен менять дефолтное поведение. Я не знаю, можно ли его поменять только для одного процесса и из самого процесса.

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

То есть нужно практически весь код переписать так, чтобы прокидывать аналог bad_alloc в расте? Сильно сомневаюсь именно из-за того, что в подавляющем большинстве случаев обрабатывать OOM вообще не нужно.

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

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

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

А насколько лучше/хуже это другой вопрос.

Это ключевой вопрос. Особенно с учетом наличия инструментов высокого качества и значительного числа готовых наработок.

Что включается в middleware?

http-сервера, MQ-шные сервера, СУБД и т.д.

И где там

Да вот жеж: «Это ошибка программиста и оно должно отловиться тестами и на код ревью.»

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

То есть нужно практически весь код переписать так, чтобы прокидывать аналог bad_alloc в расте?

Зачем?

в подавляющем большинстве случаев обрабатывать OOM вообще не нужно.

Именно. Поэтому переписывать код и прокидывать bad_alloc будут только те, кому надо.

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

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

Согласен.

Это ключевой вопрос.

Да, но само наличие вопроса не должно ведь переводить разговор про «C++ vs Rust» в «C vs Rust», верно?

Особенно с учетом наличия инструментов высокого качества и значительного числа готовых наработок.

Особенно про качество.

Да вот жеж:

Ну правильно. Оно должно (should) отлавливаться, это задача тестов. Где там про веру в отлов всех ошибок?

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

glib используется в systemd

Нет.

// мимопроходил

Сборка ее требует, так что проходи дальше.

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

Поэтому переписывать код и прокидывать bad_alloc будут только те, кому надо.

Именно об этом я и говорю. Да и переписывать придётся скорее только в случае, если тот же alloc::oom не подойдёт.

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

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

Ну вот с OOM killer-ом же.

С OOM-киллером понятно - это не проблема. Еще что-то есть?

в подавляющем большинстве случаев это ведь не так.

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

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

Да, но само наличие вопроса не должно ведь переводить разговор про «C++ vs Rust» в «C vs Rust», верно?

Я же сказал: с маркетинговой точки зрения. С точки зрения маркетинга сейчас проще продать Rust тем, кто вынужден сидеть на чистом C. А уже затем, когда на Rust-е появится что-то посолиднее, чем недописанный Servo или очередной клон vim-а, можно будет начать продавать Rust и C++никам.

Особенно про качество.

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

Где там про веру в отлов всех ошибок?

Забейте, вы не поймете все равно.

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

когда на Rust-е появится что-то посолиднее, чем недописанный Servo или очередной клон vim-а, можно будет начать продавать Rust и C++никам.

Rust вполне успешно продается плюсовикам - не плюсовым конторам пока, но плюсовикам.

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

Много уже проектов на Rust-е запустил? Сколько собираешься запустить в ближайшее время?

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

Много уже проектов на Rust-е запустил? Сколько собираешься запустить в ближайшее время?

Я скорее контора, причем специфическая.

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

Сборка ее требует

Во-первых, нет. Во-вторых, «сборка требует» != «используется».

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