Программисты сегодня…
…толком и не знают где заканчивается язык программирования и начинается фреймворк.
Что я под этим имею в виду?
Примерно до 1988-ого года большинство программ, которые могли бы использовать люди, были написаны с нуля с помощью программистов (зачастую всего лишь одним) используя 3GL (язык программирования третьего поколения). Ключевое слово с нуля.
Как я объяснял в первой статье этой серии, 3GL — это абстрактная сборка или машинный язык в зарезервированных словах.¹ Язык программирования — это коллекция зарезервированных слов и некоторых правил грамматики, которые ограничивают использование этих слов таким образом, чтобы не путать компилятор (который развёртывает эти слова в серию команд на машинном языке). Всё вместе это называется синтаксис языка.
Как вы видите некоторые языки имеют на удивление мало зарезервированных слов для запоминания. В SmallTalk всего лишь 6!
Вернёмся к программному обеспечению до 1988-ого. Если вы посмотрите на программы написанные до этого времени, то увидите, что единственные слова помимо зарезервированных — это названия переменных и функций, которые создали программисты.
Код для сжатия изображений (который написан на С) использует только два зарезервированных слова: for и double. Два подчёркнутых слова (fabs иprintf) — это функции из подключенных библиотек (stdio.h и math.h). Когда библиотека подключена таким образом это называют зависимостью. Все остальные слова в этой программе или переменные, или комментарии написанные программистом.
Простым подсчётом слов получается, что 90% кода написано программистом. Меньше 10% кода уже было написано кем-то. 4% из другого языка и 6% из двух библиотек.
for(x=0; x < im1->width; x++) { for(y=0; y < im1->width; y++) { totalDiff += fabs( GET_PIXEL(im1, x, y)[RED_C] - GET_PIXEL(im2, x, y)[RED_C] ) / 255.0; totalDiff += fabs( GET_PIXEL(im1, x, y)[GREEN_C] - GET_PIXEL(im2, x, y)[GREEN_C] ) / 255.0; totalDiff += fabs( GET_PIXEL(im1, x, y)[BLUE_C] - GET_PIXEL(im2, x, y)[BLUE_C] ) / 255.0; } } printf("%lf\n", 100.0 * totalDiff / (double)(im1->width * im1->height * 3) );
А теперь давайте посмотрим на Java-версию этой функции:
public enum ImgDiffPercent { ; public static void main(String[] args) throws IOException { // https://rosettacode.org/mw/images/3/3c/Lenna50.jpg // https://rosettacode.org/mw/images/b/b6/Lenna100.jpg BufferedImage img1 = ImageIO.read(new File("Lenna50.jpg")); BufferedImage img2 = ImageIO.read(new File("Lenna100.jpg")); double p = getDifferencePercent(img1, img2); System.out.println("diff percent: " + p); } private static double getDifferencePercent(BufferedImage img1, BufferedImage img2) { int width = img1.getWidth(); int height = img1.getHeight(); int width2 = img2.getWidth(); int height2 = img2.getHeight(); if (width != width2 || height != height2) { throw new IllegalArgumentException(String.format("Images must have the same dimensions: (%d,%d) vs. (%d,%d)", width, height, width2, height2)); } long diff = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y)); } } long maxDiff = 3L * 255 * width * height; return 100.0 * diff / maxDiff; } private static int pixelDiff(int rgb1, int rgb2) { int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2); } }
Всё, что выделено жирным — это ключевые слова, а всё подчёркнутое — это слова из импортированных библиотек. 65% этого кода написано программистом, 20% кода из синтаксиса и 15% зависимости от внешних библиотек.
Я не говорю, что это плохая вещь. Я просто указываю на этот факт. Как выясняется, подключение кода из библиотек — это отличный способ увеличить продуктивность. Нет никакого смысла для обычного программиста заново создавать базовые инструменты программирования: зарезервированные слова, библиотечные классы и функции. Таким образом, в современном программирования развивается тенденция всё меньше полагаться на свой код и всё больше на уже написанные чужие решения в виде готовых библиотек. Несмотря на то, что само по себе это неплохо, многие согласятся, что это зашло слишком далеко.
И магия случается…
В начале 2016-ого произошло то, что по ощущениям сломало половину интернета. Один программист удалил из публичного репозитория npm 11-строчную программу left-pad. Оказалось, что некоторые из самых больших и используемых в мире JavaScript-фреймворков чаще включали в себя зависимость от left-pad вместо того, чтобы записать следующие 10 строк кода:
function leftpad (str, len, ch) { str = String(str); var i = -1; if (!ch && ch !== 0) ch = ' '; len = len - str.length; while (++i < len) { str = ch + str; } return str; }
Другой npm-пакет, который назывался isArray имел 18 миллионов скачиваний в феврале 2016-ого года и является зависимостью для 72 других npm-пакетов. 18 миллионов программистов и 72 автора пакетов скорее используют зависимость, чем напишут следующую строчку кода:
return
toString.call(arr) == '[object Array]';
Может быть я чего-то не понимаю, но для меня это совершенно ясно показывает, что программисты, которые создали 72 пакета для npm, имеют самое ужасное чувство юмора, которое я только видел. Или же понятия не имеют о том, что было в isArray и как на самом деле работает JavaScript. Я взял это как самый выдающийся пример карго-культного программирования.
Чтобы ещё больше донести мысль, что большинство современных программистов слепо используют библиотеки классов без понимания их содержимого, я отошлю вас к отрезвляющему и удручающему аккаунтуJordan Scales и его личной реакции на фиаско с left-pad.
Убирайся с моей лужайки
Так к чему же я всё это веду?
Моё мнение, что “программирование”, которым его представляет среднестатистический человек, сегодня едва ли существует. Программисты, которые “пишут код” в виде новых алгоритмов, работают или в очень больших компаниях, или пишут программное обеспечение для обработки видео, картинок или звуков в стартапах.
Армии “детей сегодня”, которые работают в соляных шахтах корпоративных или государственных IT, делают что-то совсем иное. Программы, которые они делают, являются программным эквивалентом для создания мемов и социально-медийных постов, включающих в себя пост-модерновые популярные культурные отсылки. Только вместо того, чтобы перерабатывать картинки с Клинтом Иствудом, хорошим парнем Грегом и мудаком Стивом, они вырезают и вставляют код, а также без разбора используют такие библиотеки, как left-pad или isArray. Они действительно не понимают, где заканчивается язык программирования и начинается фреймворк. Для них это всё одна каша.
И несмотря на то, что я не “ребёнок”, я едва ли лучше себя чувствую. Я нахожу себя таким же карго-культным программистом (неохотно, но честно).
Перевод статьи Adam Zachary Wasserman: Framework or language?