История Мела

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

В мои дни вашей IDE был текстовый редактор (от EMACS до Блокнота)… и API (если вы вообще получил один) был документ, в котором перечислялись библиотеки, установленные вместе с приложением, функции в них, какие параметры они принимали (в каком порядке) и какие значения (если они были) возвращались (и их порядок).

Это было оно.

«Вот документ API, вот ваш бриф, вот ваш текстовый редактор, код будет готов через два дня».

В наши дни кажется, что все состоит из чужого фреймворка, содержащего триили более чужих фреймворков, каждый из которых состоит из еще одного три фреймворка от еще других, содержащих чьи-то чужие фреймворки… и scriptkiddies просто #include все, нажимают кнопку [COMPILE] и вуаля, они ' разработал что-то.

Глянь сюда …



Посадите их перед текстовым редактором и попросите написать какой-нибудь собственный код, и (если они вообще поймут, о чем их просят) я совсем не удивлюсь. если они расплакались.

Конечно, я понимаю… зачем изобретать велосипед?

Но проблема в том, что если вы в последнее время обращали внимание, то знаете, что огромное количество фреймворков и библиотек, на которые они бездумно полагаются, пронизаны эксплойтами и даже вредоносными программами (несколько часто упоминаемых библиотек Python имеют например, недавно был в Новостях),

Я не знаю… они просто делают разработчиков такими, какими они были раньше, похоже.

(Я уверен, что мы с Энтони Лоуренсом могли бы хорошенько поворчать о современной молодежи за парой кружек пива 😉)

Фреймворки? Настоящим разработчикам не нужны вонючие фреймворки!

На самом деле на самом деленастоящим разработчикам даже не нужен текстовый редактор!

Это сообщение было отправлено в Usenet его автором, Эдом Натером (‹[email protected]›), 21 мая 1983 года.

[Примечание. за время своего существования оригинал превратился в «свободный стих», который Натер позже заявил, что предпочитает его собственной оригинальной прозе, но я ненавижу его и поэтому переформатировал его в прозаическую форму, насколько это было в моих силах различать логическая структура].

В недавней статье, посвященной мужской стороне программирования, было сделано откровенное и неприкрашенное заявление:

Настоящие программисты пишут на FORTRAN.

Может быть, они и делают это сейчас, в эту декадентскую эпоху пива Lite, ручных калькуляторов и «удобного» программного обеспечения, но в старые добрые времена, когда термин «программное обеспечение» звучал смешно, а настоящие компьютеры были сделаны из барабанов и электронных ламп. , Настоящие Программисты писали машинным кодом.

Не ФОРТРАН. Не РАФОР. Даже не язык ассемблера.

Машинный код.

Сырые, неприкрашенные, непостижимые шестнадцатеричные числа.

Напрямую.

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

Я назову его Мэл, потому что так его звали.

Впервые я встретил Мела, когда пошел работать в Royal McBee Computer Corp., ныне несуществующую дочернюю компанию компании по производству пишущих машинок. Фирма производила LGP-30, небольшой, дешевый (по меркам того времени) компьютер с барабанной памятью, и только что начала производить RPC-4000, значительно улучшенный, больше, лучше, быстрее — барабанную память. компьютер.

Ядра стоили слишком дорого, и в любом случае они никуда не делись.

(Вот почему вы не слышали ни о компании, ни о компьютере.)

Меня наняли написать компилятор FORTRAN для этого нового чуда, и Мел был моим гидом по его чудесам.

Мэл не одобрял компиляторы.

«Если программа не может переписать свой собственный код, — спросил он, — что в ней хорошего?»

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

Он работал на LGP-30 и играл в блэкджек с потенциальными клиентами на компьютерных выставках.

Его эффект всегда был драматическим. Стенд LGP-30 был переполнен на каждой выставке, и продавцы IBM стояли вокруг, переговариваясь друг с другом. Мы никогда не обсуждали, действительно ли это продавало компьютеры.

