Forwarded from Коза кричала
Разгадана одна из главных тайн мироздания: Почему вомбат срет кубиками?
Эта загадка будоражила умы ученых давно, но ответ был получен лишь теперь. Попутно доказали несостоятельность всех прежних гипотез, имевших в академических кругах широкое хождение. Одни говорили, что у вомбатов квадратный анус. Другие - что какашки приобретают необычную форму при прохождении костей таза. Третьи - что вомбаты лепят из какашек геометрически строгие куличики уже, так сказать, пост-фактум - посрамши.
Так вот это не так. У вомбатов любопытный кишечник. Одни участки мышц в нем твердые, другие эластичные. И именно поэтому какашки получаются почти квадратными. Но возникает вопрос - а зачем им быть такими? Какой смысл заложила в это Природа? Дело в том, что вомбаты таким образом помечают территорию и общаются с сородичами. Какашка, выпав из жопы, должна остаться на месте, чтобы донести свой "месседж". А будь она круглой, то просто укатится хрен знает куда. Поэтому куб - идеальная форма.
Знание - сила!
Эта загадка будоражила умы ученых давно, но ответ был получен лишь теперь. Попутно доказали несостоятельность всех прежних гипотез, имевших в академических кругах широкое хождение. Одни говорили, что у вомбатов квадратный анус. Другие - что какашки приобретают необычную форму при прохождении костей таза. Третьи - что вомбаты лепят из какашек геометрически строгие куличики уже, так сказать, пост-фактум - посрамши.
Так вот это не так. У вомбатов любопытный кишечник. Одни участки мышц в нем твердые, другие эластичные. И именно поэтому какашки получаются почти квадратными. Но возникает вопрос - а зачем им быть такими? Какой смысл заложила в это Природа? Дело в том, что вомбаты таким образом помечают территорию и общаются с сородичами. Какашка, выпав из жопы, должна остаться на месте, чтобы донести свой "месседж". А будь она круглой, то просто укатится хрен знает куда. Поэтому куб - идеальная форма.
Знание - сила!
#prog #article
Статья (перевод) о том, как сбить с толку шахматный движок и заставить его крашнуться или предложить заведомо неверные ходы.
Статья (перевод) о том, как сбить с толку шахматный движок и заставить его крашнуться или предложить заведомо неверные ходы.
chess.resistant.tech
Win by Segfault and other notes on Exploiting Chess Engines
We document a number of paths that can be used to exploit the Stockfish chess engine, causing crashes when attempting to evaluate the next best move, or even outright tricking the engine into believing it has no valid moves (while preserving the illusion…
Forwarded from мне не нравится реальность (вафель 🧇🍓)
This media is not supported in your browser
VIEW IN TELEGRAM
Forwarded from мне не нравится реальность (вафель 🧇🍓)
вафель держит Илью 2021 год, фото в цвете
Forwarded from Linker Unsafe
lwn.net
Pattern matching accepted for Python
The Python steering council has, after some discussion, accepted the
controversial proposal to add a
pattern-matching primitive to the language.
"We acknowledge that
Pattern Matching is an extensive change to Python and that reaching
consensus across the…
controversial proposal to add a
pattern-matching primitive to the language.
"We acknowledge that
Pattern Matching is an extensive change to Python and that reaching
consensus across the…
Linker Unsafe
**Pattern matching accepted for Python** Давайте поорём
#prog #cpp
— Mom, can we have pattern matching?
— We already have pattern matching at home.
Meanwhile pattern matching at home:
https://github.com/solodon4/Mach7
— Mom, can we have pattern matching?
— We already have pattern matching at home.
Meanwhile pattern matching at home:
https://github.com/solodon4/Mach7
GitHub
GitHub - solodon4/Mach7: Functional programming style pattern-matching library for C++
Functional programming style pattern-matching library for C++ - solodon4/Mach7
Никто:
Абсолютно никто:
Мой коллега в час ночи в рабочем чатике:
— Эй, а попробуйте решить на расте вот такую задачу по десериализации YAML!..
#трудовыебудни
Абсолютно никто:
Мой коллега в час ночи в рабочем чатике:
— Эй, а попробуйте решить на расте вот такую задачу по десериализации YAML!..
#трудовыебудни
Блог*
#prog #rust #моё В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
#prog #rust #моё
Кое-что я при разработке этого макроса упустил: проверка на недостижимость кода недостаточно точна. Если строка не начинается с префикса, скажем,
Начнём с выяснения того, является ли одна строка префиксом другой. Ничего сложного в этом нет (кроме того, чтобы перепутать одну строку с другой, ага), просто несколько неудобно из-за ограничений const fn:
Кое-что я при разработке этого макроса упустил: проверка на недостижимость кода недостаточно точна. Если строка не начинается с префикса, скажем,
"java"
, то пытаться отщипнуть префикс "javascript"
уже не имеет смысла, потому что он заведомо отсутствует. Однако мой макрос проверяет строки на (не)равенство и не учитывает их возможных структурных отношений. Сейчас мы это исправим, и пойдём по уж проторенной дорожке: вынесем нужную проверку в const fn
и будем генерировать код, который не тайпчекается в случае, если проверка завершилась неудачей.Начнём с выяснения того, является ли одна строка префиксом другой. Ничего сложного в этом нет (кроме того, чтобы перепутать одну строку с другой, ага), просто несколько неудобно из-за ограничений const fn:
const fn is_prefix(s: &str, maybe_prefix: &str) -> bool {Теперь немного подумаем о том, как детектировать недостижимые паттерны. Для этого нам нужно перебрать все пары различных строк из
if maybe_prefix.len() > s.len() {
return false;
}
let s = s.as_bytes();
let mp = maybe_prefix.as_bytes();
let mut i = 0;
while i < mp.len() {
if mp[i] != s[i] {
return false;
}
i += 1;
}
true
}
match
и проверить, что для каждой такой пары строка из более поздней ветки не является префиксом строки из более ранней ветки. Так? Так, да не совсем: у ветки может быть охранное выражение, и в этом случае выполнение ветки может не произойти по совершенно произвольным причинам. Поэтому в генерируемом коде мы будем хранить не только строки, но и признак того, что охранное выражение есть, и в соответствующей функции будем эти строки пропускать. Сказано — сделано:const fn has_unreachable_patterns(ss: &[(&str, bool)]) -> bool {Осталось только сгенерировать код для проверки, заменив в макросах функцию
if ss.is_empty() {
return false;
}
let mut i = 0;
let mut j;
while i < ss.len() - 1 {
// строки, для которых есть охранное выражение, пропускаем
if ss[i].1 {
i += 1;
continue
}
j = i + 1;
while j < ss.len() {
// А вот вторую строку в паре нужно проверять всегда,
// вне зависимости от того, есть у него охранное выражение или нет:
// если охранного выражения нет у первой строки, то исполнение
// до ветки со второй строкой точно не дойдёт.
if is_prefix(ss[j].0, ss[i].0) {
return true;
}
j += 1;
}
i += 1;
}
false
}
non_repeating
(это изменение, кстати, одинаковое для всех двух (трёх) макросов) — и это, кажется, наиболее зубодробительная часть:const _HAS_NO_UNREACHABLE_PATTERNS: [(); 0] = [Это довольно много, так что разберём по частям:
();
has_unreachable_patterns(
&[
$((
$prefix,
false $(|| {stringify!($condition); true})?
),)*
]
) as _
];
const _HAS_NO_UNREACHABLE_PATTERNS: [(); 0] = [Это объявление константы. Если
();
has_unreachable_patterns(...) as _
];
has_unreachable_patterns(...)
вычисляется в true
, то оно при касте в usize
становится 1
, вызывая ошибку несоответствия типов.&[Здесь мы формируем ссылку на литерал массива, элементами которого являются пары, первыми элементами которых являются строки-префиксы.
$((
$prefix,
...
),)*
]
false $(|| {stringify!($condition); true})?Здесь мы формируем значение
true
, если охранное выражение имеется. Сделать повтор синтаксического фрагмента без соответствующей синтаксической метапеременной нельзя, но и само выражение нам не требуется, поэтому воспользуемся стандартным трюком: переведём выражение в безвредную строку и отбросим её. На итоговое выражение это не повлияет, а наличие нужной метапеременной обеспечено. И да, это не замыкание, как может показаться, а выражение с оператором "или".
Блог*
#prog #rust #моё Кое-что я при разработке этого макроса упустил: проверка на недостижимость кода недостаточно точна. Если строка не начинается с префикса, скажем, "java", то пытаться отщипнуть префикс "javascript" уже не имеет смысла, потому что он заведомо…
Что ж, с этим разобрались. Проверим теперь, как это работает на практике, и для этого модифицируем
Есть недостатки у нашего решения? Определённо — помимо тех, о которых я уже писал. Во-первых, теперь это жёсткая ошибка вместо предупреждения компилятора — но да, это спорный недостаток. А во-вторых — и вот это уже недостаток куда как более существенный — ошибка компиляции не говорит о том, какие паттерны перекрываются. И я, к сожалению, не придумал, как их показывать, не выходя за пределы того, что умеет stable Rust.
use_prefixes
:fn use_prefixes(s: &str) -> String {Эта функция закономерно вызывает жалобы у компилятора на несоответствие типов. Отлов ошибок работает! Теперь немного поменяем определение:
prefixes!(match s {
"foo".. => s.to_string(),
"bar".. => [s, s].concat(),
"foobar".. => [s, "3"].concat(),
_ => String::new(),
})
}
fn use_prefixes(s: &str) -> String {...И теперь у компилятора нет вопросов.
prefixes!(match s {
"foo".. if true => s.to_string(),
"bar".. => [s, s].concat(),
"foobar".. => [s, "3"].concat(),
_ => String::new(),
})
}
Есть недостатки у нашего решения? Определённо — помимо тех, о которых я уже писал. Во-первых, теперь это жёсткая ошибка вместо предупреждения компилятора — но да, это спорный недостаток. А во-вторых — и вот это уже недостаток куда как более существенный — ошибка компиляции не говорит о том, какие паттерны перекрываются. И я, к сожалению, не придумал, как их показывать, не выходя за пределы того, что умеет stable Rust.