Однажды настанет день, когда команды в программировании будут выглядеть вроде «эй, компьютер, сделай-ка мне вот эту хреновину».
Что там будет под капотом, ни одна живая душа уже не поймет. Команда «хреновина» интерпретируется в абзац с описанием, который интерпретируется в ключевые слова, который интерпретируется в набор векторных обозначений, который интерпретируется в какой-нибудь С, который скомпилируется в…
и где-то там внизу превратится в электрические импульсы на железяках.
Программистами станут лощеные гуманитарии с «высокими вербальными способностями, коммуникативными навыками и умением быть няшей в команде». Слава богу до этого дня, как до Аляски на упряжке, но каждый раз изобретая очередной Kotlin, мы этот день приближаем.
Просто я задумался — а не стали ли наши ЯПы уже чем-то таким? Чуть более умным эквивалентом фразы «компьютер, сделай хреновину». Кучей формализованных протоколов для электричества, про которое мы уже забыть забыли. Штукой, которая все сильнее рвет нашу связь с механической реальностью.
Я часто слышу фразу: «Фил, отступись, хватит думать обо всякой чепухе». Но блин, будь проклят тот день, когда на Хабре напишут «хватит думать».
У меня на работе много небольших проектов, и мы используем разные стеки — .net, React.ts, c++, Java. В чем ты хоть немного прошарен, то на тебя и повесят. Я пришел как дотнетчик, но таски на доске есть на все приложения, доступ к репозиториям — тоже.
Возник кейс, когда все таски на мой стек были полным дерьмищем, за которое возьмется только безумец. Я — не безумец, и начал брать таски с тайпскриптом и реактом, потом с джавой. Все приложения делают примерно одно и тоже, но рассчитаны на разные платформы. Проблем у меня не возникало.
Вот я написал штуку, которая выбирает лучший впн сервер на шарпах, вот пошел делать то же самое на джаве. То же самое, точно таким же образом. Поначалу не придавал значения, но в какой-то момент не заметить закономерность было уже очень сложно.
Я просто делал одно и то же на разных языках программирования. Этот код был очень похожим, за исключением деталей, которые никак не влияют на решаемую задачу. Ведь бизнес не приходит ко мне со словами: «Эй Фил! Нам нужно использовать абстрактные классы, чтобы отобразить клиенту состояние впн соединения». Бизнес и пользователи хотят, чтобы девайс показал им картинку. Да и я на самом деле тоже просто хочу показать им эту картинку.
Но я не могу. Нельзя просто сказать машине: делай то, что мне нужно. Пока еще я тот самый промежуточный интерпретатор, который превращает фразу «сделай хреновину» в команды, пока еще мне приходится детально и пошагово разъяснять процессору, куда и как класть долбаные байты.
Но и я уже не работаю с байтами. Я работаю на очень абстрактном уровне со штуками, которые производят фабрику фабрик механизмов, которые управляют этими байтами. Там внизу есть железяка, и она устроена еще сложнее — я понятия не имею как, что там делается. Но оно делается, через сотню призм, о которых я тоже не имею никакого понятия. Половину того, что я хочу сказать машине, она «додумывает» сама, и я не знаю, как именно.
Я как будто запаял капот автомобиля и стал чинить его через выхлопную трубу, которая становится с каждым годом все длиннее и длиннее, и однажды, чтобы починить двигатель, мне просто придется кричать в трубу, а не лезть руками.
Дотнетный компиль превращает мой сишарп в промежуточный язык (IL), который едет на машину к клиенту, где в свою очередь другой дотнетный компиль (который just-in-time) на лету превращает мой IL в платформоспецифичный код, который в свою очередь скармливается процессору…
И где-то там все мои формальные описания, все различия между ЯПами стираются, и делают одно и то же. На пальцах:
Я знаю, что процессор знает команду O1. Получив ее, он пульнет электричеством во встроенный микродинамик, у того что-то где-то перемкнет и раздастся писк.
И вот я на сишарпе пишу:
using System;
Console.Beep(500,500);
Эта строка у меня превратится в О1
Я пишу на плюсах:
#include <windows.h>
Beep(500,500);
И она тоже превратится в О1.
Я что, должен думать, почему здесь System.Console, а там windows.h? Но мой мозг это запоминает, а таких специфичных деталей дофига, они совсем разные. Рано или поздно деталей становится так много, что мой выбор ЯПа становится не логическим, а просто потому что мне так больше нравится.
На прошлой работе меня заставили писать код с ограничениями, потому что под ним стоял не очень умный транспилятор. Мне рассказывали как давным-давно делали либу на сишарпе, а когда поняли, что упускают прибыль, решили делать еще и на джаве и на плюсах. Но кода к тому моменту было так много, что решили — дешевле будет нанять команду разрабов, которые напишут превращатель сишарпа в джаву и плюсы.
И это сработало. С кучей оговорок и проблем, но они просто автоматически превращали сишарп код в джава код, и пуляли либу клиентам. Все эти убеждения, что «каждый язык решает свою задачу», выбросили на помойку.
И вот сидя над дизайном очередного модуля, я подумал — а что бы сказал старина фон Нейман и его команда, когда услышали о моих проблемах? Те самые парни, которые конструировали свои принципы хранения данных и доказывали идиотам, что двоичная система для машин лучше, чем десятичная.
Они бы не офигели от нашего количества абстракций ради абстракций? Смогли бы принять, что в 2019 все чаще выбирают абстракции чисто эстетически и этим размывают связь с выполнением на машине.
Процессор, компьютер — это очень, очень сложная штука. А мы свели это к простым абстракциям, чтобы думать, что якобы этим управляем. В итоге ни один сегодняшний софтверный инженер не понимает, как устроена машина, но, так как он вроде бы может этим управлять, ему кажется, что машина ему повинуется, и он крутой. Это иллюзия.
Каждый раз, когда очередной стартапер думает «да че там случится с моей нодой, когда я все перевезу с x86 на ARM. Вся эта низкоуровневая фигня меня не касается», мы все дальше и дальше от реального контроля над задачами. Язык общения с машиной стал почти человеческим. Но похоже, это не работает так, как задумано.
Почти любой из распространенных сегодня ЯПов продается, как инструмент решения всех проблем. Но это не работает. Сначала появляется инструмент, который делает жизнь проще при решении какой-нибудь одной маленькой задачи, все начинают его хайпить, создают ему инфраструктуру, делают все, что бы он стал применим везде — и вот у нас очередной чересчур сложный и слишком абстрактный инструмент, который все делает плохо. Кто-то где-то уже пилит новый ему на замену. Чтобы запутать все еще больше.
Один мой друг-гуманитарий (эй, уберите револьверы, мы же все с вами притворяемся, что с гуманитариями можно дружить, я — не исключение) написал рассказ. Заявил мне, что я, как друг, должен его прочитать. Я долго отлынивал. Но он меня достал, и я прочитал. И это оказался один из тех случаев, когда гуманитарные знания улучшили мои навыки разработчика. Смотрите.
Сам рассказ — фантастика. В центре дизайна проблема словесного взаимодействия между людьми. Там весь мир заболел болезнью, когда тебе кажется, что ты говоришь нормально, но окружающие слышат какую-то бессвязную чепуху. Рассказ в итоге об этом — как с помощью языка передавать свое восприятие, и что делать, если языка у тебя нет. Я и раньше думал о том, что между языком программирования и естественными языками можно проводить параллели, но думал, конечно не всерьез. Прочитал и задумался покрепче.
Когда бизнес приносит мне задачу «Эй, Фил, сделай хреновину», что вообще происходит у меня в мозгу? Сколько ступенек интерпретации проходит, пока звуковая волна, отскакивая от моих ушей, превращается в сигналы и пробегает по нейронам мозга куда надо. Я об этом вообще не думаю, это происходит само.
И из-за этой неосознанности, из-за того, что я спокойно отдал мозгу автоматически интерпретировать «услышанное» в «понятое» — появилась куча багов, которые я не контролирую. Вот менеджер три часа объясняет мне бизнес задачу, а я ухожу от него с одной мыслью: «что за буллшит он нес!? Пусть напишет в джире, тогда и сделаю».
Сколько бы он ни говорил, так и не смог скомпилировать в меня свое видение, хотя сам себе в голове он может его донести за секунду.
Потому что в наших мозгах наросла куча абстракций за миллионы лет. Появились одновременно и понимание, и грандиознейшее непонимание, с которым мы ничего не можем сделать.
Языкам программирования еще нет и века, а слой абстракций между моим программированием и реальной работой железяк уже пугающе толстый. И когда я об этом подумал, мне стало тревожно, потому что контроль уходит.
Когда лет через 20 абстракции станут еще на три порядка толще, а ЯПы будут почти человеческими, я уже не буду понимать, как компьютер выполнит мою просьбу, как он ее поймет. Потому что я полностью автоматизирую процесс его понимания.
И когда кто-то напишет очередное «мое разочарование в софте» и будет жаловаться, какое все громоздкое, неправильное и неповоротливое — с этим уже ничего нельзя будет сделать. Стремясь упростить свою жизнь, мы теряем над ней контроль. А это очень плохо.
Но еще больше я боюсь другого. Высокоуровневые ЯПы настолько изменят мое мышление, что мысль «все плохо» просто физически не сможет зародиться в моей голове. Я точно уверен, что естественный язык, на котором я говорю, очень серьезно влияет на мое сознание. Если я русский, то десять поколений моих предков диктуют мне, как я должен думать с помощью языка, который я от них унаследовал. Языка, который устроен, например, так, что в любом предложении о случившейся проблеме — должен быть виноватый. Даже если я говорю «случилась херня» — виновата все равно херня. А, например, в испанском такого нет. Случилось и случилось (и даже сейчас по-русски подразумевается, что случилось «что-то»).
Я проговорил на русском четверть века каждый день — и теперь физически не верю в случайности. Или верю, что мужчины важнее женщин, потому что весь язык завязан на мужском роде. Мою статью перевели на английский, в комменты пришли американцы с просьбами заменить местоимения на гендерно-нейтральные — и я не знаю, что делать со своим возмущением. А у немцев, например, таких проблем нет. Их язык давно гендерно-гибкий. И там все ходят в одну баню, а страной руководит женщина.
Язык управляет мной не меньше, чем я им, и это не тот выбор, который бы делал я сам. Его за меня сделали другие люди. Но естественный язык — штука древняя и неповоротливая, я не могу взять, и надавать по щам его создателям если мне в нем что-то не нравится. И не могу его сменить, по крайней мере легко.
С программированием почти также. Выучил ООП-язык, потом посмотрел на функциональный и сломал себе мозг. ЯП — это не просто инструмент, который тебе служит, а крупная часть твоей жизни, которая во многом определяет твое мышление не только на работе. Потому что на самом глубоком уровне, ЯП влияет не на то, как задача будет сделана, а на то, как ты о ней думаешь. Это не гаечный ключ у тебя в гараже — это кусок твоего сознания.
И чем абстрактнее становится язык, тем сильнее из твоего мышления вымывается его реальная природа — контролировать электричество в железе. Все эти картинки у тебя на мониторе, циферки, библиотеки, анимации — они не настоящие. Настоящее только электричество. Только железо. Я не готов потерять над ним контроль.