Работа Мела заключалась в том, чтобы переписать программу блэкджека для RPC-4000.

(Порт? Что это значит?)

Новый компьютер имел схему адресации «один плюс один», при которой каждая машинная инструкция, помимо кода операции и адреса необходимого операнда, имела второй адрес, указывающий, где на вращающемся барабане находится следующая инструкция. располагается.

Говоря современным языком, за каждой отдельной инструкцией следовал GO TO!

Поместите это в трубку Паскаля и выкурите ее.

Мелу нравился RPC-4000, потому что он мог оптимизировать свой код: то есть располагать инструкции на барабане таким образом, чтобы как только одна заканчивала свою работу, следующая поступала к «считывающей головке» и была доступна для немедленного выполнения.

Для этой работы существовала программа, «оптимизирующий ассемблер», но Мэл отказался ее использовать.

«Никогда не знаешь, куда он положит вещи, — объяснил он, — поэтому тебе придется использовать отдельные константы».

Прошло много времени, прежде чем я понял это замечание.

Поскольку Мел знал числовое значение каждого кода операции и присваивал свои собственные адреса барабанов, каждую написанную им инструкцию также можно было считать числовой константой.

Он мог взять более раннюю команду «сложить», скажем, и умножить на нее, если бы она имела правильное числовое значение.

Его код было нелегко изменить кому-то другому.

Я сравнил оптимизированные вручную программы Мэла с тем же кодом, обработанным оптимизирующей программой на ассемблере, и Мэл всегда работал быстрее.

Это произошло потому, что метод проектирования программ «сверху вниз» еще не был изобретен, и Мэл все равно не стал бы его использовать.

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

Мел никогда не писал циклы с временной задержкой, даже когда упрямый Flexowriter требовал задержку между выходными символами для правильной работы.

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

Он придумал незабываемый термин для этой процедуры.

Хотя «оптимальный» является абсолютным термином, как и «уникальный», общепринятой вербальной практикой стало делать его относительным: «не совсем оптимальный», «менее оптимальный» или «не очень оптимальный».

Мэл назвал места с максимальной задержкой по времени «самыми пессимумными».

После того, как он закончил программу блэкджека и запустил ее («даже инициализатор оптимизирован», — с гордостью сказал он), он получил запрос на изменение от отдела продаж.

Программа использовала элегантный (оптимизированный) генератор случайных чисел для перетасовки «карт» и раздачи из «колоды», и некоторые продавцы сочли это слишком честным, поскольку иногда покупатели проигрывали.

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

Мэл возражал.

Он чувствовал, что это явно нечестно, а так оно и было, и что это посягало на его личную неприкосновенность как программиста, что и происходило, поэтому он отказался это делать.

С Мелом разговаривал главный продавец, а также Большой Босс и, по настоянию босса, несколько коллег-программистов.

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

Мэл был в восторге от этого, утверждая, что его подсознание неудержимо этично, и категорически отказывался это исправлять.

После того, как Мэл ушел из компании ради более зеленой травы$, Большой Босс попросил меня взглянуть на код и посмотреть, смогу ли я найти тест и отменить его.

С некоторой неохотой я согласился посмотреть.

Отследить код Мэла было настоящим приключением.

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

Вы можете многое узнать о человеке, просто прочитав его код, даже в шестнадцатеричном формате.

Мэл был, я думаю, невоспетым гением.

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

Здравый смысл подсказывал, что это должен быть замкнутый цикл, в котором программа будет вращаться вечно, бесконечно.

Однако программный контроль прошел прямо через него и благополучно вышел с другой стороны.

Мне потребовалось две недели, чтобы понять это.

Компьютер RPC-4000 имел действительно современное средство, называемое индексным регистром. Это позволяло программисту написать программный цикл, внутри которого использовалась индексированная инструкция; каждый раз число в индексном регистре добавлялось к адресу этой инструкции, чтобы оно относилось к следующему элементу данных в последовательности.

