среда, 2 апреля 2025 г.

[life.cinema] Очередной кинообзор (2025/03)

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

Фильмы

Контратака (Contraataque, 2025). Мне понравилось.

Компаньон (Companion, 2025). Получил удовольствие от просмотра. Редко в последние годы встречаются фильмы, которые захватывают внимание и при просмотре которых не хочется выискивать и цепляться к недостаткам. Однако, мои вкусы несколько специфичны 😀

Микки 17 (Mickey 17, 2025). На фоне того, что нормальной фантастики давно не было этот фильм заметно выделяется. Я бы сказал, свежо и оригинально, приятно было смотреть. Претензии могу высказать к визуальной части, но, возможно, это было сделано специально, чтобы сделать происходящее еще более гротескным и вычурным.

Криминальный город: Возмездие (Beomjoe dosi 4, 2024). Если вам нравятся корейские фильмы с мордобоем, то смело можно смотреть.

Криминальный шеф (What You Wish For, 2023). Смотришь, смотришь, ждешь, ждешь настоящей кульминации и картсиса, а... А ничего похожего на это и не наступает. В результате складывается впечатление, что фильм не смог реализовать свой потенциал.

Месть (2023). Очень простенько сделанное кино, местами где-то на уровне художественной самодеятельности, но бодренькое. И с неожиданным для меня лично финалом, который с лихвой компенсировал все технические и художественные недостатки.

Свидание с монстром (Woman of the Hour, 2023). Хорошая картинка и достойная актерская игра. Но вот само построение сюжета с прыжками во времени туда обратно вызывает вопросы о том, а не испортило ли это все потенциально интересную историю.

Ограбление по-аризонски (The Last Stop in Yuma County, 2024). В принципе, я являюсь любителем такого рода фильмов. Но в данном случае нет в кино нерва, который бы вел бы зрителя от самых первых кадров до развязки (которая мне вполне понравилось). В итоге набор красивых картинок и более-менее удачных эпизодов, которые не складываются в целостное полотно.

Город демонов (Oni Goroshi, 2025). В принципе, любители жанра "кровавое мочилово" могут посмотреть. Но т.к. главный герой оказался настолько неубиваемым, что для меня лично все происходящее на экране быстро превратилось в цирк.

Клинер (Cleaner, 2025). Ничего не ждал от этого фильма, т.к. перед просмотром прочитал много отрицательных отзывов. На самом деле вполне себе средненькое современное кино про "сильных и независимых женщин" (tm). Лично мне не хватило динамики и экшОна, как-то все затянуто и уныло получилось.

След киллера (Damaged, 2024). У этого фильма есть две большие проблемы. Во-первых, всего две кинозвезды, что наводит на мысль, что Венсан Кассель не может быть просто вспомогательным персонажем, и что ему отводится гораздо большая роль, чем нам пытаются показать. Во-вторых, какое-то странное, неожиданное (я бы даже сказал внезапное) и нелогичное саморазоблачение главного злодея, когда у него были все шансы выйти сухим из воды. По итогу, корявым финалом авторы убили все то хорошее, что еще оставалось в их фильме.

Электрический штат (The Electric State, 2025). Просто удивительный пример того, как соединить просто офигенную картинку с абсолютно невнятным сюжетом и бездарной актерской игрой главных героев. Тот случай, когда в бочку меда (визуал) добавляют несколько мисок дерьма (сюжет, актерская игра).

Охотник за головами (The Getback, 2023). Редкая халтура, как по сюжету, так и по актерской игре. Но, особенно, в части т.н. экшОн сцен. Смело можно не смотреть.

Сериалы

Самбра: Анатомия преступления (Sambre, первый сезон, 2023). У этого сериала есть два достоинства -- полное отсутствие гламура, правда жизни как в позднем чернушном соцреализме, + очень хороший грим для героев, которые стареют по мере повествования, выглядит все очень достоверно. Но в целом это никакой не детектив, это что-то вроде социальной драмы в криминальном контексте. Хорошо сделанная, местами цепляющая, но драма, а не детектив.

