Forwarded from Архонт щітпосту | #укртґ
«У России три пути: вебкам, закладки и айти»
> OnlyFans приостанавливает работу аккаунтов из России
> полиция Германии ликвидирует Гидру
> Интел полностью останавливает работу в России
У России… нет путей?
> OnlyFans приостанавливает работу аккаунтов из России
> полиция Германии ликвидирует Гидру
> Интел полностью останавливает работу в России
У России… нет путей?
🤔20👍9😢6❤2
Forwarded from partially unsupervised
Существует известная проблема из области социологии: как получить более или менее честные данные в количественном исследовании, если респонденты не хотят/боятся/стыдятся отвечать честно.
И вот случайно наткнулся на простой и изящный подход в духе differential privacy. TL;DR - формируем список из N утверждений, делим респондентов на две группы, одной показываем все N утверждений, другой - все, кроме того самого чувствительного. Вопрос формулируется как "с каким количеством утверждений (неважно, каких именно) вы согласны", и по разнице между группами легко вывести истинную поддержку.
Должно подойти не только для опросов про войну, но и для user research.
И вот случайно наткнулся на простой и изящный подход в духе differential privacy. TL;DR - формируем список из N утверждений, делим респондентов на две группы, одной показываем все N утверждений, другой - все, кроме того самого чувствительного. Вопрос формулируется как "с каким количеством утверждений (неважно, каких именно) вы согласны", и по разнице между группами легко вывести истинную поддержку.
Должно подойти не только для опросов про войну, но и для user research.
🔥11
Блог*
#rust В сорцах rustc банят числа.
Ввиду последних событий, вероятно, будут банить числа 86 и 90
👍1😁1
Forwarded from Незаслуженный учитель России
Задал ребенку блестящее (не могу кривить душой!) задание.
Мы решили (так как беседуем с ней раз в неделю уже третий год), что пора обсуждать литературу. Решили начать с мифа. Ученица начиталась терминологии, объяснила мне, что такое космогонический миф, а что такое онтологический. Было очень здорово, хотя слова эти по первости она произносила по слогам. Мы приводили друг другу примеры, пересказывали мифы разных народов и оба собой глубоко гордились.
И тут ученица задала блестящий вопрос — а выросли ли мы уже, все человечество, из мифов? Я задумался и предположил, что нет. В качестве примера я привел детскую мифологию, объясняющую мир. Например, мне в деревенском детстве объясняли, что убивать пауков нельзя. Если убьешь паука, то Бог плачет и идет дождь. Девочка очень обрадовалась и стала толковать. Пауки полезны, они очищают дом от насекомых, их нельзя убивать; но надо объяснить, почему. Я к этому добавил, что рассказывали мне это про пауков-крестовиков, у которых на спинке буквально крест — отсюда и мотив Бога. Ученица в качестве своего детского мифа привела историю про аиста, приносящего детей.
И тут у меня в голове щелкнуло. Я поразмыслил и предложил ей провести исследование. Буквально расспросить одноклассников о мифах, в которые они верили в детстве и с помощью которых им объяснили мир. А еще лучше — расспросить родителей о том, во что они верили в детстве. Ученица прямо самостоятельно и без напоминания записала все в тетрадочку и сообщила, что это очень остроумное задание. Я не мог не согласиться и решил ей польстить.
— Вообще-то это можно даже назвать антропологическим исследованием! — важно сказал я.
Девочка округлила глаза и тут же записала такое важное и звучное выражение.
Буду держать вас в курсе.
Мы решили (так как беседуем с ней раз в неделю уже третий год), что пора обсуждать литературу. Решили начать с мифа. Ученица начиталась терминологии, объяснила мне, что такое космогонический миф, а что такое онтологический. Было очень здорово, хотя слова эти по первости она произносила по слогам. Мы приводили друг другу примеры, пересказывали мифы разных народов и оба собой глубоко гордились.
И тут ученица задала блестящий вопрос — а выросли ли мы уже, все человечество, из мифов? Я задумался и предположил, что нет. В качестве примера я привел детскую мифологию, объясняющую мир. Например, мне в деревенском детстве объясняли, что убивать пауков нельзя. Если убьешь паука, то Бог плачет и идет дождь. Девочка очень обрадовалась и стала толковать. Пауки полезны, они очищают дом от насекомых, их нельзя убивать; но надо объяснить, почему. Я к этому добавил, что рассказывали мне это про пауков-крестовиков, у которых на спинке буквально крест — отсюда и мотив Бога. Ученица в качестве своего детского мифа привела историю про аиста, приносящего детей.
И тут у меня в голове щелкнуло. Я поразмыслил и предложил ей провести исследование. Буквально расспросить одноклассников о мифах, в которые они верили в детстве и с помощью которых им объяснили мир. А еще лучше — расспросить родителей о том, во что они верили в детстве. Ученица прямо самостоятельно и без напоминания записала все в тетрадочку и сообщила, что это очень остроумное задание. Я не мог не согласиться и решил ей польстить.
— Вообще-то это можно даже назвать антропологическим исследованием! — важно сказал я.
Девочка округлила глаза и тут же записала такое важное и звучное выражение.
Буду держать вас в курсе.
👍4
Forwarded from Макс Силинг
cat вступил в профсоюз и его теперь нельзя уволить с его работы на первом месте в пайплайне
🔥7
Блог*
#prog #rust #моё Тут Даня рассказывает о том, как можно уменьшить время на критические секции с мапой в многопоточном контексте, расчитывая хэш для поиска ключа заранее. Бенчмарк, который он сделал, показывает, что CPU time от подобных манипуляций остаётся…
#prog #rust #article
И ещё немного про мьютексы в Rust.
Why Rust mutexes look like they do (перевод)
(от автора m4vgalib, между прочим)
И ещё немного про мьютексы в Rust.
Why Rust mutexes look like they do (перевод)
(от автора m4vgalib, между прочим)
👍3
#prog #rust #моё
Пусть у нас есть слайс из вот таких структур:
| ||
| |return type of closure is &'2 String
| has type
В чём дело? Посмотрим на сигнатуру sort_by_key:
Что делать? Можно, конечно, клонировать строку, но делать аллокацию в памяти только ради того, чтобы сравнить данные и тут же их деаллоцировать — это расточительно. Проще использовать sort_by, который требует функцию, возвращающую Ordering:
ауф. Так что до новых встреч.
Пусть у нас есть слайс из вот таких структур:
struct Data {
name: String,
whatever: u32,
bytes: Vec<u8>,
}
, и нам надо отсортировать слайс по полю name. Казалось бы, плёвое дело:arr.sort_by_key(|d| &d.name);
Но компилятор ругается:error: lifetime may not live long enough
--> src/lib.rs:8:21
|
8 | arr.sort_by_key(|d| &d.name);
| -- ^^^^^^^ returning this value requires that '1 must outlive '2| ||
| |return type of closure is &'2 String
| has type
&'1 DataВ чём дело? Посмотрим на сигнатуру sort_by_key:
fn sort_by_key<K, F>(&mut self, f: F) where
F: FnMut(&T) -> K,
K: Ord,
Обратите внимание, параметр K не параметризован никакими временами жизни и потому считается независимым от переданной ссылки на T. Очевидно, в нашем случае это не так: ссылка на поле структуры не может жить дольше ссылки на структуру целиком.Что делать? Можно, конечно, клонировать строку, но делать аллокацию в памяти только ради того, чтобы сравнить данные и тут же их деаллоцировать — это расточительно. Проще использовать sort_by, который требует функцию, возвращающую Ordering:
arr.sort_by(|a, b| a.name.cmp(&b.name));
Окей, это работает, но выглядит уже не очень. Нам приходится повторять себя, да и идея "сравнить по name" уже не так хорошо читается. А если нам потребуется сравнивать сначала по name, а потом по bytes?arr.sort_by(|a, b| (&a.name, &a.bytes).cmp(&(&b.name, &b.bytes)));
Ох, выглядит так себе, от обилия скобочек немного рябит в глазах. А если переписать на методах Ordering?arr.sort_by(|a, b| a.name.cmp(&b.name).then_with(|| a.bytes.cmp(&b.bytes)));
Лучше особо не стало. И, кстати, что там, что там велик соблазн скопипастить выражения для a и заменить на b — великолепный способ, чтобы забыть в каком-то месте поменять. Мы можем сделать лучше! Упрячем sort_by в одном месте и выставим интерфейс, который принимает функцию для вынимания ключа:trait SliceExt<T> {
fn sort_by_ref_key<K, F>(&mut self, f: F)
where
F: FnMut(&T) -> &K,
K: Ord + ?Sized; // почему "?Sized"?}
impl<T> SliceExt<T> for [T] {
fn sort_by_ref_key<K, F>(&mut self, mut f: F)
where
F: FnMut(&T) -> &K,
K: Ord + ?Sized,
{
self.sort_by(|a, b| f(a).cmp(&f(b)));
}
}
Теперь мы можем красиво отсортировать по имени:arr.sort_by_ref_key(|d| &d.name);
Не менее красиво мы можем отсортировать по имени и по байтам... А нет, погодите, не можем — это потребует возвращать пару ссылок, а кортеж из ссылок ссылкой не является doc.rust-lang.org
slice - Rust
A dynamically-sized view into a contiguous sequence, `[T]`.
👍2
...Или мы можем подрубить nightly и абстрагироваться от конкретной разновидности заимствующих ключей при помощи GAT-ов!
...Ну, зато мы выпендрились GAT-ами. Как всегда, весь код в гисте.
#![feature(generic_associated_types)]Так как непосредственно конструктор типа мы передать не можем, мы передадим некий маркерный тип, к которому при помощи трейта прицепим ассоциированными типом нужный нам тип ключа:
trait BorrowedKeyFamily {
type Key<'a>: Ord + 'a;
}
Теперь нам нужен этот самый маркерный тип написать и связать его с кортежем ссылок:struct PairRef<T, U: ?Sized>(std::marker::PhantomData<(T, U)>);Как обычно, типовые сигнатуры начинают занимать больше места, чем сам код. Что ж, используем всё это для нового метода в
impl<T, U> BorrowedKeyFamily for PairRef<T, U>
where
T: Ord + 'static,
U: Ord + 'static + ?Sized,
{
type Key<'a> = (&'a T, &'a U);
}
SliceExt:trait SliceExt<T> {
// ...
fn sort_by_borrowed_key<K, F>(&mut self, f: F)
where
F: FnMut(&T) -> K::Key<'_>,
K: BorrowedKeyFamily;
}
impl<T> SliceExt<T> for [T] {
// ...
fn sort_by_borrowed_key<K, F>(&mut self, mut f: F)
where
F: FnMut(&T) -> K::Key<'_>,
K: BorrowedKeyFamily
{
self.sort_by(|a, b| f(a).cmp(&f(b)));
}
}
Кстати, благодаря анонимному лайфтайму нам не пришлось писать F: for<'a> FnMut(&'a T) -> K::Key<'a> (и, признаться честно, я удивлён, что для GAT это работает). Теперь напишем сортировку с только что сделанным методом:arr.sort_by_borrowed_key(|d| (&d.name, &d.bytes));
Всем спасибо, все сво...error[E0282]: type annotations needed
--> src/lib.rs:12:9
|
12 | arr.sort_by_borrowed_key(|d| (&d.name, &d.bytes));
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `K` declared on the associated function `sort_by_borrowed_key`
А, компилятор не может понять, что за маркерный тип тут используется. Что ж, неприятно, но вполне логично — мы теоретически можем написать ещё один тип и реализовать для него BorrowedKeyFamily с парой ссылок (вот, кстати, место, где пригодился бы аналог FunctionalDependencies из GHC). Придётся воткнуть турборыбу:arr.sort_by_borrowed_key::<PairRef<_, _>, _>(|d| (&d.name, &d.bytes));
Выглядит уже не так клёво. Вдобавок, у нашего кода есть одно досадное и неочевидное ограничение. Посмотрим ещё раз на ограничения на тип Key:type Key<'a>: Ord + 'a;
То есть что бы ни лежало в Key<'a>, оно должно жить как минимум 'a. А у нас 'a может быть произвольным. Для T и U в составе пары это фактически выливается в ограничение for<'a> 'a, что эквивалентно 'static по определению. На практике это означает, что мы не сможем класть в ключ строковые слайсы, что резко ограничивает применимость подхода....Ну, зато мы выпендрились GAT-ами. Как всегда, весь код в гисте.
👍6