Forwarded from Linker Unsafe
На случай, если нужно будет кому-то рассказать, как состоят дела у C++ с неопределённым поведением. Ребята провели большую работу по собиранию и классификации разных случаев, но не гарантируется, что этот список полный.
www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1705r0.html
www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1705r0.html
Forwarded from Backlog
Excel и потерянные деньги💸
Исследования показывают, что около 90% электронных таблиц содержат ошибки. Только малая часть из них критична, но может привести к многомиллионным убыткам если их вовремя не обнаружить.
- 16 тысяч covid случаев в Британии не было зарегистрировано из-за того, что разработчики экспортировали данные в устаревший формат xls, который ограничен по количеству колонок.
- Производитель марихуаны Canopy Growth переоценил квартальную прибыль на 47 миллионов долларов из-за неправильной формулы в Excel которая считала разницу расходов и доходов.
- Boeing слил личные данные сотрудника в скрытой колонке таблицы.
- 10 тысяч несуществующих билетов было продано на Олимпийские игры в Лондоне. Всё из-за того, что сотрудник написал в таблице 20000 вместо 10000.
- Электроэнергетическая компания TransAlta потеряла 24 миллиона долларов, потому что приобрела больше договоров хеджирования чем нужно. Сотрудник компании использовал Excel функцию cut-and-paste, но неправильно выровнял ряды.
- Инвестиционный банк Lazard Ltd недооценил SolarCity на $400 млн., консультируя их при выкупе компанией Tesla, так как неправильно посчитал входные данные используя формулу Excel
Так вот, сегодня я узнал, что существуют целые компании, которые только тем и занимаются, что исправляют ошибки в электронных таблицах. Их клиентами являются крупные банки, регулирующие органы и транснациональные компании. Процесс изучения каждой электронной таблицы уникален. Для аудита сложных таблиц они используют ПО, которое построчно выявляет ошибки в структуре, формулах, неправильном формате данных. Один из основных тестов состоит в том, чтобы изменить входные данные и посмотреть, реагируют ли выходные данные так, как ожидалось. Но автоматизация, к сожалению, не помогает поймать логические проблемы. Для этого эксперты должны не только идеально разбираться в электронных таблицах, но и знать отрасль в которой работает их клиент. Короче говоря, это означает, что их работа сводится к тому, чтобы проводить дни за чтением таблиц и документов.
А есть такие же консультанты, которые посмотрят на код и скажут, что в будущем эта строчка будет стоить нам миллионных убытков? Я бы нанял
Исследования показывают, что около 90% электронных таблиц содержат ошибки. Только малая часть из них критична, но может привести к многомиллионным убыткам если их вовремя не обнаружить.
- 16 тысяч covid случаев в Британии не было зарегистрировано из-за того, что разработчики экспортировали данные в устаревший формат xls, который ограничен по количеству колонок.
- Производитель марихуаны Canopy Growth переоценил квартальную прибыль на 47 миллионов долларов из-за неправильной формулы в Excel которая считала разницу расходов и доходов.
- Boeing слил личные данные сотрудника в скрытой колонке таблицы.
- 10 тысяч несуществующих билетов было продано на Олимпийские игры в Лондоне. Всё из-за того, что сотрудник написал в таблице 20000 вместо 10000.
- Электроэнергетическая компания TransAlta потеряла 24 миллиона долларов, потому что приобрела больше договоров хеджирования чем нужно. Сотрудник компании использовал Excel функцию cut-and-paste, но неправильно выровнял ряды.
- Инвестиционный банк Lazard Ltd недооценил SolarCity на $400 млн., консультируя их при выкупе компанией Tesla, так как неправильно посчитал входные данные используя формулу Excel
Так вот, сегодня я узнал, что существуют целые компании, которые только тем и занимаются, что исправляют ошибки в электронных таблицах. Их клиентами являются крупные банки, регулирующие органы и транснациональные компании. Процесс изучения каждой электронной таблицы уникален. Для аудита сложных таблиц они используют ПО, которое построчно выявляет ошибки в структуре, формулах, неправильном формате данных. Один из основных тестов состоит в том, чтобы изменить входные данные и посмотреть, реагируют ли выходные данные так, как ожидалось. Но автоматизация, к сожалению, не помогает поймать логические проблемы. Для этого эксперты должны не только идеально разбираться в электронных таблицах, но и знать отрасль в которой работает их клиент. Короче говоря, это означает, что их работа сводится к тому, чтобы проводить дни за чтением таблиц и документов.
А есть такие же консультанты, которые посмотрят на код и скажут, что в будущем эта строчка будет стоить нам миллионных убытков? Я бы нанял
мне не нравится реальность
Photo
#prog #rust
Поясню на практическом примере, почему нужны generic associated types. Посмотрим на трейт std::io::BufRead. Это трейт, который расширяет функционал std::io::Read функционалом, который слишком неэффективно реализовывать напрямую на методах, предоставляемых
Один из методов, предоставляемых
Метод
Как мы можем обойти эту проблему? Вот тут и вступает в дело generic associated types. Мы можем написать альтернативное определение итератора:
Погоди, но вроде это можно реализовать и без GAT с таким определением:
Поясню на практическом примере, почему нужны generic associated types. Посмотрим на трейт std::io::BufRead. Это трейт, который расширяет функционал std::io::Read функционалом, который слишком неэффективно реализовывать напрямую на методах, предоставляемых
Read
. Подразумевается, что тип, реализующий BufRead
, имеет некоторый внутренний буфер, доступ к которому можно получить при помощи fill_buf. Наличие этого внутреннего буфера позволяет реализовать некоторые операции, которые затруднительно реализовывать непосредственно поверх Read
, например, read_until.Один из методов, предоставляемых
BufRead
— это lines, который возвращает итератор строк. Но что именно возвращает этот итератор? Он возвращает Result<String, std::io::Error>
. То есть каждый вызов Iterator::next
выделяет память в куче под строку. Как-то не zero cost. В конце концов, у типа, реализующего BufRead
, есть некий внутренний буфер, так почему нельзя возвращать ссылку на него? Давайте посмотрим внимательнее на типы.Метод
Iterator::next
имеет следующую сигнатуру:fn next(&mut self) -> Option<Self::Item>;Обратите внимание: несмотря на то, что в
next
неявно входит лайфтайм, этот лайфтайм отсутствует в возвращаемом типе! Это означает, что значение, возвращаемое next
, может быть, и не владеющее, но оно по крайне мере точно ничего не заимствует из self
. А как должен выглядеть гипотетический next
у нашего итератора, который возвращает ссылку на внутренний буфер?fn next<'a>(&'a mut self) -> Option<&'a str>;(Я сейчас намеренно опускаю вопрос об ошибках, потому что это не главное в том, что я хочу донести). Чем эта сигнатура кардинально отличается от
Iterator::next
? А тем, что (я даже специально расписал лайфтаймы, чтобы это было видно более ясно) возвращаемое значение заимствует self
! Таким образом, даже не смотря на то, что технически мы можем написать этот метод, он не подходит под сигнатуру Iterator::next
, а значит, мы не можем использовать все эти полезные итераторные комбинаторы.Как мы можем обойти эту проблему? Вот тут и вступает в дело generic associated types. Мы можем написать альтернативное определение итератора:
trait AnotherIterator {Новая версия итератора позволяет явно выразить тот факт, что мы не можем вызвать
type Item<'a>; // обратите внимание: тип параметризован
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
// комбинаторы поверх next
}
next
два раза подряд, сохранив оба результата. Да, нам придётся реализовать комбинаторы заново, но этот будут общие методы, а не функции под конкретный тип, которые плохо композируются друг с другом.Погоди, но вроде это можно реализовать и без GAT с таким определением:
trait OneMoreiterator<'a> {Можно. Но это решение обладает рядом недостатков. Первое: его неудобно использовать на практике. Так как нужный нам лайфтайм
type Item;
fn next(&'a mut self) -> Option<&'a Self::Item>;
}
'a
, скорее всего, будет локальным, а не обобщённым параметром, нам придётся использовать HRTB и писать что-то вродеfn do_stuff<I>(iter: I)Во-вторых — и это уже куда как более сильное ограничение — данное определение позволяет возвращать из
where
I: for<'a> OneMoreIterator<'a>,
{
//...
}
next
лишь ссылку на Item
, а не произвольный тип, параметризованный лайфтаймом (скажем, я могу себе представить тип, реализующий AnotherIterator
и возвращающий MutexGuard). В качестве примера, демонстрирующего оба недостатка, можно назвать WindowsMut
, несуществующий пока аналог Windows, возвращающий перекрывающиеся мутабельные подслайсы исходного слайса.GitHub
rfcs/text/1598-generic_associated_types.md at master · rust-lang/rfcs
RFCs for changes to Rust. Contribute to rust-lang/rfcs development by creating an account on GitHub.
Forwarded from Так говорил 2Pizza
Please open Telegram to view this post
VIEW IN TELEGRAM
rusta::mann
< мем из профунктора Я сгорел, ведь правильно приготовленный type-driven design оберегает от кучи логических ошибок, особенно связанных с проверками инвариантов (пресловутый is_initialized() вместо типа, который гарантирован находиться в валидном состояннии…
#prog #article
Продолжение темы от того же автора: Names are not type safety.
https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-type-safety/
В рассуждениях автора легко провести параллели с тем, как использовать и ограничивать unsafe-код в Rust.
Продолжение темы от того же автора: Names are not type safety.
https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-type-safety/
В рассуждениях автора легко провести параллели с тем, как использовать и ограничивать unsafe-код в Rust.
Я:
— Я взрослый мужчина, у которого есть работа и который знает цену деньгам, и я не буду делать импульсивных покупок.
Также я:
— Я взрослый мужчина, у которого есть работа и который знает цену деньгам, и я не буду делать импульсивных покупок.
Также я: