Size: a a a

2020 March 23
Блог*
#prog #rust #amazingopensource

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

https://github.com/RReverser/cow-utils-rs
источник
Блог*
dereference_pointer_there
#prog #rust #amazingopensource

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

https://github.com/RReverser/cow-utils-rs
#prog #rust #article

Продолжая тему строк в Rust: развёрнутая статья, которая достаточно доходчиво объясняет, почему в Rust два типа строк. Да и написано так, что читать легко и приятно.

https://fasterthanli.me/blog/2020/working-with-strings-in-rust/
источник
Блог*
dereference_pointer_there
#prog #rust #article

Продолжая тему строк в Rust: развёрнутая статья, которая достаточно доходчиво объясняет, почему в Rust два типа строк. Да и написано так, что читать легко и приятно.

https://fasterthanli.me/blog/2020/working-with-strings-in-rust/
#prog #rust #amazingopensource

Ещё одна библиотека от небезызвестного Кладова (ссылка взята из статьи выше). Собственно, описание достаточно красноречиво:

A SmolStr is a string type that has the following properties:

* size_of::<SmolStr>() == size_of::<String>()
* Clone is O(1)
* Strings are stack-allocated if they are:
   * Up to 22 bytes long
   * Longer than 22 bytes, but substrings of WS (see src/lib.rs). Such strings consist solely of consecutive newlines, followed by consecutive spaces
* If a string does not satisfy the aforementioned conditions, it is heap-allocated

Unlike String, however, SmolStr is immutable. The primary use case for SmolStr is a good enough default storage for tokens of typical programming languages. Strings consisting of a series of newlines, followed by a series of whitespace are a typical pattern in computer programs because of indentation. Note that a specialized interner might be a better solution for some use cases.

https://github.com/rust-analyzer/smol_str
источник
2020 March 24
Блог*
#prog #rust #article

Асинхронность в Rust построена вокруг центральной абстракции: футура. Эта абстракция, являющая собой некоторое вычисление, которое когда-то в будущем может дать результат. В настоящий момент футура в Rust — это тип, реализующий трейт Future. Этот трейт определяет единственный метод poll. При вызове он либо возвращает готовое значение, либо сигнализирует, что значение ещё не получено. Таким образом, футуры в Rust пассивны: при создании они (обычно) не запускают никаких вычислений, для того, чтобы получить из них значение, требуется вызывать метод poll, пока он не вернёт значение. Выполнение этой задачи возложено на экзекутор: программный компонент, который продвигает прогресс футур и, возможно, переключается между ними.

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

Найу Мелан¹ такое положение дел не устроило (особенно в силу того, что она делал библиотеку для реализации structured concurrency в Rust), поэтому она создала библиотеку для того, чтобы писать асинхронный код, не завязанный на конкретный экзекутор с незамысловатым именем async_executors. В своём блоге она написала, каким образом этого удалось достичь и с каким препятствиями столкнулась.

blog.wnut.pw/2020/02/25/anouncing-async_executors-a-building-block-for-executor-agnostic-libraries/

¹ Я на самом деле не курсе гендера автора, я лишь спекулирую на имени, поэтому, Найа, если ты вдруг это читаешь и считаешь, что тебя мисгендернули, не надо жаловаться на меня в суд или в поддержку Telegram, пожалуйста
источник
2020 March 25
Блог*
dereference_pointer_there
Теперь проверим, как это всё работает:
use std::mem::size_of_val;
use std::iter;

// FromFn не реализует FusedIterator по понятным причинам
let it1 = iter::from_fn(|| None::<i32>).fuse();
let it2 = iter::from_fn(|| None::<i32>).fuse_slim();

// В этом случае SlimFuse не лучше (но и не хуже!), чем Fuse
assert_eq!(size_of_val(&it1), size_of_val(&it2));

// Итераторы возвращают одно и то же
assert!(it1.eq(it2));

// Теперь возьмём fused итератор. Все итераторы коллекций являются fused —
// в частности, std::slice::Iter.
let     it1 = [1, 2, 3].iter().fuse();
let mut it2 = [1, 2, 3].iter().fuse_slim();

// Наш адаптер эксплуатирует свойства итератора и оказывается менее жирным!
assert!(size_of_val(&it1) > size_of_val(&it2));

// Проверим, что наш итератор выдаёт то же самое, что и стандартный
assert!(it1.eq(it2.by_ref()));

// Проверим, что с наш адаптер действительно fused
assert!(it2.by_ref().eq(iter::empty::<&i32>()));
assert!(it2.by_ref().eq(iter::empty::<&i32>()));

Замечательно. Торжество zero-cost абстракций!

Весь код в этих постах я выложил гистом на GitHub
#prog #rust #моё

Так как я добропорядочный программист, я решил сделать так, чтобы от этого изменения выиграли все и открыл PR в стандартную библиотеку Rust
источник
2020 March 31
Блог*
dereference_pointer_there
#prog #rust #моё

Так как я добропорядочный программист, я решил сделать так, чтобы от этого изменения выиграли все и открыл PR в стандартную библиотеку Rust
#prog #rust #моё

