1.92K subscribers
3.72K photos
142 videos
15 files
3.93K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
#prog #rust #article

How to stop fighting with coherence and start writing context-generic trait impls

Транскрипт выступления, если что. Мне помогло понять, что же всё-таки такое context-generic programming, как это называет автор
🔥4
#prog #rust #article

symbolic derivatives and the rust rewrite of RE#

Растовая версия очень быстрого движка для регулярных выражений, который поддерживает, помимо прочего, конъюкцию (пересечение результатов подвыражений), отрицание и lookahead и при этом работает за линейное от входных данных время. По производительности на выражениях с большим количеством состояний обгоняет regex, особенно для поиска без учёта регистра.

Теория, поддерживающая этот движок — это развитие идей Brzozowski, но вместо того, чтобы считать производную от регулярного выражения для разных символов и потом объединять их по классам эквивалентности, новый подход считает т. н. символическую производную — производную для всех возможных входных символов сразу.

Из-за того, что данный подход поддерживает конъюкцию, движок может работать на байтах и при этом поддерживать UTF-8 просто за счёт добавления правила, которое ограничивает вход до валидных UTF-8 последовательностей:

// \p{utf8} expands to:
// ([\x00-\x7F]
// | [\xC0-\xDF][\x80-\xBF]
// | [\xE0-\xEF][\x80-\xBF]{2}
// | [\xF0-\xF7][\x80-\xBF]{3})*


Пример кода:

use resharp::Regex;

// basic matching
let re = Regex::new(r"hello.*world").unwrap();
assert!(re.is_match("hello beautiful world"));

// intersection: contains both "cat" and "dog", 5-15 chars
let re = Regex::new(r"_*cat_*&_*dog_*&_{5,15}").unwrap();

// complement: does not contain "1"
let re = Regex::new(r"~(_*1_*)").unwrap();
👍15🔥82
#prog #rust #rustlib #article

🦀Building Rust Procedural Macros Without quote!: Introducing zyn

I've been writing proc macros for a while now. Derive macros for internal tools, attribute macros for instrumentation. And every time, the same two problems: quote! doesn't compose (you end up passing TokenStream fragments through five layers of helper functions and writing hundreds of let statements), and debugging generated code means cargo expand and then squinting at unformatted token output hoping something jumps out.

Because of this I ended up writing the same helper methods, composite AST parsing and tokenizing types, extractors etc. I would have to copy these from project to project as needed, and eventually just decided to publish a crate so I never have to do it again.

So I built zyn — a proc macro framework with a template language, composable components, and compile-time diagnostics.


I wrote the debug system after spending two days on a bug where a generated impl block was missing a lifetime bound. cargo expand spat out 400 lines of tokens and I couldn't find it, so I built a debug system.
🤔51👍1🤡1
#prog #rust #rustlib

bnum — библиотека для работы с обобщёнными числами, для которых на уровне типов зафиксированы: знаковость, число байт под хранение, битовая ширина и поведение при переполнении.

use bnum::prelude::*;
// imports common use items
// including the `Integer` type and the `n!` macro

// say we want to write a polynomial function
// which takes any unsigned or signed integer
// of any bit width and with any overflow behaviour
// for example, the polynomial could be p(x) = 2x^3 + 3x^2 + 5x + 7

fn p<const S: bool, const N: usize, const B: usize, const OM: u8>(x: Integer<S, N, B, OM>) -> Integer<S, N, B, OM> {
n!(2)*x.pow(3) + n!(3)*x.pow(2) + n!(5)*x + n!(7)
// type inference means we don't need to specify the width of the integers in the n! macro
}

// 2*10^3 + 3*10^2 + 5*10 + 7 = 2357
assert_eq!(p(n!(10U256)), n!(2357));
// evaluates p(10) as a 256-bit unsigned integer

type U24w = t!(U24w);
// 24-bit unsigned integer with wrapping arithmetic
type I1044s = t!(I1044s);
// 1044-bit signed integer with saturating arithmetic
type U753p = t!(U753p);
// 753-bit unsigned integer that panics on arithmetic overflow

let a = p(U24w::MAX); // result wraps around and doesn't panic
let b = p(I1044s::MAX); // result is too large to be represented by the type, so saturates to I044s::MAX
// let c = p(U753p::MAX); // this would result in panic due to overflow
🫡10🤔21
🤯82😁2👎1
Блог*
#prog #rust #php #abnormalprogramming Experimentally compiling PHP code to Rust
#prog #rust #php #abnormalprogramming

rustc-php: A Rust compiler written in PHP

A Rust compiler written in PHP that emits x86-64 Linux ELF binaries directly (no LLVM, no assembler, no linker). Implements ownership checking, borrow checking, type checking, move semantics, generics, traits, closures, and iterators. Useful if you need to compile Rust on a shared hosting server from 2008 where the only installed runtime is PHP.
🤯15😁11😱1
#rust

docs.rs: building fewer targets by default

TL;DR: начиная с первого мая, если у пакета не указаны платформы, под которые он собирается, docs.rs будет собирать документацию только под x86_64-unknown-linux-gnu. Изменение касается только новых пакетов и пересборки старых.

Сейчас, если что, без метаданных документация собирается под пять платформ по умолчанию.
🔥14