1.83K subscribers
3.24K photos
127 videos
15 files
3.52K links
Блог со звёздочкой.

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Блог*
#prog #rust #моё Во время решения одной из задач Advent of Code мне пришлось решать довольно заковыристую в плане владения задачу: требовалось связать цепочку интерпретаторов так, чтобы данные, выдаваемые одним экземпляром интерпретатора, использовались в…
#prog #rust #моё
В конце этой заметки я сказал, что планирую расширить код до поддержки impl BorrowMut<VecDeque<T>>. Теперь я понимаю, что это несколько неосмотрительно: код в unsafe полагается на то, что адрес, по которому лежат данные, не меняется. В случае impl BorrowMut такой гарантии уже нет. Для доказательства того, что подобный вариант является unsound, предположим, что MutPair уже реализовал подобный функционал (это изменение я, с вашего позволения, опущу, потому что это чисто механическое изменение кода) и рассмотрим следующий тип:

#[derive(Default)]
struct DeqWrapper<T> {
inner: VecDeque<T>,
}

Для него можно написать следующие реализации Borrow и BorrowMut:

impl<T> Borrow<VecDeque<T>> for DeqWrapper<T> {
fn borrow(&self) -> &VecDeque<T> {
&self.inner
}
}

impl<T> BorrowMut<VecDeque<T>> for DeqWrapper<T> {
fn borrow_mut(&mut self) -> &mut VecDeque<T> {
self.inner.clear();
&mut self.inner
}
}

Да, это отвратительно, да, так никто (я надеюсь) не пишет. Но принципиально нас ничего от этого не ограждает. Хочу отметить, что код выше не содержит unsafe.

Теперь попытаемся использовать данный тип:

let wrapper = DeqWrapper::<i32>::default();
wrapper.inner.push_back(0);
wrapper.inner.push_back(1);
let mut mut_pair = MutPair::new(wrapper).unwrap(); // (1)
let _ = mut_pair.get(); // (2)

Что тут происходит? В (1) мы делаем внутри MutPair::new проверку длины дека. Так как при этом мы используем .borrow(), DeqWrapper даёт ссылку на поле inner, длина которого как раз достаточна, поэтому MutPair возвращает Ok и .unwrap() не паникует. В (2) мы вызываем .borrow_mut(), из дека удаляется данные, MutPair::get использует get_mut, предполагая, что данные есть, и — вуаля! — мы получаем ссылку на неинициализированные данные! Что является UB в Rust.

Хочу особо отметить, что мы получили UB, не написав (как пользователь) unsafe-код и не вызвав unsafe-код напрямую, поэтому наш код unsound.
Блог*
#prog #rust #моё В конце этой заметки я сказал, что планирую расширить код до поддержки impl BorrowMut<VecDeque<T>>. Теперь я понимаю, что это несколько неосмотрительно: код в unsafe полагается на то, что адрес, по которому лежат данные, не меняется. В случае…
В чём же проблема? Наш код слепо доверял реализации BorrowMut, чего делать не стоит (unsafe не должен доверять safe).

Каковы решения? Лично я вижу такие:
1) Объявить методы MutPair как unsafe. В принципе, вариант, но это немного лишает смысла эту абстракцию.
2) Оставить код как есть. Вполне рабочий вариант, но не исключено, что для кого-то это окажется недостаточно гибким.
3) Обобщить код относительно sealed-трейта и включить в него только доверенные реализации (для VecDeque<T> и &mut VecDeque<T>). Тоже рабочий вариант (если я таки буду публиковать этот код на crates.io, то, вероятно, так и поступил бы), но это выглядит несколько избыточным решением + страдает эргономика: пользователю теперь надо импортировать нужный трейт, который он(а) не может реализовать.
99) Требовать от типов реализовать трейт, который не только даёт мутабельную ссылку на VecDeque, но и требует доказательство вменяемости такой реализации. К сожалению, этот вариант сильно превосходит текущие возможности Rust и навряд ли когда-то будет осуществлён.
Forwarded from The After Times
#prog #video
Как писать тесты (если быть более точным — тесты для property-based тестирования).
Лично для меня поразила идея metamorphic testing — простая и вместе с тем плодотворная.
https://youtu.be/zvRAyq5wj38
#prog #article

As closing thoughts: this blog post is not intended to start a flame war, nor is it intended to be an assault on dynamically typed programming. There are many patterns in dynamically-typed languages that are genuinely difficult to translate into a statically-typed context, and I think discussions of those patterns can be productive. The purpose of this blog post is to clarify why one particular discussion is not productive, so please: stop making these arguments. There are much more productive conversations to have about typing than this.

https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-type-systems-are-not-inherently-more-open/
Forwarded from Aleksandr Razumov
Ну и правильно писать на го нифига не просто, весь этот маркетинговый булщит работает только под хорошим менторством и ревью от синьеров
#article #retroit

Разбор электронных часов, использовавшихся на "Союзе". Спойлер: схема занимает несколько плат, большинство покрыто чипами.

http://www.righto.com/2020/01/inside-digital-clock-from-soyuz.html
Forwarded from Aikidos
Бог умер
Forwarded from Stanislav Seregin
А джаваскрипт нет, кек
#quotes
(Я тоже, кстати)
Forwarded from Αλεχ Zhukovsky
я до сих пор не знаю зачем нужен кубернетес
Олег срывает покровы
#quotes
Forwarded from Oleg
сервис меш это тср-айпи для зумеров