ДерьмоКино вне категории

Бесстрашный (Tian long ba bu zhi qiao feng chuan, 2022). Какой-то Хон Гиль-дон только на технологиях XXI-го века. Не знаю кто и зачем будет смотреть это в здравом уме.

Мастер (A Working Man, 2025). Кино со Стейтемом превращается в отдельный жанр. Его герои настолько круты и неубиваемы, что даже неинтересно смотреть. И ладно бы там в самом экшОне были прорывы, как в первом Джоне Уике, так ведь нет. По итогу просто жалко потраченного на очередную туфту времени.

вторник, 1 апреля 2025 г.

[life.cinema] Вместо заключительного кинообзора

Так уж получилось, что в первые три месяца этого года у меня выдалось много свободного времени, часть которого уходила на просмотры всякого разного. Часть из отсмотренного попадала в традиционные кинообзоры, но далеко не все, т.к. был ряд фильмов, которые я даже не смог досмотреть (например: тыц и тыц).

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

И сегодня на этот вопрос я убедительного ответа найти не смог.

В связи с этим завязываю с публикацией списков, 99% которых составляет дешевый шлак. Может быть время от времени буду делать короткие заметки о фильмах, которые действительно понравилось. Но без привязки к конкретному графику.

Грустно, конечно. Длилась вся эта история, емнип, с октября 2012-го. Но что поделать, если кинематограф с ускорением несется по наклонной плоскости куда-то под плинтус и выдает "шедевры" вроде Капитан Америка: Новый мир, Мастер и Бесстрашный. Не хочу участвовать в этой безумной гонке наперегонки со здравым смыслом.

Upd от 2-го апреля: тем, кто воспринял этот текст слишком уж всерьез стоит обратить внимание на дату публикации ;)

понедельник, 31 марта 2025 г.

[prog.c++] Наследие темного прошлого C++, которое сейчас стало напрягать все больше и больше

Зафиксирую несколько моментов в C++, которые в последнее время напрягают, раздражают и, как правило, ведут к эпизодически проявляющимся ошибкам. Они были унаследованы из старых темных времен, являются наследием Си, но отравляют жизнь до сих пор. Хотя, наверное, не всем, а лишь тем, кто пытается следить за качеством кода 😡


Неявные приведения типов.

В каких-то случаях это удобно. Напишешь ты что-то вроде:

void dump_value(std::string_view value) {...}

а потом спокойно пихаешь туда строковый литерал:

dump_value("Hello, World!");

и все работает.

Хотя, чем старше становлюсь и с чем большим объемом чужого кода приходится иметь дело, тем больше склоняюсь к тому, что писать так:

dump_value("Hello, World!"sv);

или даже так:

std::string calculated_value = some_calculation();
dump_value(std::string_view{calculated_value});

тоже вполне себе OK.

Но вот что откровенно вымораживает, так это то, что язык допускает неявные преобразованиями между int-ами, long-ами, float-ами, double-ами и прочими числовыми типами. Иногда нужно включать высокие уровни предупреждений для того, чтобы компилятор хоть как-то пожаловался на выражения вида:

std::vector<item> items = collect_items();
int delta = items.size() > 3 ? 2 : 0;
std::size_t limit = (items.size() - delta) * 1.75;

Мой скромный опыт показывает, что когда начинают свободно смешиваться разные арифметические типы, то это либо показатель пока еще низкой квалификации разработчика (студент или вчерашний студент), либо это свидетельство просчетов при проектировании.

Очень хочется, чтобы компилятор запретил все подобные неявные преобразования между числовыми типами. Чтобы ошибка выдавалась даже при попытке неявно преобразовать std::uint8_t в std::uint16_t. Не говоря уже про преобразования от std::size_t к short или от double к long.


