Size: a a a

2020 April 10
Блог*
dereference_pointer_there
#prog

Взлом умной секс-игрушки. В плане безопасности состояние катастрофическое. Ну и вообще, зачем данные между плагом и PC гонять в виде JSON?!

youtube.com/watch?v=RnxcPeemHSc
Есть текстовая расшифровка на русском, но видео всё же стоит посмотреть

habr.com/ru/company/ua-hosting/blog/495378
источник
Блог*
dereference_pointer_there
#prog #haskell #cpp #article
Товарищ мёртвопищ опять вызывает бурления широких народных хабромасс.
Haskell быстрее C++!
Python медленнее PHP!
Одна и та же оптимизация приводит к противоположным результатам в GCC и Clang!

...Реализация на других языках программирования (включая Rust) тоже имеется, так что есть шанс сравнить производительность.
https://habr.com/ru/post/483864/
#prog #haskell #c

И ещё раз про wc на Haskell. На это раз — с комбинируемыми статистиками, тормозными эрзац-завтипами и макросами. А, ну и опции нормально поддерживаются.

habr.com/ru/post/496370/
источник
Блог*
#prog #rust #amazingopensource

beef — как Cow, только занимает меньше памяти.

github.com/maciejhirsz/beef
источник
Блог*
#prog #rust

Как относительно просто сделать вполне рабочий string interner на Rust.

matklad.github.io/2020/03/22/fast-simple-rust-interner.html
источник
Блог*
dereference_pointer_there
#prog #rust #amazingopensource

beef — как Cow, только занимает меньше памяти.

github.com/maciejhirsz/beef
#prog #rust

Статья о дизайне beef (точнее, о том, как снизить размер beef::Cow ещё сильнее): troubles.md/abusing-rustc
Стоит ли оно того? Да: в Rust-порте simd-json использование beef::Cow вместо std::borrow::Cow привело к увеличение throughput в (почти) всех бенчмарках
источник
Блог*
#prog #rust #amazingopensource

Библиотека, позволяющая хранить данные за указателем, эксплуатируя неиспользуемые биты в указателе

crates.io/crates/tagged-box
источник
Блог*
#prog #meme
источник
Блог*
источник
2020 April 11
Блог*
#blogrecommendation

Что объединяет фильм «Форрест Гамп» и роман Шолохова «Тихий Дон»?

t.me/bookswithklishin/375
Telegram
ReadMe.txt
Что объединяет фильм «Форрест Гамп» и роман Шолохова «Тихий Дон»?

Казацкая песня про колоду-дуду, которая трансформировалась в американский фолк-хит 1960-х Where Have All the Flowers Gone.

Основу песни написал Пит Сигер. В интервью позже он вспоминал, что в 1955 году читал в самолете роман Шолохова «Тихий Дон», где, дальше длинная цитата, «рассказывалось о том, как казаки ускакали, чтобы присоединиться к армии царя. По пути они пели. В книге приводится три строчки из песни:

Where are the flowers? The girls plucked them
Where are the girls? They’re all married
Where are the men? They’re all in the army».

Текст Сигера представлял собой пересказ этих строк. Только добавляется, что солдаты погибли и на их могилах снова растут цветы. Вьетнам, шестидесятые, вот это все.

Но были ли в его книги на самом деле такие строки, спросил себя я.

В 1955 году был только один перевод «Тихого Дона» на английский, сделанный Гарри Стивеном. И там колыбельная из третьей главы первого тома выглядит так:

And where are the geese?…
источник
2020 April 12
Блог*
#prog и, пожалуй, #menacingopensource
источник
Блог*
Волны твиттера принесли прекрасное: https://twitter.com/vamchale/status/1249076951685398530

TL;DR: в Elm была проблема — паттерн-матчинг по негативным числовым литералам приводил к ошибке парсинга. Эван Чаплицкий не только не исправил этот баг (при этом спросив у автора тикета «Instead of fake examples, can you explain how this comes up?») — он еще и добавил в компилятор текст ошибки, который прилагает использовать вместо паттерн-матчинга if-else.
источник
2020 April 13
Блог*
#gamedev

Когда F. E. A. R. вышла, игру хвалили за сильный, реалистичный AI. Обычным подходом в играх для создания реалистичного AI со сложным поведением является программирование поведения вручную, часто с использованием иерархического конечного автомата. Такой подход трудоёмок, требует большого количества ручной подгонки и непрактичен для создания по-настоящему сложного поведения. Разработчики F. E. A. R. пошли по другому пути: вместо того, чтобы прописывать сложное поведение целиком, AI дали цели и набор возможных действий — и предоставили свободу в выборе достижения целей. Вкупе с небольшим количеством дополнительной логики для группового поведения это позволило добиться реалистичного поведения — того, за что игру 2005 года выпуска вспоминают до сих пор.

alumni.media.mit.edu/~jorkin/gdc2006_orkin_jeff_fear.pdf
источник
Блог*
"Хочешь найти темы для блога? Зайди в новичковый чат" (c) #моё
источник
Блог*
Планирую написать небольшую заметку про отличия функций, замыканий и функциональных указателей в Rust. Интересует?
Анонимный опрос
65%
Да!
6%
Нет!
29%
Да пили уже
Проголосовало: 103
источник
Блог*
#prog #menacingopensource