Всё сложилось не очень хорошо.

Во-первых, в PR #70366 @cuviper также внёс изменения в iter::Fuse. Теперь вместо I и bool Fuse хранит Option<I>, который выставляется в None, когда нижележащий итератор возвращает None. Для fused итераторов этот Option никогда не выставляется в None, а в ветке, в которой разбираются варианты, для None используется intrinsics::unreachable. Ради изоляции unsafe код ещё и был вынесен в отдельный файл. Этот PR был в итоге смержен (несмотря на очевидное изменение поведения в плане дропа нижележащего итератора), поэтому мне свой PR было проще выкинуть, чем пытаться адаптировать, что я и сделал.

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

В-третьих, в своём новом PR я реализовал подход, предложенный @cuviper: итератор в Fuse теперь хранится в Result<I, StopStateOf<I>>, а смена состояния Fuse делегируется этому ассоциированному типу. Для обычных итераторов это (), и его метод выставляет Result в Err(()), а для fused итераторов это Infallible, и его метод ничего не делает. Таким образом, мы убиваем двух зайцев одним выстрелом: мы убираем ветвление по тегу без unsafe и не храним тег для fused итератора (не говоря уже о том, что мы убираем кучу специализированного кода). Но в бочке мёда нашлась ложка урана: схожий PR 33090, который добавлял специализации для iter::Zip и, в частности, менял поля в зависимости от итераторов был частично откатан в PR 36490 из-за слома обратной совместимости: после этого PR Zip, который раньше был ковариантным, становился инвариантным. Та же проблема не минула и мой PR: нижеприведённый код компилируется до моего PR и не компилируется после:

fn test_fuse_covariant<'a, I>(iter: Fuse<&'static I>) -> Fuse<&'a I> {
   iter
}


Выглядит логично: если у нас есть Fuse, в котором лежит долгоживущая ссылка, то мы должны быть в состоянии использовать его там, где ожидается Fuse с ссылкой, живущей меньше. После обновления же код ломается. В принципе, это логично: для компилятора в обобщённом контексте ассоциированный тип непрозрачен, и он не может заранее сказать, какая у него корректная вариантность, поэтому компилятор избирает консервативный подход и предполагает, что ассоциированный тип инвариантен. Что не является логичным, так это то, что добавления ограничения 'static, которое явно говорит о том, что ассоциированный тип не содержит нестатических ссылок, не помогает. Да, это действительно недочёт в компиляторе, но, как мне сказал в дискорде @eddyb, инвариантность важна для обеспечения корректности кода. Ну и, разумеется, способов указать вариантность ассоциированного типа нет  ¯\_(ツ)_/¯

В общем, в текущем виде мой PR, скорее всего, не смержат, и когда можно будет это исправить — непонятно. Печально.
источник
Блог*
Полезная вещь, на мой взгляд. И я припоминаю, что когда-то искал что-то подобное
источник
Блог*
Нашел абсолютный chad метод скинуть время начала чего-либо, с учетом часового пояса человека, который эту страницу откроет.
https://time.is/2100_26_Mar_2020_in_CET?New_post
источник
Блог*
источник
Блог*
#quotes
источник
Блог*
Переслано от весёлый кремовый 🍰 т...
Не буду я мерить простоту языка в том, как легко его понять питонисту. В нормальных людях могу, в питонистах не буду.
источник
Блог*
#amazingopensource #art

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

За наводку спасибо @sv9t_channel

https://msurguy.github.io/flow-lines/
Github
источник
Блог*
dereference_pointer_there
#amazingopensource #art

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

За наводку спасибо @sv9t_channel

https://msurguy.github.io/flow-lines/
Github
Понимаю, что без картинок никто смотреть не будет, так что вот вам пример (формулу не подскажу, потерял)
источник
Блог*
dereference_pointer_there
Понимаю, что без картинок никто смотреть не будет, так что вот вам пример (формулу не подскажу, потерял)
Ну и оригинальный svg, если кому надо
источник
Блог*
dereference_pointer_there
#amazingopensource #art

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

За наводку спасибо @sv9t_channel

https://msurguy.github.io/flow-lines/
Github
источник
Блог*
А ещё у меня сегодня день рождения. Ура, что ли
источник
2020 April 01
Блог*
#science

А вот это действительно полезно. Там полно статей на самые разные темы
источник
Блог*
Open Access to ACM Digital Library During Coronavirus Pandemic

For the next three months, there will be no fees assessed for accessing or downloading work published by ACM. We hope this will help researchers, practitioners and students maintain access to our publications as well as increasing visibility and awareness of ACM’s journals, proceedings and magazines. Please be sure to inform your colleagues that the ACM DL is now open, and will continue that way through June 30, 2020.

https://www.acm.org/articles/bulletins/2020/march/dl-access-during-covid-19
источник
Блог*
DISCLAIMER: Я НЕ БУДУ ДЕЛАТЬ РОЗЫГРЫШИ НА 1 АПРЕЛЯ
источник
Блог*
#prog #rust
Мой коллега рассказал про изящный способ контроля над фичами библиотек
источник