Блог*
#prog #rust #article Как сделать API, оперирующее глобальным состоянием, которое не даёт возможности использовать себя некорректно. Rust особенно хорош в части предотвращения неправильного использования на этапе компиляции: единственная проверка в рантайме…
#prog #rust #article #rustlib
От этого же человека: библиотека для трансформации неструктурированного текста в формате markdown. Очень элегантное, на мой взгляд, API для потокового изменения документа.
adventures.michaelfbryan.com/posts/markedit/
От этого же человека: библиотека для трансформации неструктурированного текста в формате markdown. Очень элегантное, на мой взгляд, API для потокового изменения документа.
adventures.michaelfbryan.com/posts/markedit/
Michaelfbryan
I Made A Thing: Markedit
A couple days ago I released markedit, a small crate for editing unstructured markdown documents. This is a useful enough library that I thought I’d explain the main ideas behind it and potential use cases.
This originally came about when I was at work, preparing…
This originally came about when I was at work, preparing…
#prog #rust #rustlib
Кому-то в расточате требовались параметризованные тесты. Так вот, такая библиотека есть.
crates.io/crates/test-case
Кому-то в расточате требовались параметризованные тесты. Так вот, такая библиотека есть.
crates.io/crates/test-case
#prog #rust #rustlib #amazingopensource
Библиотека, которая возвращает
https://github.com/RReverser/cow-utils-rs
Библиотека, которая возвращает
Cow
вместо String
для трансформированных строк, если это возможно. Всегда знал, что кто-то напишет нечто подобное, на мой взгляд, очень полезная вещь.https://github.com/RReverser/cow-utils-rs
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.
Блог*
#prog #rust #rustlib #amazingopensource Библиотека, которая возвращает Cow вместо String для трансформированных строк, если это возможно. Всегда знал, что кто-то напишет нечто подобное, на мой взгляд, очень полезная вещь. https://github.com/RReverser/cow…
#prog #rust #article
Продолжая тему строк в Rust: развёрнутая статья, которая достаточно доходчиво объясняет, почему в Rust два типа строк. Да и написано так, что читать легко и приятно.
https://fasterthanli.me/blog/2020/working-with-strings-in-rust/
Продолжая тему строк в Rust: развёрнутая статья, которая достаточно доходчиво объясняет, почему в Rust два типа строк. Да и написано так, что читать легко и приятно.
https://fasterthanli.me/blog/2020/working-with-strings-in-rust/
fasterthanli.me
amos loves to tinker
Блог*
#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:https://github.com/rust-analyzer/smol_str
* 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.
GitHub
GitHub - rust-analyzer/smol_str
Contribute to rust-analyzer/smol_str development by creating an account on GitHub.
#prog #rust #rustasync #rustlib #article
Асинхронность в Rust построена вокруг центральной абстракции: футура. Эта абстракция, являющая собой некоторое вычисление, которое когда-то в будущем может дать результат. В настоящий момент футура в Rust — это тип, реализующий трейт Future. Этот трейт определяет единственный метод poll. При вызове он либо возвращает готовое значение, либо сигнализирует, что значение ещё не получено. Таким образом, футуры в Rust пассивны: при создании они (обычно) не запускают никаких вычислений, для того, чтобы получить из них значение, требуется вызывать метод
В стандартной библиотеке 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, пожалуйста
Асинхронность в 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, пожалуйста
doc.rust-lang.org
Future in std::future - Rust
A future represents an asynchronous computation obtained by use of `async`.
Блог*
Теперь проверим, как это всё работает: 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(); // В этом случае…
#prog #rust #моё
Так как я добропорядочный программист, я решил сделать так, чтобы от этого изменения выиграли все и открыл PR в стандартную библиотеку Rust
Так как я добропорядочный программист, я решил сделать так, чтобы от этого изменения выиграли все и открыл PR в стандартную библиотеку Rust
GitHub
Make `iter::Fuse` truly zero cost by AnthonyMikh · Pull Request #70374 · rust-lang/rust
As documentation for std::iter::FusedIterator says:
Note: In general, you should not use FusedIterator in generic bounds if you need a fused iterator. Instead, you should just call Iterator::fuse ...
Note: In general, you should not use FusedIterator in generic bounds if you need a fused iterator. Instead, you should just call Iterator::fuse ...
Блог*
#prog #rust #моё Так как я добропорядочный программист, я решил сделать так, чтобы от этого изменения выиграли все и открыл PR в стандартную библиотеку Rust
#prog #rust #моё
Всё сложилось не очень хорошо.
Во-первых, в PR #70366 @cuviper также внёс изменения в iter::Fuse. Теперь вместо
Во-вторых, адаптировать подход со специализируемым обобщённым типом оказалось невозможно. Ну, то есть я так думал, но @cuviper подсказал, как это можно реализовать. В очередной раз убедился, что есть полно людей умнее меня.
В-третьих, в своём новом PR я реализовал подход, предложенный @cuviper: итератор в
Выглядит логично: если у нас есть
В общем, в текущем виде мой PR, скорее всего, не смержат, и когда можно будет это исправить — непонятно. Печально.
Всё сложилось не очень хорошо.
Во-первых, в 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, скорее всего, не смержат, и когда можно будет это исправить — непонятно. Печально.
GitHub
Implement Fuse with Option by cuviper · Pull Request #70366 · rust-lang/rust
The former done flag was roughly similar to an Option tag, but left
the possibity of misuse. By using a real Option, we can set None
when the iterator is exhausted, removing any way to call it agai...
the possibity of misuse. By using a real Option, we can set None
when the iterator is exhausted, removing any way to call it agai...
Forwarded from Shady Bytes
Нашел абсолютный chad метод скинуть время начала чего-либо, с учетом часового пояса человека, который эту страницу откроет.
https://time.is/2100_26_Mar_2020_in_CET?New_post
https://time.is/2100_26_Mar_2020_in_CET?New_post
Forwarded from саша кремов
Не буду я мерить простоту языка в том, как легко его понять питонисту. В нормальных людях могу, в питонистах не буду.
#amazingopensource #art
Генератор траекторий векторных полей. Генерируется в svg, так что качество не теряется. Разумеется, формулы можно задать свои.
За наводку спасибо @sv9t_channel
https://msurguy.github.io/flow-lines/
Github
Генератор траекторий векторных полей. Генерируется в svg, так что качество не теряется. Разумеется, формулы можно задать свои.
За наводку спасибо @sv9t_channel
https://msurguy.github.io/flow-lines/
Github
🎉1
Блог*
#amazingopensource #art Генератор траекторий векторных полей. Генерируется в svg, так что качество не теряется. Разумеется, формулы можно задать свои. За наводку спасибо @sv9t_channel https://msurguy.github.io/flow-lines/ Github
Понимаю, что без картинок никто смотреть не будет, так что вот вам пример (формулу не подскажу, потерял)
Блог*
Понимаю, что без картинок никто смотреть не будет, так что вот вам пример (формулу не подскажу, потерял)
streamlines1585658874559.svg
82.9 KB
Ну и оригинальный svg, если кому надо