Итак, сегодня 5 декабря. Чем примечателен этот день? Это — день, когда Блог* появился на свет.
Тогда мои амбиции были невелики: я считал, что этот блог будут читать только моя семья и ближайшие знакомые — полтора-два десятка человек максимум. Собственно, само название, как и логотип, я считал временным — даже думал в какой-то момент его поменять. Оглядываясь назад, легко обвинить меня в недальновидности — но с другой стороны, кто тогда мог подумать, что канал с мемасиками и заметками по расту станет... Не популярным, но всё же достаточно известным?
Тем не менее, наиболее характерные черты канала, кажется, оформились уже тогда — пачки репостов и чужого контента (но обязательно только то, что я прочитал сам), малость разбавленные собственными постами про не совсем тривиальные вещи на Rust (собственно, свой самый первый пост я и сейчас считаю довольно хардкорным — большая часть остальных постов у меня вроде попроще). С течением времени канал обрёл лицо, но не изменил заложенным в самом начало принципам. Единственное, что существенно изменилось с тех пор — это то, что с весны я начал лично приветствовать всех новых подписчиков.
Разумеется, я повлиял на канал просто в силу того, что я являюсь его единственным автором, но вот повлиял ли он на меня? На самом деле — да. По себе я знаю, что я человек, который относительно быстро увлекается чем-то новым, но так же быстро к этому охладевает, и потому я опасался, что быстро забью на блог и тот просто умрёт. Именно поэтому я дал себе обещание выкладывать на канале хоть что-то каждый день. Те, кто подписан на Блог* достаточно давно, знают, что в полной мере я сдержать это обещание не смог (некоторые дни я всё же пропускал), но всё же мой план сработал — то, что вы сейчас читаете этот пост, является живым тому подтверждением. Я целый год ежедневно занимался чем-то исключительно по собственной прихоти. Это может показаться незначительным, но для меня — человека со слабой волей — это стало достижением.
Ещё более удивительным для меня стал тот факт, что за этот год я написал в общей сложности — так, дайте-ка посчитаю — 23 оригинальных авторских поста, причём без какого-то специального намерения. Я даже сделал на Хабре перевод весьма крутой и крупной статьи, сделав себя несколько заметным и за пределами Telegram. Если бы мне в начале предыдущего года сказали бы, что я столько напишу — я бы не поверил. Блог* не только замотивировал меня заниматься им ежедневно, но и раскрыл писательскую жилку. Одним словом, он повлиял на меня куда сильнее, чем я ожидал, когда выложил тот мем с жирафом.
Но, впрочем, достаточно разговоров обо мне. Своим нынешним состоянием Блог* обязан и другим людям.
Один из них — это Олег Ковалёв (@olegkovalov), ведущий @oleg_log. Именно он, обладающий поистине гигантским терпением, терпеливо выслушивал мои замечания в духе "А вот на расте!..", проявил искренний интерес к моему блогу, сделал первый, кажется, публичный репост и, подкинув мне идею для поста, помог мне набрать первую сотню подписчиков. Олег, если ты это читаешь — спасибо тебе большое.
Другой человек — это... Тоже Олег, но другой, который ведёт небезызвестный Профунктор (я ещё застал время, когда у него была ссылка @libmustdie). Он организовал подборку, в которую попал в том числе и канал вашего (не)покорного слуги, и разом нагнал мне больше сотни подписчиков. И тебе, Олег, спасибо (а также Моноид-тян).
Также я благодарен множеству других людей — владельцам каналов, которые репостили отдельные посты и тепло отзывались о канале (Рома, я типа до сих пор помню твой комплимент). Это очень греет душу и помогает осознавать, что я стараюсь над этим каналом не ради себя одного.
Но главные, кому я хочу сказать спасибо — это моим подписчикам (слишком многочисленным, чтобы перечислить их тут поимённо). Тот факт, что вы читаете мой канал — и даёте мне ценный фидбек — помог мне перестать относиться к каналу как к какой-то блажи и начать относиться к нему как чему-то, что имеет ценность для многих людей — куда большего числа, чем с которым я бы мог познакомиться лично.
Тогда мои амбиции были невелики: я считал, что этот блог будут читать только моя семья и ближайшие знакомые — полтора-два десятка человек максимум. Собственно, само название, как и логотип, я считал временным — даже думал в какой-то момент его поменять. Оглядываясь назад, легко обвинить меня в недальновидности — но с другой стороны, кто тогда мог подумать, что канал с мемасиками и заметками по расту станет... Не популярным, но всё же достаточно известным?
Тем не менее, наиболее характерные черты канала, кажется, оформились уже тогда — пачки репостов и чужого контента (но обязательно только то, что я прочитал сам), малость разбавленные собственными постами про не совсем тривиальные вещи на Rust (собственно, свой самый первый пост я и сейчас считаю довольно хардкорным — большая часть остальных постов у меня вроде попроще). С течением времени канал обрёл лицо, но не изменил заложенным в самом начало принципам. Единственное, что существенно изменилось с тех пор — это то, что с весны я начал лично приветствовать всех новых подписчиков.
Разумеется, я повлиял на канал просто в силу того, что я являюсь его единственным автором, но вот повлиял ли он на меня? На самом деле — да. По себе я знаю, что я человек, который относительно быстро увлекается чем-то новым, но так же быстро к этому охладевает, и потому я опасался, что быстро забью на блог и тот просто умрёт. Именно поэтому я дал себе обещание выкладывать на канале хоть что-то каждый день. Те, кто подписан на Блог* достаточно давно, знают, что в полной мере я сдержать это обещание не смог (некоторые дни я всё же пропускал), но всё же мой план сработал — то, что вы сейчас читаете этот пост, является живым тому подтверждением. Я целый год ежедневно занимался чем-то исключительно по собственной прихоти. Это может показаться незначительным, но для меня — человека со слабой волей — это стало достижением.
Ещё более удивительным для меня стал тот факт, что за этот год я написал в общей сложности — так, дайте-ка посчитаю — 23 оригинальных авторских поста, причём без какого-то специального намерения. Я даже сделал на Хабре перевод весьма крутой и крупной статьи, сделав себя несколько заметным и за пределами Telegram. Если бы мне в начале предыдущего года сказали бы, что я столько напишу — я бы не поверил. Блог* не только замотивировал меня заниматься им ежедневно, но и раскрыл писательскую жилку. Одним словом, он повлиял на меня куда сильнее, чем я ожидал, когда выложил тот мем с жирафом.
Но, впрочем, достаточно разговоров обо мне. Своим нынешним состоянием Блог* обязан и другим людям.
Один из них — это Олег Ковалёв (@olegkovalov), ведущий @oleg_log. Именно он, обладающий поистине гигантским терпением, терпеливо выслушивал мои замечания в духе "А вот на расте!..", проявил искренний интерес к моему блогу, сделал первый, кажется, публичный репост и, подкинув мне идею для поста, помог мне набрать первую сотню подписчиков. Олег, если ты это читаешь — спасибо тебе большое.
Другой человек — это... Тоже Олег, но другой, который ведёт небезызвестный Профунктор (я ещё застал время, когда у него была ссылка @libmustdie). Он организовал подборку, в которую попал в том числе и канал вашего (не)покорного слуги, и разом нагнал мне больше сотни подписчиков. И тебе, Олег, спасибо (а также Моноид-тян).
Также я благодарен множеству других людей — владельцам каналов, которые репостили отдельные посты и тепло отзывались о канале (Рома, я типа до сих пор помню твой комплимент). Это очень греет душу и помогает осознавать, что я стараюсь над этим каналом не ради себя одного.
Но главные, кому я хочу сказать спасибо — это моим подписчикам (слишком многочисленным, чтобы перечислить их тут поимённо). Тот факт, что вы читаете мой канал — и даёте мне ценный фидбек — помог мне перестать относиться к каналу как к какой-то блажи и начать относиться к нему как чему-то, что имеет ценность для многих людей — куда большего числа, чем с которым я бы мог познакомиться лично.
Telegram
Блог*
Количество подписчиков моего блога медленно, но неуклонно растёт. Я начал подумывать о том, чтобы дать своему каналу какое-то более выделяющееся имя, ибо из опыта общения с людьми, знающих о канале, я понял, что астериск в названии канала ("Блог*") многие…
Этот день рождения Блог*а — первый, но, надо думать, отнюдь не последний. Пусть в следующий раз я смогу похвастать уже тысячами подписчиков (впрочем, я не гонюсь в первую очередь за количеством — пусть их будет поменьше, но они будут действительно читать мой блог!), пусть в следующем году оригинального контента станет больше и пусть Блог* станет уважаемым СМИ, на которое будут ссылаться международные издания. Спасибо, что довели меня до этого.
Отпразднуем снова через год! Ура!
Отпразднуем снова через год! Ура!
Ну и в годовщину имеет смысл устроить небольшое голосование. Я отобрал пачку наиболее достойных, на мой взгляд, авторских постов, а теперь предлагаю судить вам о том, какой из них лучший. Вот они (ибо ссылки в опросах не работают):
1. Реализация трейта, гарантирующего нулевой размер
2. Написание zero-cost (ну, почти) форматировщиков даты.
3. Эпические "Хроники замыканий" в трёх частях: раз, два, три.
4. Рассказ о lifetime elision и анонимном лайфтайме (
5. Как написать код, за который вас возненавидят коллеги (или о том, как можно абьюзить Deref).
6. Конструирование макроса, переводящего численные константы в строки на этапе компиляции.
7. Тонкий и глубокий анализ недостатков регулярных выражений (aka "Да не бомбит у меня!").
⬇️⬇️⬇️⬇️
1. Реализация трейта, гарантирующего нулевой размер
Self
.2. Написание zero-cost (ну, почти) форматировщиков даты.
3. Эпические "Хроники замыканий" в трёх частях: раз, два, три.
4. Рассказ о lifetime elision и анонимном лайфтайме (
'_
).5. Как написать код, за который вас возненавидят коллеги (или о том, как можно абьюзить Deref).
6. Конструирование макроса, переводящего численные константы в строки на этапе компиляции.
7. Тонкий и глубокий анализ недостатков регулярных выражений (aka "Да не бомбит у меня!").
⬇️⬇️⬇️⬇️
Telegram
Блог*
#prog #rust
Допустим, ты пишешь на Rust библиотеку и определяешь трейт, для вызова метода которого по каким-то причинам требуется, чтобы Self был ZST. Для удобства дальнейшего изложения сделаем подобное определение:
pub mod foo {
pub trait Foo {
…
Допустим, ты пишешь на Rust библиотеку и определяешь трейт, для вызова метода которого по каким-то причинам требуется, чтобы Self был ZST. Для удобства дальнейшего изложения сделаем подобное определение:
pub mod foo {
pub trait Foo {
…
#prog #rust #моё
Вы что, правда думали, что за всеми празднествами я оставлю вас без поста? Не скрою, идея заманчивая, но я решил ей не поддаваться... Хотя к тому моменту, как я закончу писать этот пост, уже наверняка наступит 6 декабря... Впрочем, достаточно прелюдий — переходим к постановке задачи!
Иногда нам требуется сопоставить значение с одной из строк... Но при этом игнорируя регистр символов. В общем случае это довольно сложная задача, и даже не из-за зависимости от локали, а просто от сложности правил перевода символов из одного регистра в другой. Пока что забьём на это и будем рассматривать только ASCII-строки. Что нам требуется? Чтобы:
а) чтобы можно было сопоставить (ASCII) строку, невзирая на её регистр;
б) чтобы нас предупреждал компилятор о перекрывающихся паттернах (а вот это уже интересно — компилятор требует точного совпадения паттернов для проверки);
в) чтобы по возможности сохранить возможности, предоставляемые
Итак, как нам проверить, что строки неодинаковы с точностью до регистра? В принципе, можно сделать уже известным способом const assert, используя соответствующие const fn, но так как я человек ленивый, я пойду по лёгкому пути: я проверю, что все паттерны на самом деле в нижнем регистре, а проверить их уникальность оставлю компилятору.
Итак, переходим к подзадаче: убедиться, что строка состоит из символов ASCII, но в нижнем регистре, на этапе компиляции. Правда, так как мы хотим использовать в паттернах не только буквы, но и, скажем, цифры, правильнее сказать "из символов ASCII не в верхнем регистре". Для решения части "на этапе компиляции" воспользуемся уже знакомым трюком, который я тут вроде уже показывал: заведём новую константу типа
Вы что, правда думали, что за всеми празднествами я оставлю вас без поста? Не скрою, идея заманчивая, но я решил ей не поддаваться... Хотя к тому моменту, как я закончу писать этот пост, уже наверняка наступит 6 декабря... Впрочем, достаточно прелюдий — переходим к постановке задачи!
Иногда нам требуется сопоставить значение с одной из строк... Но при этом игнорируя регистр символов. В общем случае это довольно сложная задача, и даже не из-за зависимости от локали, а просто от сложности правил перевода символов из одного регистра в другой. Пока что забьём на это и будем рассматривать только ASCII-строки. Что нам требуется? Чтобы:
а) чтобы можно было сопоставить (ASCII) строку, невзирая на её регистр;
б) чтобы нас предупреждал компилятор о перекрывающихся паттернах (а вот это уже интересно — компилятор требует точного совпадения паттернов для проверки);
в) чтобы по возможности сохранить возможности, предоставляемые
match
.Итак, как нам проверить, что строки неодинаковы с точностью до регистра? В принципе, можно сделать уже известным способом const assert, используя соответствующие const fn, но так как я человек ленивый, я пойду по лёгкому пути: я проверю, что все паттерны на самом деле в нижнем регистре, а проверить их уникальность оставлю компилятору.
Итак, переходим к подзадаче: убедиться, что строка состоит из символов ASCII, но в нижнем регистре, на этапе компиляции. Правда, так как мы хотим использовать в паттернах не только буквы, но и, скажем, цифры, правильнее сказать "из символов ASCII не в верхнем регистре". Для решения части "на этапе компиляции" воспользуемся уже знакомым трюком, который я тут вроде уже показывал: заведём новую константу типа
[(); 1]
, а в качестве значения ей присвоим [(); condtion as _]
, где condition
— условие, которое нам нужно проверить. Если condition
вычисляется в true
(и вычисляется на этапе компиляции в принципе), то as _
приводит булево значение к 1usize
, получая выражение [(); 1]
, соответствующее типу. В противном случае false
приводится к 0
и выражение принимает вид [(); 0]
, вызывая ошибку компиляции из-за несовпадения типов. Теперь всё, что нам остаётся для решения это подзадачи — написать функцию, которую можно вызвать на этапе компиляции и которая проверяет указанное выше условие. Написать такую функцию несколько неудобно из-за ограничений const fn (в частности, мы не можем использовать итераторы), но вполне возможно:const fn is_ascii_lowercase(s: &str) -> bool {
let s = s.as_bytes();
let len = s.len();
let mut i = 0;
while i < len {
if !s[i].is_ascii() || s[i].is_ascii_uppercase() {
return false;
}
i += 1;
}
true
}
Ладно, а как нам проверить, что несколько строк записаны в ASCII lowercase? Ну как-как, принимаем список и проходимся о нему:const fn are_all_ascii_lowercase(ss: &[&str]) -> bool {
let len = ss.len();
let mut i = 0;
while i < len {
if !is_ascii_lowercase(&ss[i]) {
return false;
}
i += 1;
}
true
}
Окей, с этой подзадачей мы разобрались. Как нам теперь убедиться, что все строки разные? А эту задачу мы уже решали: генерируем функцию, которая разбирает строку, и подсовываем в match
наши строки — и компилятор всё прекрасно проверяет за нас!Telegram
Блог*
#prog #rust #моё
Как сравнить в Rust две строки, игнорируя регистр символов? Строго говоря, используя лишь стандартную библиотеку — никак, поскольку перевод из одного регистра в другой зависит от локали, но давайте пока проигнорируем эту деталь и притворимся…
Как сравнить в Rust две строки, игнорируя регистр символов? Строго говоря, используя лишь стандартную библиотеку — никак, поскольку перевод из одного регистра в другой зависит от локали, но давайте пока проигнорируем эту деталь и притворимся…
Отлично, теперь переходим к самому вкусному: написанию макроса! Нам нужно разобрать
Что ж, давайте опробуем макрос в действии:
match
, так что начнём с этого:macro_rules! ascii_case_insensitive {
(match $value:ident {
$(... ,)*
_ => $catch_all:expr $(,)?
}) => { ... }
}
А теперь на минуту остановимся и подумаем, что из себя представляет паттерн, который мы пытаемся разобрать. В прошлый раз я совершенно упустил из виду, что обычно мы можем перечислить несколько паттернов, разделив их |
, равно как и то, что паттерн может также предваряться |
. Таким образом, корректный кусок макроса для распознавания паттернов должен выглядеть так:$(|)? $($pattern:literal)|+
$(|)?
отвечает за опциональную черту в начале. $pattern:literal
говорит, что $pattern
— это литерал, а $(...)|+
говорит о том, что то, что внутри скобок, повторяется один или более раз, и что повторы разделены |
. Но постойте-ка, есть же ещё и опциональное охранное выражение! С учётом всего этого паттерн для одной ветви принимает такой вид:$(|)? $($pattern:literal)|+ $(if $condition:expr)? => $arm:expr,Отлично, с разбором мы справились (правда, всё так же упустив возможность привязать имена к паттернам). Что мы со всем этим делаем? Мы проверяем, что все строки в нижнем регистре:
#[deny(const_err)]И что они все разные:
const _ARE_ALL_ASCII_LOWERCASE: [(); 1] = [(); are_all_ascii_lowercase(&[$($($pattern,)+)*]) as _];
#[allow(dead_code)]А что нам делать непосредственно самой проверкой? Мы проверяем, что значение равно, за вычетом ASCII-регистра, одному из паттернов... И что охранное выражение также справедливо, если оно есть:
fn non_repeating(s: &str) {
#[deny(unreachable_patterns)]
match s {
$($(| $pattern)+ => (),)*
_ => (),
}
}
x if ($(x.eq_ignore_ascii_case($pattern))||+) $(&& $condition)? => $arm,Обратите внимание, здесь мы повторяем (
+
) выражения для паттернов, разделив их ||
.Что ж, давайте опробуем макрос в действии:
#[derive(Debug)]Эта программа выдаёт следующее:
enum Example {
Foo,
Bar,
FourtyTwo,
}
impl std::str::FromStr for Example {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(ascii_case_insensitive!(match s {
"foo" => Self::Foo,
"bar" if s.as_bytes()[0].is_ascii_lowercase() => Self::Bar,
"fourtytwo" | "fourty_two" | "42" => Self::FourtyTwo,
_ => return Err(s.into()),
}))
}
}
fn main() {
let inputs = [
"foo",
"Foo",
"FOO",
"bar",
"bAr",
"BAR", // ошибка, первый символ в верхнем регистре
"fourtytwo",
"Fourtytwo",
"FOURTYTWO",
"fourty_two",
"fOuRtY_tWo",
"42",
"bogus",
];
for &input in &inputs[..] {
println!("{:?}", input.parse::<Example>());
}
}
Ok(Foo)...как и ожидалось. Что будет, если мы попытаемся сделать два одинаковых паттерна? Скажем, так:
Ok(Foo)
Ok(Foo)
Ok(Bar)
Ok(Bar)
Err("BAR")
Ok(FourtyTwo)
Ok(FourtyTwo)
Ok(FourtyTwo)
Ok(FourtyTwo)
Ok(FourtyTwo)
Ok(FourtyTwo)
Err("bogus")
...Компилятор жалуется:
"foo" | "foo" => Self::Foo,
...
error: unreachable patternА если один из паттернов не в нижнем регистре:
...то компилятор опять жалуется:
"Foo" => Self::Foo,
...
error[E0308]: mismatched typesВсё работает, как и ожидалось! Как всегда, весь код в гисте.
Telegram
Блог*
#prog #rust #моё
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
#prog #article
Обзор истории систем контроля версий с разбором их внутренних устройств в двух частях: первая, вторая.
В тему также интервью с Pierre-Étienne Meunier, ведущим разработчиком Pijul.
Обзор истории систем контроля версий с разбором их внутренних устройств в двух частях: первая, вторая.
В тему также интервью с Pierre-Étienne Meunier, ведущим разработчиком Pijul.
Initial Commit
Version Control Systems | A Technical Guide to VCS Internals
Learn what a version control system is and provide technical details of some of the most popular version control systems like SCCS, RCS, CVS, Subversion, Git, and Mercurial.
#prog #rust #article
Статья о том, чего бы автору хотелось видеть для Rust в 2021 году. Всё ключевые моменты выделять не буду (а иначе зачем я вам ссылку даю?), выделю только то, что привлекло моё внимание:
* I want to see Rust shed some of its reputation for being hard to learn
Согласно автору, новички сталкиваются с повышенной нагрузкой при изучении языка, поскольку им приходится учить и сам язык, и то, как писать на нём идиоматичный код. Учить Rust сложно ввиду того, что он схож с мейнстримными ЯП, но при этом довольно сильно от них отличается — достаточно, чтобы предыдущий опыт был не слишком полезен. Одним из следствий этих отличий является то, что лучшие практики из одних языков считаются антипаттернами в Rust (pub/sub, observer pattern), равно как и наоборот (затенение переменных). Автор считает, что новичкам имеет смысл позволить себе писать сначала неаккуратный и/или неидиоматичный код, а улучшать его уже потом. Да, это вопрос чисто психологический, но в интернете чаще выкладывают хороший код и редко — скажем так, не очень хороший, что создаёт определённое психологическое давление. Именно это и пишет автор:
I am not exactly sure how to create the conditions for this outcome. Maybe more people can publish more Rust that looks messy but “just works”.
Собственно, как совершенно справедливо заметил trentj на URLO (что в итоге стало фразой недели в TWiR №360):
"Just because Rust allows you to write super cool non-allocating zero-copy algorithms safely, doesn’t mean every algorithm you write should be super cool, zero-copy and non-allocating."
* More blog posts from developers and management using Rust at work
Особенно автору хочется видеть материалы с информацией о том, почему был выбран именно Rust, и о том, каков был опыт по сравнению с предыдущей реализацией — как правило, написанной на другом языке.
It’s great to hear Rust used in complicated, low-level development, but it would be normalizing to read about more trivial types of applications, just as a way to highlight Rust as being good for general purpose use.
Я со своей стороны могу лишь добавить, что по мере возможности стараюсь закрывать этот пробел в русскоязычном сообществе Telegram. Некоторые из подобных постов на моём канале можно найти по хештегу #successstory.
* More shared experiences from people picking up Rust as a second language.
Во многом перекликается с первым тезисом. Согласно автору, это может поспособствовать двум вещам: показать, что для того, чтобы выучить Rust, не нужно быть каким-то выдающимся человеком, и раскрыть глаза на вещи, которые опытные Rust-разработчики не замечают или воспринимают как должное.
I believe content from this crowd would be my favorites to read since I think they’ll give valid opinions to someone who has been using Rust for years (like me) now overlook or accept without second thoughts.
Статья о том, чего бы автору хотелось видеть для Rust в 2021 году. Всё ключевые моменты выделять не буду (а иначе зачем я вам ссылку даю?), выделю только то, что привлекло моё внимание:
* I want to see Rust shed some of its reputation for being hard to learn
Согласно автору, новички сталкиваются с повышенной нагрузкой при изучении языка, поскольку им приходится учить и сам язык, и то, как писать на нём идиоматичный код. Учить Rust сложно ввиду того, что он схож с мейнстримными ЯП, но при этом довольно сильно от них отличается — достаточно, чтобы предыдущий опыт был не слишком полезен. Одним из следствий этих отличий является то, что лучшие практики из одних языков считаются антипаттернами в Rust (pub/sub, observer pattern), равно как и наоборот (затенение переменных). Автор считает, что новичкам имеет смысл позволить себе писать сначала неаккуратный и/или неидиоматичный код, а улучшать его уже потом. Да, это вопрос чисто психологический, но в интернете чаще выкладывают хороший код и редко — скажем так, не очень хороший, что создаёт определённое психологическое давление. Именно это и пишет автор:
I am not exactly sure how to create the conditions for this outcome. Maybe more people can publish more Rust that looks messy but “just works”.
Собственно, как совершенно справедливо заметил trentj на URLO (что в итоге стало фразой недели в TWiR №360):
"Just because Rust allows you to write super cool non-allocating zero-copy algorithms safely, doesn’t mean every algorithm you write should be super cool, zero-copy and non-allocating."
* More blog posts from developers and management using Rust at work
Особенно автору хочется видеть материалы с информацией о том, почему был выбран именно Rust, и о том, каков был опыт по сравнению с предыдущей реализацией — как правило, написанной на другом языке.
It’s great to hear Rust used in complicated, low-level development, but it would be normalizing to read about more trivial types of applications, just as a way to highlight Rust as being good for general purpose use.
Я со своей стороны могу лишь добавить, что по мере возможности стараюсь закрывать этот пробел в русскоязычном сообществе Telegram. Некоторые из подобных постов на моём канале можно найти по хештегу #successstory.
* More shared experiences from people picking up Rust as a second language.
Во многом перекликается с первым тезисом. Согласно автору, это может поспособствовать двум вещам: показать, что для того, чтобы выучить Rust, не нужно быть каким-то выдающимся человеком, и раскрыть глаза на вещи, которые опытные Rust-разработчики не замечают или воспринимают как должное.
I believe content from this crowd would be my favorites to read since I think they’ll give valid opinions to someone who has been using Rust for years (like me) now overlook or accept without second thoughts.
DEV Community
Rust in 2021
I missed the official call for blog post submissions, I still want to share some ramblings of my hope...
#prog #rust #article
Тем временем народ настолько звереет от нехватки анонимных сумм-типов в Rust (а RFC для них было немало — Вафель не даст соврать), что пишет свои. В этот раз получилось даже неплохо.
Тем временем народ настолько звереет от нехватки анонимных сумм-типов в Rust (а RFC для них было немало — Вафель не даст соврать), что пишет свои. В этот раз получилось даже неплохо.
jam1garner
Anonymous Sum Types for Rust Error Handling
Blog post from 18 November 2020
#prog #go #article
Статья о внутреннем устройстве
Ключевая фишка реализации — фактически нетипизированная реализация мапы как таковой, отвечающая структуре hmap. Поле
Не знаю, как вам, а мне эта картина кажется весьма шаткой, особенно с учётом комментариев вроде "сохраняйте это определение структуры согласованным с вот этим местом в реализации рефлексии и той части компилятора, которая обходит AST". Ну и дублирование кода между
Статья о внутреннем устройстве
map
в Go. К сожалению, в статье длиннющая преамбула о различных вариантах реализации хэш-таблиц в разных языках и крайне мало о собственно реализации в Go.Ключевая фишка реализации — фактически нетипизированная реализация мапы как таковой, отвечающая структуре hmap. Поле
buckets
имеет тип unsafe.Pointer
, который является аналогом void*
из C: может указывать на что угодно. В контексте Go примечателен ещё и тем, что, в отличие от встроенных указателей, он не отслеживается сборщиком мусора. Все мало-мальски интересные функции, манипулирующие map
, принимают также указатель на значение типа maptype. В нем описаны характеристики хэш-таблицы — такие, как размер ключей, значений, бакетов, хранятся ли они значения по месту или же хранятся лишь указатели на них, а также функция для хэширования ключей и (через поле тип type_) функции для сравнения значений ключей и значений. Откуда берутся значения для maptype
? А их генерирует компилятор автоматически, когда переписывает обращения к map
через функции типа mapaccess1/mapaccess2. На этапе же компиляции он может проверить, что для типа ключа map
определены операции хэширования и сравнения.Не знаю, как вам, а мне эта картина кажется весьма шаткой, особенно с учётом комментариев вроде "сохраняйте это определение структуры согласованным с вот этим местом в реализации рефлексии и той части компилятора, которая обходит AST". Ну и дублирование кода между
mapaccess1
/mapaccess2
не может не радовать.GitHub
go/src/runtime/map.go at 8d3458517199f5aa2be0ec0f316fd406c9ca6cbb · golang/go
The Go programming language. Contribute to golang/go development by creating an account on GitHub.
Forwarded from Generative Anton (Anton Repushko)
Если быстро выдернуть чеку у гранаты и поднести ухо к дыре, где была чека, можно услышать, как увеличивается средний мировой IQ.
#prog #cpp
Длиннющий тред с примерами undefined behavior в C++. По состоянию на этот день в нём 98 записей
Длиннющий тред с примерами undefined behavior в C++. По состоянию на этот день в нём 98 записей
Twitter
Dmitry /Undefined Behavior/ Sviridkin
@vzverovich 98. Начиная с C++11, все временные значения живут до ; (end of statement). Начиная с него же появился удобный range based for. Но вот незадача: он раскрывается не в один statement, а в несколько. И временные значения в заголовке цикла могут не…
В разработке пост с рабочим названием "как быть, если тебе нужно написать простенький парсер, но nom выглядит перебором"