Блог*
#prog Взлом умной секс-игрушки. В плане безопасности состояние катастрофическое. Ну и вообще, зачем данные между плагом и PC гонять в виде JSON?! youtube.com/watch?v=RnxcPeemHSc
Есть текстовая расшифровка на русском, но видео всё же стоит посмотреть
habr.com/ru/company/ua-hosting/blog/495378
habr.com/ru/company/ua-hosting/blog/495378
Блог*
#prog #haskell #cpp #article Товарищ мёртвопищ опять вызывает бурления широких народных хабромасс. Haskell быстрее C++! Python медленнее PHP! Одна и та же оптимизация приводит к противоположным результатам в GCC и Clang! ...Реализация на других языках программирования…
#prog #haskell #c
И ещё раз про wc на Haskell. На это раз — с комбинируемыми статистиками, тормозными эрзац-завтипами и макросами. А, ну и опции нормально поддерживаются.
habr.com/ru/post/496370/
И ещё раз про wc на Haskell. На это раз — с комбинируемыми статистиками, тормозными эрзац-завтипами и макросами. А, ну и опции нормально поддерживаются.
habr.com/ru/post/496370/
Хабр
Радости и горести побед над C: делаем конфетку из прототипа wc на хаскеле
Привет, Хабр. Итак, в прошлый раз мы эмпирически доказали, что на хаскеле можно довольно легко написать этакий игрушечный wc, который при этом существенно быстрее реализации wc из GNU Coreutils....
#prog #rust
Как относительно просто сделать вполне рабочий string interner на Rust.
matklad.github.io/2020/03/22/fast-simple-rust-interner.html
Как относительно просто сделать вполне рабочий string interner на Rust.
matklad.github.io/2020/03/22/fast-simple-rust-interner.html
matklad.github.io
Fast and Simple Rust Interner
This post describes a simple technique for writing interners in Rust which I haven't seen documented before.
Блог*
#prog #rust #rustlib #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 в (почти) всех бенчмарках
Статья о дизайне beef (точнее, о том, как снизить размер beef::Cow ещё сильнее): troubles.md/abusing-rustc
Стоит ли оно того? Да: в Rust-порте simd-json использование beef::Cow вместо std::borrow::Cow привело к увеличение throughput в (почти) всех бенчмарках
GitHub
Beef by Licenser · Pull Request #113 · simd-lite/simd-json
experiment with beef
closes #112
closes #112
#prog #rust #rustlib #amazingopensource
Библиотека, позволяющая хранить данные за указателем, эксплуатируя неиспользуемые биты в указателе
crates.io/crates/tagged-box
Библиотека, позволяющая хранить данные за указателем, эксплуатируя неиспользуемые биты в указателе
crates.io/crates/tagged-box
#blogrecommendation
Что объединяет фильм «Форрест Гамп» и роман Шолохова «Тихий Дон»?
t.iss.one/bookswithklishin/375
Что объединяет фильм «Форрест Гамп» и роман Шолохова «Тихий Дон»?
t.iss.one/bookswithklishin/375
Telegram
ReadMe.txt
Что объединяет фильм «Форрест Гамп» и роман Шолохова «Тихий Дон»?
Казацкая песня про колоду-дуду, которая трансформировалась в американский фолк-хит 1960-х Where Have All the Flowers Gone.
Основу песни написал Пит Сигер. В интервью позже он вспоминал, что…
Казацкая песня про колоду-дуду, которая трансформировалась в американский фолк-хит 1960-х Where Have All the Flowers Gone.
Основу песни написал Пит Сигер. В интервью позже он вспоминал, что…
Forwarded from dd if=/dev/stuff of=/dev/tg
Волны твиттера принесли прекрасное: https://twitter.com/vamchale/status/1249076951685398530
TL;DR: в Elm была проблема — паттерн-матчинг по негативным числовым литералам приводил к ошибке парсинга. Эван Чаплицкий не только не исправил этот баг (при этом спросив у автора тикета «Instead of fake examples, can you explain how this comes up?») — он еще и добавил в компилятор текст ошибки, который прилагает использовать вместо паттерн-матчинга if-else.
TL;DR: в Elm была проблема — паттерн-матчинг по негативным числовым литералам приводил к ошибке парсинга. Эван Чаплицкий не только не исправил этот баг (при этом спросив у автора тикета «Instead of fake examples, can you explain how this comes up?») — он еще и добавил в компилятор текст ошибки, который прилагает использовать вместо паттерн-матчинга if-else.
Twitter
Vanessa McHale
- pattern matching on literals hits a parser bug in elm - someone reports this - evan responds by saying "Why are you doing this? Instead of fake examples, can you explain how this comes up?" (not kidding) github.com/elm/compiler/i…
#gamedev
Когда F. E. A. R. вышла, игру хвалили за сильный, реалистичный AI. Обычным подходом в играх для создания реалистичного AI со сложным поведением является программирование поведения вручную, часто с использованием иерархического конечного автомата. Такой подход трудоёмок, требует большого количества ручной подгонки и непрактичен для создания по-настоящему сложного поведения. Разработчики F. E. A. R. пошли по другому пути: вместо того, чтобы прописывать сложное поведение целиком, AI дали цели и набор возможных действий — и предоставили свободу в выборе достижения целей. Вкупе с небольшим количеством дополнительной логики для группового поведения это позволило добиться реалистичного поведения — того, за что игру 2005 года выпуска вспоминают до сих пор.
alumni.media.mit.edu/~jorkin/gdc2006_orkin_jeff_fear.pdf
Когда F. E. A. R. вышла, игру хвалили за сильный, реалистичный AI. Обычным подходом в играх для создания реалистичного AI со сложным поведением является программирование поведения вручную, часто с использованием иерархического конечного автомата. Такой подход трудоёмок, требует большого количества ручной подгонки и непрактичен для создания по-настоящему сложного поведения. Разработчики F. E. A. R. пошли по другому пути: вместо того, чтобы прописывать сложное поведение целиком, AI дали цели и набор возможных действий — и предоставили свободу в выборе достижения целей. Вкупе с небольшим количеством дополнительной логики для группового поведения это позволило добиться реалистичного поведения — того, за что игру 2005 года выпуска вспоминают до сих пор.
alumni.media.mit.edu/~jorkin/gdc2006_orkin_jeff_fear.pdf
Планирую написать небольшую заметку про отличия функций, замыканий и функциональных указателей в Rust. Интересует?
Anonymous Poll
66%
Да!
5%
Нет!
28%
Да пили уже
#prog #menacingopensource
Как передать аргументы командной строки в make? Разумеется, на костылях и непонятных командах.
stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line/6273809#6273809
Как передать аргументы командной строки в make? Разумеется, на костылях и непонятных командах.
stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line/6273809#6273809
Stack Overflow
How to pass argument to Makefile from command line?
How to pass argument to Makefile from command line?
I understand I can do
$ make action VAR="value"
$ value
with Makefile
VAR = "default"
action:
@echo $(VAR)
How do I get...
I understand I can do
$ make action VAR="value"
$ value
with Makefile
VAR = "default"
action:
@echo $(VAR)
How do I get...
Блог*
#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 можно передавать аргументы командной строки.
Если вам всё же нужен command runner, а не эрзац build system, то имеет смысл посмотреть на just. Проще и без странного поведения, присущего make. И да, в рецепты just можно передавать аргументы командной строки.
GitHub
GitHub - casey/just: 🤖 Just a command runner
🤖 Just a command runner. Contribute to casey/just development by creating an account on GitHub.
Forwarded from Matwey Kornilov
поребрик выглядит как дельта-функция, а бордюр как функция хевисайда
#prog #rust #моё
В Rust есть много хороших вещей. Одна из них — функции как первоклассные значения. Мы можем передать функцию как аргумент, возвращать функцию из функции и даже хранить функции в коллекциях. К сожалению, нацеленность Rust на абстракции нулевой (дополнительной) стоимости создаёт некоторые препятствия к широкому применению этой возможности и часто создаёт вопросы у новичков. Какие могут быть проблемы? Ну... Давайте просто поиграем с функциями, а проблемы возникнут сами 😈.
Сделаем функцию, которая будет принимать на вход два аргумента: функцию из числа в число и число, и которая будет просто применять функцию к этому числу. Неискушённый человек, только постигающий Rust, может написать следующее:
Да, но это не просто функция, это замыкание, т. е. функция, использующая данные за пределами е определения. Для того, чтобы вызвать это замыкание, требуется не только знать адрес, по которому расположен код функции, но и каким-то образом передать захваченные данные. Для каждой лямбда-функции компилятор Rust создаёт создаёт свой собственный уникальный тип. Поля этого типа — это данные, которые захватываются замыканием, в данном случае — поле под значение
Но погодите, почему же удалось вызвать
Потому что лямбда-функция
Это всё, конечно, очень интересно, но как мне всё-таки вызвать
Очевидно, поменяв тип
Ну, не совсем:
В Rust есть много хороших вещей. Одна из них — функции как первоклассные значения. Мы можем передать функцию как аргумент, возвращать функцию из функции и даже хранить функции в коллекциях. К сожалению, нацеленность Rust на абстракции нулевой (дополнительной) стоимости создаёт некоторые препятствия к широкому применению этой возможности и часто создаёт вопросы у новичков. Какие могут быть проблемы? Ну... Давайте просто поиграем с функциями, а проблемы возникнут сами 😈.
Сделаем функцию, которая будет принимать на вход два аргумента: функцию из числа в число и число, и которая будет просто применять функцию к этому числу. Неискушённый человек, только постигающий Rust, может написать следующее:
// vvvvvvvvvvvvvv - это же функция, верно?Попробуем её применить:
fn apply(func: fn(u32) -> u32, x: u32) -> u32 {
func(x)
}
fn add_one(x: u32) -> u32 {Этот код выводит "4", как и ожидается. Но постойте-ка, у нас же есть замечательный синтаксис для лямбда-функций! Может, применить его?
x + 1
}
fn main() {
println!("{}", apply(add_one, 3));
}
fn main() {Этот код тоже выводит "4". Что ж, давайте немного усложним код:
println!("{}", apply(|x| x + 1, 3));
}
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}`
Wikipedia
Closure (computer programming)
technique for creating lexically scoped first class functions