Когнитивный налог: сколько стоит думать по-английски, когда программируешь
Спор о русском в коде обычно ведут идеологи. Одни требуют «программировать на родном», другие крутят пальцем у виска. Но если убрать эмоции, остаётся инженерная задача: где локализация снимает трение, а где создаёт новое?
Мы 60 лет учим разработчиков думать по-английски, чтобы они могли программировать. Не «знать английский» — это нормально. А думать на нём, когда пишут код на русском домене. Юрист, читающий спецификацию, и разработчик, читающий код, говорят на разных языках — и мы называем это профессиональным стандартом.
Пора это признать. И посмотреть, во что это обходится на практике.
Мелкие тупняки, которые складываются в большие потери
Когнитивный налог — это не драма. Это не история про то, как кто-то полгода не мог разобраться в одном имени. Это сотни мелких заминок в день, каждая из которых длится минуту-другую — и вместе они съедают часы.
Открываешь модуль, видишь getPrincipal(). Думаешь: тело долга. Пишешь формулу. Через минуту выясняется, что в соседнем модуле getPrincipal() — это владелец учётной записи, а в третьем — глава организации. Ты не потратил полдня. Ты потратил пять минут. Но таких пятиминуток за день — десятки. Bill — счёт или банкнота? Draft — вексель или черновик? Security — ценная бумага или безопасность? Каждая — маленькая заминка. Вместе — налог, который платит каждый русскоязычный разработчик, даже не замечая этого.
Имена, которые ничего не значат
У этого есть отдельная разновидность — и она коварнее, чем кажется. Речь не о лени. Речь о том, что придумать точное имя сложно, особенно когда английский не родной. И мозг в такой ситуации делает не то, что нужно, а то, что проще.
Вот как это выглядит изнутри. Пятница, шесть вечера. У тебя три задачи в работе, одна из них горит. Нужно назвать новый компонент — тот, что обрабатывает отчёт по НДФЛ. Мозг в режиме экономии не ищет точное слово. Он ищет хоть какое-нибудь. И находит самое доступное: вроде что-то связанное с платежами, поэтому Pay, но посвящена повторным платежам, поэтому Repay. А дальше следует набор «бэйджей», чтобы было проще найти: NDFL, Report, Processing, Component. Ты не думаешь «это плохое имя» — ты думаешь «ну ладно, хотя бы понятно, о чём речь». Нажимаешь Enter.
А через полгода кто-то другой открывает PayRepayNDFL6_2ReportProcessingComponent и не понимает ничего. Что такое 6_2 — версия? Номер формы? Второй квартал шестого года? Почему Pay и Repay стоят рядом — это два действия или одно? Что делает Processing — считает, отправляет, логирует?
Дальше начинается цепная реакция. Новичок учит расшифровку этих ярлыков вместо того, чтобы разбираться в предметке. Ревьюер не знает, что проверять, — он видит только имя, а имя молчит. LLM-ассистент генерирует мусор, потому что ему не за что зацепиться. Каждая из этих заминок — минута. Но таких компонентов в проекте сотни, а минуты складываются в часы.
И самое неприятное: это не лечится дисциплиной. Можно договориться «называйте понятно» — и через месяц всё вернётся, потому что проблема не в людях. Проблема в языке, на котором им приходится думать.
Когда английский теряет точность
Была у меня история с проектом для юристов. Я писал код и использовал due, deadline, expiry как синонимы — ну а что, все три про сроки. Пока на встрече юрист не объяснил, что :срок-исполнения, :срок-хранения и :срок-годности — это три разные вещи, и их нельзя путать. Одна относится к обязательствам, другая к документам, третья к товарам.
Я не полгода писал неправильный код. Я за пару недель накопил десяток мест, где использовал «не то» слово — и каждое потом приходилось править. Английский не давал мне точности, которую дал бы русский: в нём просто нет отдельных слов для этих трёх сроков.
Именно поэтому локализация — это не только про слова. Это про онтологию: про то, есть ли в языке отдельные имена для вещей, которые в предметке действительно разные. И вот как это решали до сих пор.
1С: локализация как индустриальный стандарт
Первое, что приходит в голову, когда речь заходит о русском в коде, — это 1С. И не зря: здесь локализовано всё. Ключевые слова, типы (Число, Строка, СправочникСсылка, ПланВидовХарактеристик), ошибки (ОшибкаКонфигурации, НарушениеПравДоступа), документация.
Но дело не в переводе слов. 1С породила свою онтологию: РегистрСведений, Документ, ПланВидовХарактеристик — сущности, которых в английском просто нет. И это даёт тот эффект, которого не хватало: программист и бухгалтер говорят на одном языке. Не в том смысле, что бухгалтер читает код — а в том, что они используют одни и те же слова, когда обсуждают задачу. «Регистр сведений» — это не «information register», это понятие, которое бухгалтер знает по работе.
Локализация популярных языков — и особый случай Лиспа
Русскоязычные расширения появились почти в каждом популярном языке: алиасы ключевых слов в Python (если, пока, функция), русские идентификаторы в JS, Ruby, C#, юникод-имена в Go. Всё это — попытки снизить налог, не создавая новый язык.
Именно в Лиспе локализация пошла дальше всех — потому что Лисп для этого и создавался: минимальное ядро, макросы, расширяемость. defun переименовывается в определить-функцию, домен описывается на родном языке без перевода. В Китае это стало одним из самых популярных решений в тусовке продвинутых программистов — именно за возможность описывать домен на своём языке, не переключаясь на английский в голове.
Локализация — не причуда. Это работающая практика, которая существует в разных парадигмах: в ООП (1С), в мультипарадигменных языках, в Лиспе. Вопрос не «возможна ли она», а «какой ещё парадигмы ей не хватает».
Марка: другая философия
Мы прошли три подхода: 1С, где локализация — это ООП-парадигма; расширения Python, JS, Ruby, где она — надстройка; Лисп, где она — среда. Но есть ниша, которую никто не занял: функциональный, иммутабельный, data-driven язык, где локализация — сама конструкция, а не перевод. Такого ещё не было. И вот здесь появляется Марка.
В статьях про Clojure есть известный эффект: когда все значения иммутабельны, ты перестаёшь бояться править код на лету. Нет страха, что где-то в другом месте что-то сломалось из-за твоей правки, — потому что сломаться нечему, ты создаёшь новое значение, а старое остаётся нетронутым. Это меняет не синтаксис, а ощущение от работы.
С Маркой происходит похожая вещь, но по другой причине. Здесь предметка живёт не в комментариях и не в голове разработчика — она живёт в самом языке. Ты описываешь тип задачи, и этот тип становится частью кода, которую можно проверить, передать, вернуть из функции. Ты не держишь в голове соответствие «это поле значит вот это» — оно записано в типе, и язык его проверяет. Меняется не то, что ты можешь написать, а то, как ты думаешь, когда пишешь.
Это не «ещё один локализованный язык». Это другой режим работы — и он растёт из одной идеи: предметка должна жить в языке, а не в комментариях.
Один DSL для кода и типов — и типы как объекты первого порядка
Выражения языка типов и языка программирования — одни и те же. Типы можно передавать, возвращать, вычислять, валидировать в рантайме. Один язык для описания данных и для работы с ними.
lisp
тип Задача() :(
:текст: Строка()
:выполнено?: ?()
:срок-исполнения: Дата())
фун обработать :(з: Задача()) Строка()
разбор з Задача() :(
?+ : :готово
?- : :в-работе)Предметка живёт не в комментариях, а в исполняемой спецификации. Разработчик и аналитик читают один и тот же код — и он валидируется машиной. Тип здесь — не декларация для компилятора, а значение, с которым можно работать в REPL. Проверить входные данные, собрать новый тип на лету, вернуть его из функции — всё это часть обычного цикла разработки, а не отдельного этапа сборки.
Русский язык в функциональной парадигме
А теперь самое интересное. В функциональном языке русский раскрывается иначе, чем в ООП.
В 1С локализация работает через сущности: РегистрСведений, Документ, ПланВидовХарактеристик. Это имена объектов, которые можно осязать. Русский здесь — язык предметной области, и он привязан к объектам.
В функциональной парадигме объектов нет. Есть данные и их преобразования. И здесь русский даёт то, чего не может дать английский: естественный порядок мысли.
Смотрите. В английском функция — это getUserName(user). Глагол, объект, субъект. В русском ты думаешь: «получить имя пользователя» — и это уже другая структура. А в функциональном стиле ты думаешь ещё иначе: «имя пользователя» — это данные, «получить» — преобразование. И язык позволяет выразить это напрямую:
lisp
>>> пользователь
если-админ(замени-имя(пользователь, "Админ"))
если-ошибка(логируй)Читается как предложение на русском: «взять пользователя, если это админ, замени имя на "Админ", если в процессе возникнет ошибка: логгируй». Не try {if (user.isAdmin()) then user.name = "Admin"} catch ... — а последовательность действий, описанная на языке предметки. Порядок слов в русском гибкий, и это идеально ложится на функциональные цепочки: ты можешь сказать «имя пользователя получить» или «получить имя пользователя» — и оба варианта будут звучать естественно.
Чужой код на Марке читается не как набор вызовов, а как текст. Ты не расшифровываешь getUserName(user) — ты читаешь «получить имя пользователя» и идёшь дальше. На длинных цепочках это ощущается как разница между чтением вслух и чтением по слогам.
Вот почему русский в функциональной парадигме — это не просто перевод ключевых слов. Это новый способ выражать преобразования данных. Английский в функциональном коде часто звучит как набор команд: map, filter, reduce. Русский позволяет описать то же самое как повествование: «возьми список, обнови каждый-элемент, сверни-в сумму».
И это работает не только на уровне синтаксиса. Типы ошибок, разбор, пайплайны — всё это в Марке звучит как русская речь. Потому что язык проектировался не как перевод, а как свой способ думать о данных.
Кстати, если вас заинтересовал этот проект, узнайте о нём больше на сайте http://marka-lang.ru/. Мы как раз сейчас в стадии активной разработки и интересуемся мнением программистов об этом инструменте.
Вместо вывода
Мы весь текст обсуждали когнитивный налог: сколько стоит думать по-английски, когда код — про русскую предметку. Но если честно, это разговор про симптом, а не про болезнь.
Настоящий вопрос глубже: что если родной язык — не перевод поверх чужого опыта разработки, а органичная часть собственного? Когда язык, на котором ты думаешь, и язык, на котором ты пишешь, — один и тот же. И когда сам способ работы с кодом отличается от того, к чему ты привык.
Когнитивный налог не виден в отчётах. Его не покажет ни один тайм-трекер. Но он есть — в каждой пятиминутке, когда ты перечитываешь имя и соображаешь, что оно значит. В каждом спринте, где новичок тратит день на расшифровку вместо работы. В каждом ревью, где приходится объяснять, что делает компонент, — потому что имя молчит.
Можно снижать этот налог по чуть-чуть: переводить ключевые слова, локализовать ошибки, называть переменные по-русски. А можно — построить язык, в котором налога нет с самого начала, потому что русский в нём не надстройка, а фундамент. И вместе с ним — другой способ работы с кодом, другая модель того, как ты проводишь день.
Это не про русский или английский. Это про то, что выбор языка — это выбор того, как ты думаешь. И этот выбор уже сделан — историей языка, на котором вы пишете сейчас.
А вы замечали, что тратите время на расшифровку английских имён в своей предметке? Сколько это — часов в месяц?
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.