Как передать аргументы командной строки в make? Разумеется, на костылях и непонятных командах.

stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line/6273809#6273809
источник
Блог*
#prog #rust #amazingopensource

Если вам всё же нужен command runner, а не эрзац build system, то имеет смысл посмотреть на just. Проще и без странного поведения, присущего make. И да, в рецепты just можно передавать аргументы командной строки.
источник
2020 April 14
Блог*
#quotes

И да, между поребриком и бордюром действительно есть разница
источник
Блог*
Переслано от ttldtor
а чем отличается поребрик от бордюра?
источник
Блог*
поребрик выглядит как дельта-функция, а бордюр как функция хевисайда
источник
2020 April 18
Блог*
#prog #rust #моё

В Rust есть много хороших вещей. Одна из них — функции как первоклассные значения. Мы можем передать функцию как аргумент, возвращать функцию из функции и даже хранить функции в коллекциях. К сожалению, нацеленность Rust на абстракции нулевой (дополнительной) стоимости создаёт некоторые препятствия к широкому применению этой возможности и часто создаёт вопросы у новичков. Какие могут быть проблемы? Ну... Давайте просто поиграем с функциями, а проблемы возникнут сами 😈.

Сделаем функцию, которая будет принимать на вход два аргумента: функцию из числа в число и число, и которая будет просто применять функцию к этому числу. Неискушённый человек, только постигающий Rust, может написать следующее:

//             vvvvvvvvvvvvvv - это же функция, верно?
fn apply(func: fn(u32) -> u32, x: u32) -> u32 {
   func(x)
}

Попробуем её применить:

fn add_one(x: u32) -> u32 {
   x + 1
}

fn main() {
   println!("{}", apply(add_one, 3));
}

Этот код выводит "4", как и ожидается. Но постойте-ка, у нас же есть замечательный синтаксис для лямбда-функций! Может, применить его?

fn main() {
   println!("{}", apply(|x| x + 1, 3));
}

Этот код тоже выводит "4". Что ж, давайте немного усложним код:

fn main() {
   let one = 1;
   println!("{}", apply(|x| x + one, 3));
}

И этот код выводит... А не, не выводит, он не компилируется:

error[E0308]: mismatched types
--> src/main.rs:8:26
 |
8 |     println!("{}", apply(|x| x + one, 3));
 |                          ^^^^^^^^^^^ expected fn pointer, found closure
 |
 = note: expected fn pointer `fn(u32) -> u32`
               found closure `[closure@src/main.rs:8:26: 8:37 one:_]`

Но ведь это же функция!

Да, но это не просто функция, это замыкание, т. е. функция, использующая данные за пределами е определения. Для того, чтобы вызвать это замыкание, требуется не только знать адрес, по которому расположен код функции, но и каким-то образом передать захваченные данные. Для каждой лямбда-функции компилятор Rust создаёт создаёт свой собственный уникальный тип. Поля этого типа — это данные, которые захватываются замыканием, в данном случае — поле под значение one. Тип же fn(u32) -> u32 — это функциональный указатель (function pointer), фактически, просто адрес в памяти, по которому располагается код функции. Неудивительно, что apply не удалось вызвать  — это разные типы с разными размерами!

Но погодите, почему же удалось вызвать apply с аргументом |x| x + 1?

Потому что лямбда-функция |x| x + 1 не захватывает никаких переменных из окружения, а такие замыкания могут быть приведены к функциональному указателю начиная с версии Rust 1.19. Такое приведение может сработать в ряде различных мест, в число которых входит и аргумент функции при вызове.

Это всё, конечно, очень интересно, но как мне всё-таки вызвать apply с |x| x + one?

Очевидно, поменяв тип apply. Мы не можем дать типу замыканию имя, поэтому правильным решением будет сделать apply обобщённой функцией:

fn apply<F>(func: F, x: u32) -> u32
where
   F: Fn(u32) -> u32,
{
   func(x)
}

Что тут происходит? Мы ввели обобщённый параметр F и добавили на него ограничение Fn(u32) -> u32. Это означает, что значение типа F можно вызвать как функцию с одним аргументом u32, причём неограниченное число раз. Теперь apply можно вызвать в любом варианте:

fn main() {
   println!("{}", apply(add_one, 3));
   println!("{}", apply(|x| x + 1, 3));
   let one = 1;
   println!("{}", apply(|x| x + one, 3));
}

Отлично! Значит, замыкания имеют разные типы, а у обычных функций с одинаковыми сигнатурами типы одинаковые

Ну, не совсем:

type Pair<T> = (T, T);

fn add_one(x: u32) -> u32 {
   x + 1
}

fn add_two(x: u32) -> u32 {
   x + 2
}

fn main() {
   let funcs: Pair<_> = (add_one, add_two);
}

Этот код не компилируется:

error[E0308]: mismatched types
 --> src/main.rs:12:36
  |
12 |     let funcs: Pair<_> = (add_one, add_two);
  |                                    ^^^^^^^ expected fn item, found a different fn item
  |
  = note: expected fn item `fn(_) -> _ {add_one}`
             found fn item `fn(_) -> _ {add_two}`
источник