Ему нужно было только увеличивать индексный регистр каждый раз.

Мэл никогда им не пользовался.

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

Затем он выполнял измененную инструкцию прямо из регистра.

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

Но в цикле не было теста.

Жизненно важная подсказка пришла, когда я заметил, что бит индексного регистра, бит, который находился между адресом и кодом операции в слове инструкции, был включен, но Мел никогда не использовал индексный регистр, оставляя его все время равным нулю.

Когда зажегся свет, он чуть не ослепил меня.

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

Перенос добавит единицу к коду операции, изменив ее на следующую в наборе инструкций: инструкцию перехода.

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

Я не поддерживал связь с Мелом, поэтому не знаю, поддался ли он потоку изменений, который захлестнул методы программирования с тех давно минувших дней.

Мне нравится думать, что нет.

Как бы то ни было, я был настолько впечатлен, что перестал искать оскорбительный тест, сказав Большому Боссу, что не могу его найти.

Он не выглядел удивленным.

Когда я уходил из компании, программа для игры в блэкджек продолжала жульничать, если включить правый сенсорный переключатель, и я думаю, что так и должно быть.

Мне было неудобно взламывать код Настоящего Программиста.

[Обновление 1999 года: теперь известна фамилия Мела. В руководстве для LGP-30 упоминается «Мел Кэй из Royal McBee, который выполнил большую часть программирования [...] системы ACT 1».]

