Оказывается система типов в #rust полная по Тьюрингу
https://sdleffler.github.io/RustTypeSystemTuringComplete/
https://sdleffler.github.io/RustTypeSystemTuringComplete/
sdleffler.github.io
Rust's Type System is Turing-Complete
(N.B. The word “fuck” appears multiple times in this post. I recommend that
the reader temporarily not consider “fuck” as profanity, as it isn’t used that
way here.)
the reader temporarily not consider “fuck” as profanity, as it isn’t used that
way here.)
немного про строковые типы, почему их два, какие нюансы есть и какие гарантии предоставляет #rust
https://fasterthanli.me/articles/working-with-strings-in-rust
рассказано просто супер. с подробностями и сравнением с #c
https://fasterthanli.me/articles/working-with-strings-in-rust
рассказано просто супер. с подробностями и сравнением с #c
fasterthanli.me
Working with strings in Rust
There’s a question that always comes up when people pick up the Rust programming language: why are there two string types? Why is there String, and &str?
My Declarative Memory Management article an...
My Declarative Memory Management article an...
пакет для удобной работы с COW и строками в #rust
https://github.com/RReverser/cow-utils-rs
а вот пакет с более компактными COW
https://github.com/maciejhirsz/beef
https://github.com/RReverser/cow-utils-rs
а вот пакет с более компактными COW
https://github.com/maciejhirsz/beef
GitHub
GitHub - RReverser/cow-utils-rs: Copy-on-write string utilities for Rust
Copy-on-write string utilities for Rust. Contribute to RReverser/cow-utils-rs development by creating an account on GitHub.
причины почему именно #rust ?
так же минимальное сравнение #rust с #python, #golang
https://www.youtube.com/watch?v=DnT-LUQgc7s
так же минимальное сравнение #rust с #python, #golang
https://www.youtube.com/watch?v=DnT-LUQgc7s
YouTube
Considering Rust
The Rust programming language has become a serious contender in the space of "systems" programming languages, and has recently been adopted by many of the tech giants for "serious" projects. In response to this, more companies are now considering whether…
Суперкомпилятор
принимает исходный код алгоритма плюс некоторые данные о входных параметрах и возвращает новый исходный код, который исполняет свою задачу на этих данных быстрее или является лучше исходного алгоритма по каким-то другим показателям
https://ru.wikipedia.org/wiki/%D0%A1%D1%83%D0%BF%D0%B5%D1%80%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F
принимает исходный код алгоритма плюс некоторые данные о входных параметрах и возвращает новый исходный код, который исполняет свою задачу на этих данных быстрее или является лучше исходного алгоритма по каким-то другим показателям
https://ru.wikipedia.org/wiki/%D0%A1%D1%83%D0%BF%D0%B5%D1%80%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F
Forwarded from Блог*
#prog #rust #моё
В Rust в некоторых случаях можно использовать анонимный лайфтайм (
Времена жизни — пожалуй, именно та фича, которая больше всего делает Rust непохожим на мейнстримные языки программирования. В частности, их синтаксис (
Раскрытие сокращённой записи начинается с введения нового явного параметра для каждого аргумента, тип которого параметризован временем жизни (далее ВЖ), но для которого конкретное значение ВЖ не указано. Например, если у нас функция
Далее компилятор пытается приписать времена жизни возвращаемому типу. В обычном коде произвольные времена жизни не материализуются из ничего, они появляются из ссылок на имеющиеся значения. Логично предположить, что если у тебя есть функция с ВЖ, то ВЖ возвращаемого типа должно быть связано с аргументами. Если аргументов нет вовсе, то компилятор откажется компилировать функцию. Если аргумент есть только один и с одним обобщенным параметром ВЖ, то возвращаемый тип параметризуется этим ВЖ для всех возможных обобщённых параметров. Например, если есть функция
В Rust в некоторых случаях можно использовать анонимный лайфтайм (
'_). Практика показывает, что эта фича некоторым не до конца понятна, поэтому я решил написать об этом подробнее.Времена жизни — пожалуй, именно та фича, которая больше всего делает Rust непохожим на мейнстримные языки программирования. В частности, их синтаксис (
'identifier) — это то, что приходит первым на ум тому, кто уверяет, что у Rust нечитаемый синтаксис. Тем не менее, если взглянуть на код программы на Rust, то этих времён жизни можно увидеть очень мало. Казалось бы, как так может быть, если учесть, что каждая ссылка параметризована временем жизни, а ссылки в Rust используются достаточно активно? Дело в том, что бо́льшая часть вариантов использования времён жизни подпадает под один из достаточно простых паттернов, для которых компилятор в состоянии вывести отсутствующие времена жизни сам. Это называется lifetime elision, и правила, по которым оно происходит, перечислены в растономиконе. Раскрытие сокращённой записи начинается с введения нового явного параметра для каждого аргумента, тип которого параметризован временем жизни (далее ВЖ), но для которого конкретное значение ВЖ не указано. Например, если у нас функция
fn do_something(a: &mut u32, b: (&u32, &u32), c: Cow<str>) { ... }
, то после первого шага преобразования она выглядит так:fn do_something<'lt1, 'lt2, 'lt3, 'lt4>(a: &'lt1 mut u32, b: (&'lt2 u32, &'lt3 u32), c: Cow<'lt4, str>) { ... }
Обратите внимание, это работает не только с ссылками.Далее компилятор пытается приписать времена жизни возвращаемому типу. В обычном коде произвольные времена жизни не материализуются из ничего, они появляются из ссылок на имеющиеся значения. Логично предположить, что если у тебя есть функция с ВЖ, то ВЖ возвращаемого типа должно быть связано с аргументами. Если аргументов нет вовсе, то компилятор откажется компилировать функцию. Если аргумент есть только один и с одним обобщенным параметром ВЖ, то возвращаемый тип параметризуется этим ВЖ для всех возможных обобщённых параметров. Например, если есть функция
fn first_and_second(arg: &(u32, u32, u32))- > (&u32, &u32) {
(&arg.0, &arg.1)
}
, то её развёрнутый тип будетfn first_and_second<'a>(arg: &'a (u32, u32, u32))- > (&'a u32, &'a u32) {
(&arg.0, &arg.1)
}
Что же делать, если аргументов несколько? В случае, когда функция принимает &self или &mut self, ВЖ возвращаемого типа приравнивается ВЖ self. Из этого, кстати, следует несколько неожиданный результат, что нижеприведённый код не компилируется:struct Foo;Если расписать тип полностью, то станет понятно, почему:
impl Foo {
fn use_str(&self, s: &str) -> &str {
s
}
}
struct Foo;Действительно, lifetime elision приводит к тому, что возвращаемая строка имеет то же ВЖ, что и
impl Foo {
fn use_str<'foo, 's>(&'foo self, s: &'s str) -> &'foo str {
s
}
}
self, но в теле функции используется строка с другим ВЖ 's, которое никак не связано с 'foo. Для того, чтобы решить эту проблему, нужно явно ввести обобщённый параметр времени жизни и указать, что он один и тот же у аргумента и возвращаемого значения:struct Foo;Такой код уже компилируется.
impl Foo {
fn use_str<'s>(&self, s: &'s str) -> &'s str {
s
}
}
Telegram
folex in codingteam
Не выходит прототипировать на расте у меня
Forwarded from Блог*
Собственно, это все правила, которым подчиняется lifetime elision. Если описанные выше случаи не применимы, то компилятор скажет "я не могу, у меня лапки". Отчасти именно из-за этого начинающим настолько затруднительно усваивать концепцию времён жизни: в простых случаях их писать не надо, поэтому ситуации, в которых ВЖ действительно нужно писать, уже не очень тривиальны. Какое это имеет отношение к анонимным временам жизни? Само непосредственное:
Но погодите-ка, это ещё не всё! Анонимное ВЖ можно также использовать и в блоке
Недостатки у такого способа тоже есть. Каждое использование
Подведём итоги:
* Анонимные времена жизни можно использовать в возращаемых типах и в заголовках
* В возвращаемых типах анонимные ВЖ заполняются с использованием нехитрых правил lifetime elision
* В
- В силу их анонимности их нельзя использовать напрямую
'_ можно указать вместо обобщённого параметра ВЖ, чтобы компилятор его вывел. Скажем, сигнатуру first_and_second можно написать и так: fn first_and_second(arg: &(u32, u32, u32))- > (&'_ u32, &'_ u32). Кажется, что это ненужное добавление, но есть случаи, когда это необходимо (при условии, что программист всё ещё не хочет писать ВЖ явно). Рассмотрим вот такой код (несколько надуманный, но достаточно наглядный);fn non_zero(slice: &[u32]) -> Box<dyn Iterator<Item = &u32>> {
Box::new(slice.iter().filter(|&&n| n != 0))
}
Этот код не компилируется. Претензия компилятора сводится к несовпадению типов:= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = &u32> + 'static)>`Да, тут есть ссылка в возвращаемом типе, и ей приписывается то же ВЖ, что и у
found `std::boxed::Box<dyn std::iter::Iterator<Item = &u32>>`
slice, но мы не записали время жизни типа внутри коробки, то есть dyn Iterator. Компилятор предположил, что это владеющий тип и, следовательно, он имеет ВЖ 'static, которое является более долгоживущим, чем любое другое ВЖ. Но это не так: возвращаемый итератор содержит ссылку на слайс и потому не может пережить этот слайс. Один из способов исправить ошибку — это ввести новый параметр ВЖ и указать, что возвращаемый тип столько же и живёт, но... Мы ленивые программисты и не хотим писать много, поэтому мы напишем ровно столько, чтобы заставить компилятор работать за нас:fn non_zero(slice: &[u32]) -> Box<dyn Iterator<Item = &u32> + '_> { ... }
Да, разница действительно всего в 3 символа, не считая пробелов. С такой сигнатурой код уже компилируется, потому теперь благодаря lifetime elision возвращаемому типу приписывается корректное ВЖ.Но погодите-ка, это ещё не всё! Анонимное ВЖ можно также использовать и в блоке
impl. Об этом написано в edition guide здесь и здесь. Порой в impl-блоке типа, параметризованного ВЖ, ничто не зависит от указанного ВЖ, поэтому вместо того, чтобы вводить явно ВЖ после impl и использовать его для типа, можно просто указать '_. Например, если у нас есть определение struct StrWrap<'a>(&'a str);, то можно написать блок методов так:impl<'a> StrWrap<'a> { ...
, а можно — так:impl StrWrap<'_>Это работает и в том случае, если параметров ВЖ несколько: для
struct StrPair<'a, 'b: 'a>('a str, &'b str); можно написать так;impl StrPair<'_, '_> { ...
Если между ВЖ заданы отношения, то сгенерированные ВЖ будут также им удовлетворять. Недостатки у такого способа тоже есть. Каждое использование
'_ в заголовке impl-блока создаёт новое ВЖ, что не всегда желательно. Например, в коде нижеtrait WithLifetime<'a> {}
impl WithLifetime<'_> for &str {}
реализация трейта эквивалентнаimpl<'a, 'b> WithLifetime<'a> for &'b str {}
, а неimpl<'a> WithLifetime<'a> for &'a str {}
, как можно было подумать. Если требуется, чтобы двое ВЖ для методов было одинаковым, то их надо указывать (и вводить) явно — но только их, остальные можно заполнить анонимным ВЖ. Например, если у нас есть struct Triple<'a, 'b, 'c>(&'a u32, &'b u32, &'c u32);, то можно написать impl-блок так:impl<'a> Triple<'a, 'a, '_> {}
Также, очевидно, в силу анонимности этих параметров на них нельзя напрямую ссылаться (но можно через псевдоним типа Self).Подведём итоги:
* Анонимные времена жизни можно использовать в возращаемых типах и в заголовках
impl-блоков* В возвращаемых типах анонимные ВЖ заполняются с использованием нехитрых правил lifetime elision
* В
impl-блоках анонимные ВЖ генерируют новые ВЖ на каждое упоминание- В силу их анонимности их нельзя использовать напрямую
Forwarded from Блог*
А вот ещё пример из Go. Мутабельных строк там нет (есть лишь string.Builder). Строка в рантайме — это структура с двумя полями: адрес и длина, а слайс — структура с тремя полями: адрес, длина и ёмкость. Технически ничто не мешает преобразовать слайс байт в строку, просто отбросив поле
Cap (что, собственно говоря, и происходит в strings.Builder.String), но в общем случае это некорректная операция, потому что слайс мутабельный (всегда, иммутабельной версии слайса просто не существует), а строка — нет. Как результат, каст слайса байт в строку выделяет память в куче и копирует данные. Это лишняя работа, особенно если используемая строка почти сразу отбрасывается — например, если строка используется как ключ для map. В какой-то момент в компилятор Go запилили peephole-оптимизацию, которая распознавала паттерн someMap[string(bytesSlice)] и переписывала на реальный каст на фейковый, который просто копирует указатель и длину из слайса.pkg.go.dev
strings package - strings - Go Packages
Package strings implements simple functions to manipulate UTF-8 encoded strings.
нашел хорошую книжку по Категориям. https://henrychern.wordpress.com/2017/07/17/httpsbartoszmilewski-com20141028category-theory-for-programmers-the-preface/
Переводной календарь
Теория категорий для программистов (перевод глав книги Б. Милевски)
Предисловие редактора перевода Исходный авторский текст расположен по адресу: В основу перевода первых глав включены варианты, подготовленные М.Страховым (Monnoroch на Хабрахабр: предисловие и гл.1…
Почему бессерверная революция зашла в тупик
https://habr.com/ru/post/524126/
критика подхода
спойлер: можно юзать где надо
ну и оригинал
https://www.infoq.com/articles/serverless-stalled/
- Understanding Serverless: Tips and Resources for Building Servicefull Applications
https://www.infoq.com/articles/understanding-serverless-servicefull-applications/
https://habr.com/ru/post/524126/
критика подхода
спойлер: можно юзать где надо
ну и оригинал
https://www.infoq.com/articles/serverless-stalled/
- Understanding Serverless: Tips and Resources for Building Servicefull Applications
https://www.infoq.com/articles/understanding-serverless-servicefull-applications/
Хабр
Почему бессерверная революция зашла в тупик
Ключевые моменты Вот уже несколько лет нам обещают, что бессерверные вычисления (serverless) откроют новую эпоху без конкретной ОС для выполнения приложений. На...
модель атомик памяти в #CPP (полностью такая же для #rust)
- Неделимый, но расслабленный (relaxed)
- Полный порядок (seq_cst)
- Синхронизация пары (Acquire/Release)
https://habr.com/ru/post/517918/
- Неделимый, но расслабленный (relaxed)
- Полный порядок (seq_cst)
- Синхронизация пары (Acquire/Release)
https://habr.com/ru/post/517918/
Хабр
std::atomic. Модель памяти C++ в примерах
Для написания эффективных и корректных многопоточных приложений очень важно знать какие существуют механизмы синхронизации памяти между потоками исполнения, какие гарантии предоставляют элементы...
Крутющая статья о енамах в #rust есть и места сравнения с #C
= Peeking inside a Rust enum
https://fasterthanli.me/articles/peeking-inside-a-rust-enum
= Peeking inside a Rust enum
https://fasterthanli.me/articles/peeking-inside-a-rust-enum
fasterthanli.me
Peeking inside a Rust enum
During a recent Rust Q&A Session on my twitch channel, someone asked a question that seemed simple: why are small string types, like SmartString or SmolStr, the same size as String, but small vec t...
Никита Коваль — На пути к быстрой многопоточной хеш-таблице
https://www.youtube.com/watch?v=BpgL2LGEhP4
Хэштаблица самая популярная структура в разработке
#java
ConcurentHashMap
+ O(1)
- использует блокировки (сложно масштабируется)
- хранит списки при коллизии (лишние кэшмиссы)
+ вместо списков хранит дерево пр ипостоянных коллизиях
ConcurentSkipListMap
+ O(log N)
+ это дерево списков
- много лишних обьектов
- постоянные кэшмиссы
- нагружает GC
- не хэш таблица
NonBlocingHashMap
+ lock-free
И собственно в докладе примеры и понимание почему высокий профит от подхода
https://www.youtube.com/watch?v=BpgL2LGEhP4
Хэштаблица самая популярная структура в разработке
#java
ConcurentHashMap
+ O(1)
- использует блокировки (сложно масштабируется)
- хранит списки при коллизии (лишние кэшмиссы)
+ вместо списков хранит дерево пр ипостоянных коллизиях
ConcurentSkipListMap
+ O(log N)
+ это дерево списков
- много лишних обьектов
- постоянные кэшмиссы
- нагружает GC
- не хэш таблица
NonBlocingHashMap
+ lock-free
И собственно в докладе примеры и понимание почему высокий профит от подхода
YouTube
Никита Коваль — На пути к быстрой многопоточной хеш-таблице
Подробнее о Java-конференциях:
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
. . . . Хеш-таблицы — вероятно, самая используемая на сегодняшний день структура данных, от производительности которой зависят многие компоненты…
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
. . . . Хеш-таблицы — вероятно, самая используемая на сегодняшний день структура данных, от производительности которой зависят многие компоненты…
Introducing Domain-Oriented Microservice Architecture
https://eng.uber.com/microservice-architecture/
и перевод
https://habr.com/ru/company/flant/blog/514830/
https://eng.uber.com/microservice-architecture/
и перевод
https://habr.com/ru/company/flant/blog/514830/
https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%9A%D0%BE%D0%BD%D0%B2%D0%B5%D1%8F
«Организации проектируют системы, которые копируют структуру коммуникаций в этой организации»
ВАУ. прям немного шатает разум как трубу от этого)
«Организации проектируют системы, которые копируют структуру коммуникаций в этой организации»
ВАУ. прям немного шатает разум как трубу от этого)
https://www.the-paper-trail.org/post/2008-08-13-a-brief-tour-of-flp-impossibility/
Реальная система консенсуса не может быть одновременно
- асинхронна
- детерминирована
- отказоустойчива
Что бы она по-настоящему работала всегда надо хотябы в одном из пунктов иметь допущения. (Например рандомные таймеры)
Реальная система консенсуса не может быть одновременно
- асинхронна
- детерминирована
- отказоустойчива
Что бы она по-настоящему работала всегда надо хотябы в одном из пунктов иметь допущения. (Например рандомные таймеры)
www.the-paper-trail.org
A Brief Tour of FLP Impossibility | Paper Trail
Writing about distributed systems, compilers, virtual machines, databases and research papers from SOSP, ATC, NSDI, OSDI, EuroSys and others