#prog #cpp #rust #article
Why we didn't rewrite our feed handler in Rust
Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и написан на C++. Конкретно в тексте приведены три паттерна, которые валидны в C++ и не выразимы или выразимы неудобно на Rust.
Первое касается ограничений borrow checker-а. Вот какой пример приводят:
Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:
Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust.
Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:
Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:
Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.
Why we didn't rewrite our feed handler in Rust
Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и написан на C++. Конкретно в тексте приведены три паттерна, которые валидны в C++ и не выразимы или выразимы неудобно на Rust.
Первое касается ограничений borrow checker-а. Вот какой пример приводят:
fn process_source(sources: Vec<Source>) {
for source in sources {
let mut buffer: Vec<&[u8]> = Vec::new();
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
}
}Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:
error[E0597]: `data` does not live long enough
--> src/lib.rs:32:23
|
31 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
32 | buffer.extend(data.split(splitter));
| ------ ^^^^ borrowed value does not live long enough
| |
| borrow later used here
33 | process_data(&buffer);
34 | }
| - `data` dropped here while still borrowed
Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust.
Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:
struct RecV1 {
uint32_t x;
uint32_t y;
}
struct RecV2 {
uint32_t x;
uint32_t y;
uint32_t z;
}Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:
template <typename T>
T InitRec() {
T res;
res.x = 1;
res.y = 2;
if constexpr(std::is_same_v<T, RecV2>()) {
res.z = 3;
}
return res;
}
Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.
👍10🤡5🔥1
#prog #rust #abnormalprogramming
fibonacci-numbers crate with self-recursive dependencies
fibonacci-numbers crate with self-recursive dependencies
I have created a crate called fibonacci-numbers. There are 187 different major versions of the crate, each exporting the Fibonacci number corresponding to that version.
<...>
Version 186 depends on version 184 and 185 and exports the largest Fibonacci number that fits in a u128:
pub const VALUE: u128 = fib184::VALUE + fib185::VALUE;
😁28🔥7🤡3🤯1
#prog #article
That boolean should probably be something else
Да, про сумм-типы там тоже упоминается.
That boolean should probably be something else
By storing a boolean as our data, we're coupling that data tightly to our application logic.
Instead, we should remain critical and ask what data the boolean depends on, and should we maybe store that instead?
Да, про сумм-типы там тоже упоминается.
#prog #abnormalprogramming
spellscript
output: the power is amplified: 49
spellscript
esotoric [sic!] programming language that's read like a spellbook
begin the grimoire.
summon the power with essence of 7.
conjure ritual named amplify with value to return value multiplied by value.
enchant power with essence 0 of through ritual amplify with power.
inscribe whispers of "the power is amplified: " bound with power.
close the grimoire.
output: the power is amplified: 49
❤11🤯3🤡3😁1
#prog #rust
rustc_codegen_gcc: Progress Report #38
В rustc_codegen_gcc теперь работает LTO, в том числе и cross-language! 🎉
rustc_codegen_gcc: Progress Report #38
В rustc_codegen_gcc теперь работает LTO, в том числе и cross-language! 🎉
blog.antoyo.xyz
rustc_codegen_gcc: Progress Report #38
Antoyo's Personal Blog
😢16👍9🌚3
#prog #rust #article
A Little Rust Trait Limitation
I stumbled across a … bug(?) … a limitation(?) … an issue(!) with the Rust compiler. Fortunately, I was able to find out what was going on in the Rust programming language forum. I thought this issue was interesting enough and subtle enough to try to explain to my blog audience.
<...>
This isn’t an explanation of why this limitation is necessary or fundamental, because it isn’t – it’s a limitation that could, and maybe at some point will be, fixed.
A Little Rust Trait Limitation
I stumbled across a … bug(?) … a limitation(?) … an issue(!) with the Rust compiler. Fortunately, I was able to find out what was going on in the Rust programming language forum. I thought this issue was interesting enough and subtle enough to try to explain to my blog audience.
<...>
This isn’t an explanation of why this limitation is necessary or fundamental, because it isn’t – it’s a limitation that could, and maybe at some point will be, fixed.
😢14
#prog #article
Beating the L1 cache with value speculation
Редкий пример того, как использование кеша процессора вкупе с предсказателем переходов может замедлить программу.
Beating the L1 cache with value speculation
Редкий пример того, как использование кеша процессора вкупе с предсказателем переходов может замедлить программу.
mazzo.li
Beating the L1 cache with value speculation
😢16🔥5🤔2
#prog #c #rust #article
"Just Use Rust": A Best-Case Historical Study of Open Source Vulnerabilities in C (PDF)
"Just Use Rust": A Best-Case Historical Study of Open Source Vulnerabilities in C (PDF)
We identified 68 prominent open source projects with C code, collected their vulnerability history data, and used their CWE designations to explore a best-case speculation on how many vulnerabilities might have been prevented with Rust. We estimate that 58.2% of historical vulnerabilities in our selection of open source C projects would have been virtually impossible in Rust.
😢17😁13🤡7👍5🔥1🤔1
#prog #ml
Про проблемы с воспроизводимостью в ML с неожиданными источниками.
t.iss.one/partially_unsupervised/273
Про проблемы с воспроизводимостью в ML с неожиданными источниками.
t.iss.one/partially_unsupervised/273
Telegram
partially unsupervised
Когда-то я думал, что ML метрика - это довольно простая функция от двух параметров: обученной модели и тестового датасета. Но это абстракция, конечно, не выдерживает столкновения с реальным миром, а параметров значительно больше.
С локальными факторами справиться…
С локальными факторами справиться…
😢16🤔3👍2
#prog #article
Syntax highlighting is a waste of an information channel
Syntax highlighting is a waste of an information channel
Color carries a huge amount of information. Color draws our attention. Color distinguishes things. And we just use it to distinguish syntax.
Nothing wrong with distinguishing syntax. It's the "just" that bothers me.
<...>
I've listed some examples of what we could do with this. If this is something that already exists I included a link.
We can use different colors to mark how nested a set of parenthesis are.
<...>
Highlight different levels of nesting.
<...>
Highlight identifiers imported from a different file.
<...>
Highlight functions that raise errors not caught in their body.
<...>
Highlight functions that were directly called in the bodies of tests that failed in the last test run.
😢20👍10🤔2