[2002: Копия руководства по программированию для LGP-30 находится по адресу http://ed-thelen.org/comp-hist/lgp-30-man.html]

Давайте посмотрим на это более подробно, не так ли?

Я часто чувствовал, что программирование — это вид искусства.

И вот доказательства этому…

Он мог взять более раннюю команду «сложить», скажем, и умножить на нее, если бы она имела правильное числовое значение.

[…]

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

[…]

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

Это просто прекрасно в своем простом прагматизме и прагматичной простоте — и вот тут-то… неразрывная комбинация того и другого… и есть ООП в чистом виде (не говоря уже о реализации, его суть — одна только концепция).

Что касается этого

Перенос добавит единицу к коду операции, изменив ее на следующую в наборе инструкций: инструкцию перехода.

В последний раз я громко смеялся от такой концепции, когда впервые узнал о Redcode Imp в Core War.



Объяснение Imp в статье немного невзрачное.

Фактический код выглядит просто: MOV.I $ 0, $ 1

MOV.I копирует всю инструкцию из A в B. A равно $0 и указывает прямо на чертенка в текущем местоположении. B равен 1 доллару и указывает прямо на следующее место.

Когда имп выполняется, он копирует себя из текущего местоположения в следующее местоположение. Когда выполняется следующая локация, она содержит точную копию чертенка, поэтому процесс повторяется. — https://programminggames.org/Core_War

Это... прямо здесь... суть как ООП, так и рекурсии... единый, автономный оператор, который является собственным операндом... сингулярность кода... совершенная программа — если есть кодовый Бог, Imp является «Он»… альфа и омега, нуждаясь не более чем в себе, чтобы представить все, чем программирование является (а именно, Дорогой компьютер: ваша следующая инструкция — выполнить следующую инструкцию).

Он полностью рекурсивен и достигается с помощью одной инструкции — вещь возвышенной красоты в своей простоте.

И отступить на мгновение…

Поскольку Мел знал числовое значение каждого кода операции и присваивал свои собственные адреса барабанов, каждую написанную им инструкцию также можно было считать числовой константой.

Он мог взять более раннюю команду «сложить», скажем, и умножить на нее, если бы она имела правильное числовое значение.

Много лет назад я наткнулся на язык, названный его разработчиком NNAPL (язык программирования приложений для нейронных сетей).

Это было странно.

В то время (где-то в 1993 году) его функция меня поразила — я просто не мог понять, как это возможно.

Вы дали ему какие-то обучающие данные, и он построил из них нейронную сеть.

Чего ждать?

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

Я знал, как тесно они работали.

Но NNAPL… вы только что ввели команду trainnet ‹файл обучающих данных›… и она построила из нее соответствующую сеть без каких-либо инструкций, создав входной слой, скрытые слои, выходной слой, цель и метод коррекции без вашего участия.

Я даже не уверен, насколько это возможно сегодня, не говоря уже о том, как это было достигнуто тогда.

Однако он делал больше: помимо кажущегося чуда единственной команды, позволяющей построить нейронную сеть из… ну, ничего… на самом деле это был полноценный язык сам по себе, который мог можно использовать для написания любой программы, которую вы пожелаете, точно так же, как и на любом другом языке, таком как C, PASCAL или любом другом.

Дело в том, что… у него был только один встроенный тип данных: INT.

Все остальное, что вы хотели сделать с ним, влекло за собой определение структуры данных с точки зрения ее длины в байтах (не забывая добавить два маркера CR/LF в качестве разделителя переменной). Кроме INT, здесь не было абсолютно никакой печати… и, таким образом, ничто не мешало вам прибавить 144 к четвергу и разделить результат на косинус кота миссис Миггинс.

Потенциал такого языка был захватывающим — что можно было бы сделать с его помощью, чтобы преодолеть ограничения предыдущих парадигм … какие неожиданные функции могли бы быть разработаны, которые облегчили бы манипулирование не только данными, но и концептуальными структурами способами, которые до сих пор даже не представлялись, не говоря уже о возможном? (Потенциально это было намного самопереписывающимся функциям в LISP).

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

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

Но это также было вещью очаровательной простоты и неземной красоты в своем роде.

Я не могу найти никаких записей об этом сегодня, и я не уверен, что у меня есть копия компилятора/интерпретатора на каком-либо из моих старых дисков — хотя я был бы рад обнаружить, что есть ².

Аааааааа... Мел... мастер программирования с побочным эффектом ³... программист-программист, нарушающий правила и злоупотребляющий средствами, отказывающийся подчиняться или быть ограниченным соглашением - тест на граничные условия? Ему не нужны вонючие тесты… он не признает никаких границ (JMP++)!


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

² Мне никогда не не нравился кот.

³ Был очень полезный в 4DOS v4.02.

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

Одной из многих вещей, которые могла делать 4DOS и не могла command.com, было выполнение встроенных команд в приглашении.

Итак, я выполнял эту внутреннюю команду внутри подсказки, игнорировал результат (который меня не интересовал), брал побочный эффект из регистра и выводил значение в подсказку, а затем саму команду $command. Таким образом, я всегда знал, где я был, когда отдал предыдущую команду, и что это было, даже если я сейчас находился в совершенно другом каталоге, а свидетельство команды было стерто из Истории — что было приятно.

Я также получил массу удовольствия, заменив народный command.com на переименованную версию 4DOS.com, которую я модифицировал так, чтобы она вел себя как ELIZA Вайценбаума, (роджерианский ненаправленный) терапевт. моделирование .

Он отлично работал для большинства вещей… вел себя совершенно нормально.

Но если вы пытались удалить файлы, это не ограничивалось вопросом «Вы уверены?» Если вы сказали «Да», он ответил: «Вы ДЕЙСТВИТЕЛЬНО уверены?» Если вы снова ответили «Да», он ответил «Расскажите мне больше о своих файлах» и некоторое время приводил вас в веселый танец, прежде чем, наконец, согласился удалить их / их.

Вы больше не можете этого делать — *вздох* компьютеры уже не так интересны, как раньше.

⁴ Так много файлов
Должно быть, они были важны —
но теперь их нет.

https://ru.m.wikipedia.org/wiki/ELIZA