Oct. 23rd, 2025

avva: (Default)
(для программистов)

Бьярн Струструп выпустил статью под названием "Concept-Based Generic Programming in C++", о том, что такое концепты (нововведение в C++ последних лет) и как они помогают писать код с темплейтами еще лучше, чем раньше. Если в двух словах, концепты это способ формулировать требования к типам (например, "тип T обязан быть численным" или "обязан поддерживать операцию < и возвращать bool"), чтобы можно было эти требования включать в темплейты.

Струструп наглядно показывает на хорошо подобранных примерах, зачем это нужно и как помогает. После прочтения я уяснил для себя эту часть современного C++, которую раньше не понимал. Но вместе с тем кажется, что это только усиливает те тенденции в C++, которые мне не нравятся.

Кажется, что для Струструпа идеальное использование C++ выглядит так. Рядовой программист использует классы, функции итд., которые написали для него некие волшебники за кулисами. Для него все вылизано и сделано максимально простым: он объявляет переменные каких-то типов, делает с ними операции, которые удобно записываются как + или <<, и так далее. Если он что-то написал неправильно, то в 90% случаев это даже не скомпилируется, а если скомпилируется, то кинет исключение, но ему для этого ничего не нужно особенно делать. При этом волшебники за кулисами, чтобы все это сделать, написали тонны крайне нечитаемого и сложного кода, который делает головокружительную эквилибристику, жонглирует мета-программированием, использует всякие подспорные std::штуки и "двойные" ссылки и ключевое слово "requires", которые рядовой программист в обычной жизни вообще никогда не видит. Почему-то оба эти языка, тот, на котором пишет программист и волшебник за кулисами, называются C++.

С моей точки зрения это ужасно, с точки зрения Струструпа - красиво и правильно. Более того - неизбежно вытекает из твердых принципов, которые он повторяет в начале статьи (generality, uncompromised efficiency, statically type-safe interfaces - совместимость тут даже не упоминается, как само собой разумеющееся, видимо).

Например, он дает пример класса Span, который заключает в себе идею контейнера с прямым доступом по индексу, проверяющего, что индекс не выходит за пределы. Span можно инициализировать обычным массивом с размером, известным во время компиляции, или вектором с размером, доступным по size(), и он будет работать одинаково просто и удобно, и кидать исключение в случае слишком большого индекса. Если мы а) несогласны вносить проверку границ в сам язык (uncompromised efficiency), но при этом хотим дать к ней удобный доступ всем, кто хочет и не ограничиться одними массивами или векторами, а вообще для всего (generality), и при этом для разных видов Span автоматически компилировать разный код для доступа к реальным данным и проверки их длины (statically type-safe interfaces), то мы приходим к необходимости наворотить кучу сложной магии за кулисами, чтобы можно было написать:

double arr[10];
Span s(arr);
s[20] // throws

При этом Струструп отдельно с гордостью поясняет, что, казалось бы, надо писать Span<double> s(arr), потому что темплейт-классу Span необходимо знать тип элемента в контейнере, но пользуясь отдельным специальным магическим заворотом, можно сделать так, что эта информация выцепляется из arr статически. По-моему это только все ухудшает, потому что не понимаешь даже, что используешь темплейтный класс. По Струструпу, это правильно, мне и не нужно это понимать, мне надо пользоваться API, которые наваяли волшебники, и не отсвечивать.

Внутренности Span частично выглядят так:
template<class T>
class Span {
T* p;
unsigned n;
Span(std::ranges::continuous_range auto& s) : p{data(s)}, n{size(s)} {}
}

T.e. Span хранит указатель на начало данных, правильного типа, и их размер; но откуда он их берет? Для контейнера s он вызывает data(s) и size(s) - откуда они берутся?
data() и size() - темплейтные функции, которые по-разному написаны для массива и для вектора (итп.), сидят в std::range - то, что для них не указан std::range это еще один вид магии, так называемый ADL, крайне неприятный. А std::ranges::continuous_range это как раз и есть концепт, который говорит в своем определении, что тип обязан предоставить data() и size() - "предоставить" не как в ООП, не как методы в классе, а просто чтобы были, чтобы data(s) и size(s) компилировалось и давало правильный тип.

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

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

I chose the < … > notation for type parameterization following some use in theory. Initially, I did not use the prefix template keyword: < … > was a suffix to the name they parameterized. However, people strongly insisted on having a prefix keyword to make templates stand out. That is typical, initially people ask for a LOUD syntax for novel constructs because they are seen as difficult or even dangerous. Later, the same people complain about verbosity.
avva: (Default)
Оказывается, значительную часть японской фантастики, которая была переведена и издана в СССР, перевел один человек, некий "Зея Рахим". Мне попалось это имя в выпускных данных одного романа, заинтересовало своей необычностью. За ним прячется тень загадочного человека.

Известно, что много лет сидел в одной камере с Даниилом Андреевым (автором "Розы мира", сидел в 1947-1957), который к нему привязался. В 60-х крутился в литературных кругах; Нина Воронель описала знакомство с ним в своих воспоминаниях. Называл свое полное имя - "Харун ибн Кахар, шейх Уль-Мюлюк, эмир Эль-Каири", но по паспорту был Зея Рахим, татарин из Мукдена; он же утверждал, что это имя навязала ему советская власть, и что на самом деле он араб, вырос в Александрии, учился в Японии, владел фабриками в Манчжурии, был арестован после того, как СССР выбил японцев из Манчжурии и получил длинный срок за шпионаж в пользу Японии.

Насчет его переводов Воронель пишет (правда, надо учесть, что к достоверности ее воспоминаний было немало претензий):

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

Это тот самый Сергей Хмельницкий, который, как потом стало известно, много лет был осведомителем КГБ. Впрочем, сам Рахим, похоже, был одновременно харизматичным и скользким типом; вдова Андреева в итоге порвала с ним отношения, и вроде бы после того, как он втерся в доверие к ее родителям и занял у них и не вернул большую сумму денег.

Но самый интересный - как по мне - пунктик во всем этом я узнал в комментариях к ЖЖ-записи - цитирующей сохранившиеся упоминания Рахима (той же Воронель и другие). В комментарии пришла его внучка и рассказала, что сам Зея Рахим умер в 1998-м от рака, его дочь Светлана - относительно недавно в 2017-м, но главное - его семья тоже так и не знала, чему верить в плане легенды о его жизни, потому что "дедушка так же загадочно общался и с близкими".

Я подумал, что если бы я был фантазером и фантасмагористом, и рассказывал длинные и противоречивые легенды о своей жизни, то наверное своей семье, детям и внукам хоть под конец жизни рассказал бы целиком правду. Чтобы не было этого ощущения, как эта правда о каком-то человеке с паспортом на имя Зея Рахим, то, кто он вообще был, где вырос, какое настоящее имя - исчезает и улетучивается безвозвратно; вполне возможно, не осталось уже ни архивов, ни людей, которые когда-либо смогут пролить свет на это.

А может, ему пофиг было.

"Дедушка так же загадочно общался и с близкими".

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 26th, 2025 08:10 pm
Powered by Dreamwidth Studios