Использование "безразмерных" типов short, int, long и пр.

Да, я помню, что Страуструп агитировал за int. И он же считал ошибкой, что std::size_t в STL сделали беззнаковым.

Но мы сейчас живем в мире 64-х битовых архитектур и в ситуации, когда на машине несколько десятков гигабайт памяти уже не редкость. Причем на таких машинах решаются задачи в которых вся эта память используется. И совсем уже не экзотика, когда у нас может быть вектор с числом элементов больше 2 миллиардов или байтовый блоб размером больше 4GiB. Но при этом 32-х битовые архитектуры так же все еще встречаются и один и тот же исходный код может быть скомпилирован как в 32-х, так и в 64-х битах. И запущен он может быть на разных машинах с разным объемом памяти и исходных данных совершенно разного размера.

Поэтому когда я сейчас вижу в программах что-то вроде:

int l = strlen(some_string);

или

int last_element_index = vec.size() - 1;

то у меня буквально руки опускаются. Хорошо, пусть в большинстве случаев это безобидный код. Но, блин, как такие ошибки ловить в ситуациях, когда данные у нас оказываются реально большими? И зачем, спрашивается, эти самые ошибки ловить?

Поэтому я вообще склонен запретить использовать в коде типы, размерность которых никак не зафиксирована (short, unsigned short, int, unsigned int, long, unsigned long и т.п.).

Грубо говоря, int-у место разве что в примерах в старых учебниках. Но в современном предназначенном для продакшена коде, ему не должно быть места. Следует использовать либо типы с зафиксированной размерностью (std::uint8_t, std::uint16_t, std::uint32_t и т.д.), либо типы с обещанной минимальной размерностью (std::uint_fast8_t, uint_least8_t, std::uint_fast16_t, std::uint_least16_t и т.д.).


И еще один момент, которого в C++ нет, но который, имхо, был бы полезен.

ЕМНИП, в Pascal можно было объявить перечисление из, скажем, трех элементов, а затем создать массив, для индексации которого может использоваться именно это перечисление. Что-то вроде:

type
  Dimensions = (Price, Speed, Riskiness);
  Corrections = array of [Dimensions] of Real;
var
  CurrentCorrections : Corrections;
begin
  CurrentCorrections[Price] := 1.0;
  CurrentCorrections[Speed] := 0.5;
  CurrentCorrections[Riskiness] := 1.25;
  ...

При этом вы точно знаете, что ваш объект CurrentCorrections тесно связан с Dimensions. И если со временем ваш Dimensions меняется, то это сказывается и на работе с CurrentCorrections.

Тогда как в C++ такой фичи нет. Мы можем сделать так:

enum class Dimensions { Price, Speed, Riskiness };
using Corrections = std::array<double, 3>; // А вот тут уже первая неприятность.
...
Corrections current_corrections;
current_corrections[Dimensions::Price] = 1.0;
current_corrections[Dimensions::Speed] = 0.5;
current_corrections[Dimensions::Riskiness] = 1.25;

Но надежность этого кода будет исключительно на совести и внимательности программиста.

Например, у нас нет возможности узнать сколько элементов в перечислении. Как и нет возможности узнать значения элементов этого перечисления (чтобы выяснить монотонно ли они возрастают с шагом в 1 или нет).

Поэтому со временем кто-то может модифицировать перечисление Dimensions, например, вот так:

enum class Dimensions { Price = -2, Speed = 0, Riskiness = 3, Effectiveness = 10 };

и весь старый код, включая ставшее неправильным определение типа Corrections, все равно скомпилируется. А потом хорошо, если быстро упадет.

Может быть рефлексия, которую обещают завести в C++26, поможет сделать что-то подобное. Но еще вопрос когда C++26 получится попробовать в реальном проекте, да еще и за чужой счет. И даже когда в проектах начнет повсеместно применяться C++26, то как много C++ников захочет велосипедить что-то подобное на этой самой рефлексии?