Linker Unsafe
220 subscribers
182 photos
24 videos
18 files
859 links
Собираю ржавые и лямбдообразные новости, прикольные цитатки с форумов, ссылки на статьи и всё такое. В-общем, сюда я тащу такие крупицы, которые мне будет жаль потерять в цифровой бездне. Возможно, они покажутся интересными и вам.

Фи сюда: @nlinker
Download Telegram
Forwarded from Aikidos
это как сейчас в го видят "женерики"
Всем, кто не читает код, который реальную задачу не выполняет.
Например, нужно какой-то интеррапшен/ брэкет реализовать
А в го из общения файберов только ченнелы.

И вот кто-то читает статью или костылит сам какой-то интеррапшен с помощью специального одноразового ченнела и откладывание освобождения ресурсов на прокидывании ошибок в нём.

Потом пишет десять частных кусков кода, чтобы интеррапшен глубже прокидывать, каждый раз заново реализует.

Естественно, 1000 багов, естественно полноценно конкурентный код со всеми возможными сценариями отмен невозможно проверить тестами.

Абстрагировать всё это нельзя, потому что типы везде у ченнелов и ресурсов разные, а женериков нет

И вот ты открываешь эти лестницы из костылей и пытаешься понять, работает ли хотя бы один из них, и где тут между строками говна бизнкс-логика

Quet Zal:
context же

Oleg ℕizhnik:
Ну так если хоть сколько нетривиальная логика ресурсов, а точнее они вообще есть, его использовать нельзя

Quet Zal:
ну таймауты-интерапшены через него
логику ресурсов руками под каждый конкретный случай
и да, возможно в итоге получится более error-prone код чем если бы была какая-нибудь супер библиотека на типах, но прочитать и понять такой код будет проще
Когда индустриальный программист пишет статью, он разбавляет её водой.
Когда участник русскоязычной Haskell-группы пишет статью, он разбавляет её кислотой.
Когда академик пишет статью, он разбавляет её кровью индустриального программиста.
(Посвящается Гранину)
Маск нервно курит в сторонке :-)
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempdir::TempDir;

#[tokio::test]
async fn test_mailbox_senders() -> Result<(), Box<dyn std::error::Error>> {
let tmp_dir = TempDir::new("test_mailbox")?;
let address = tmp_dir.path().join("test_message_1");
let mut mailbox_sender = MailboxSenders::default();
let (tx, fut) = mailbox_sender.create(address.clone());
tx.unbounded_send("foo\n".into())?;
mailbox_sender
.get(&address)
.unwrap()
.unbounded_send("bar".into())?;
tx.unbounded_send("baz\n".into())?;
mailbox_sender.remove(&address);
drop(tx);
fut.await?;
let contents = fs::read_to_string(&address).unwrap();
assert_eq!(contents, "foo\nbar\nbaz\n");
Ok(())
}
}
Hippolot:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3ebc57e006f8bd8a0e9611d2f7714f16

Как бы вы реализовали метод poll с такими же ограничениями как в сигнатуре? Футура должна суммировать значения трёх других футур

Denis:
а ты принципиально не используешь сторонние крейты?

Hippolot:
Те, что доступны на плейгранде, можно использовать. Я просто не совсем соображаю как с такими же ограничениями реализовать футуру. С async/.await было бы так:
async fn sum<Fut1, Fut2, Fut3>(fut1: Fut1, fut2: Fut2, fut3: Fut3) -> i32
where
Fut1: Future<Output = i32>,
Fut2: Future<Output = i32>,
Fut3: Future<Output = i32>,
{
fut1.await + fut2.await + fut3.await
}

Kitsu:
Ну во-первых зачем свою футурку писать, это ведь по сути join_all + sum. Ну а если очень хочется можно сделать Either<Fut, FutResult> для каждой футуры и последовательно поллить Either::Left. Как только все футуры будут готовы вернуть сумму из Either::Right. В идеале конечн это в какой-нибудь VecDeque положить, чтоб все это дело полилось раунд-робином.

red75prime:
C unsafe{ Pin::new_unchecked(ref_mut_fut1).poll(...) } мы никуда fut1 не двигаем, поэтому должно быть безопасно. Возможно. На 100% не поручусь.

Наверно ещё один unsafe понадобится, чтобы дропнуть содержимое fut1 in-place.

Denis:
ещё можно сделать futures unordered + fold :)

red75prime:
Да. Join из futures использует MaybeDone, а он делает Pin::new_unchecked(): https://github.com/rust-lang/futures-rs/blob/90c83b8faca107e6c4db63d10b0d4f2ea36d6628/futures-util/src/future/maybe_done.rs#L96

Drop in place реализуется через Pin::set()
https://t.iss.one/rustlang_ru/261371
Forwarded from Αλεχ Zhukovsky
Сравни один и тот же код:

Скала:

def stateMonad[S]: Monad[State[S, ?]] = {
type StateS[A] = State[S, A]
new Monad[StateS] {

override def unit[A](a: => A): StateS[A] =
State(s => (a, s))

override def flatMap[A, B](f: StateS[A])(g: A => StateS[B]): StateS[B] =
State[S, B](
s1 => {
val (a, s2) = f.run(s1)
g(a).run(s2)
}
)
}
}

раст: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=47674d68fc881db41fa44153257b521f
Forwarded from Αλεχ Zhukovsky
Forwarded from саша кремов
Да нет, просто это разные области знаний, и если ты потратил годы на постижение ИП, это не значит что теперь ты с двух ног можешь залететь в ФП.
Forwarded from Oleg Andreev
решил переписать толстый цикл task::spawn(async move {while let Some(event) = stream.next().await {...} }) на комбинацию стримов
Forwarded from Oleg Andreev