Редактирование программ "во время их работы"? Зачем?


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

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

возможно, я что-то упускаю, но какой в этом смысл?

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

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

может кто-нибудь дать мне хороший пример, который заставит меня слюни за эту функцию? :)

с нетерпением жду слюни!

13 64

13 ответов:

есть некоторые чрезвычайно интересные случаи использования. Одним из примеров является программирование GUI-я видел это при разработке приложения GUI в режиме реального времени, когда оно работало рядом с моим Emacs: я добавил код для новой кнопки и нажал "C-c C-c", чтобы скомпилировать эту единственную функцию, а кнопка просто в окне! Не пришлось закрывать и снова открывать приложение. Затем я начал настраивать виджеты и манипулировать макетом, и открытое окно мгновенно перестраивалось - кнопки перемещались, новые текстовые поля будут просто появляться и т. д. как только я выполнял каждое маленькое изменение, которое я сделал.

еще один пример-отличный скринкаст о библиотеке Clojure OpenGL "Penumbra", где программист создает 3D-игру tetris в режиме реального времени. Он начинает с пустого окна OpenGL рядом с его emacs. Он определяет объект Куба-C-M - x-и это на экране. Запускает команду, чтобы повернуть его, сразу же он начинает вращаться. Запускает цикл, определяющий еще 5 кубов в разных местах, поп-поп-поп-поп они появляются. Это все сразу реагирует, полный инструментарий OpenGL прямо там, чтобы играть. Добавьте новую текстуру поверхности в свой куб и сразу же увидите ее. Он становится податливым 3d-миром-код динамически изменяет существующий мир вместо закрытия и повторного открытия 3D-холста с каждым изменением.

Penumbra Livecoding Screencast - скачать HD версию для лучшего опыта.

существует также большой презентация / скринкаст об аудиотеке "обертон" для Clojure. Библиотека представляет собой набор инструментов синтезатора, где у вас есть набор функций синтезатора для управления звуковой волной. Во время презентации разработчик пишет немного кода, который запускает воспроизведение тона. Затем он тратит десять секунд на запись цикла, который воспроизводит этот звук 10 раз, но каждый раз делает частоту выше, и снова C-M-x, и вы слышите его, ноты поднимаются выше. В течение 20 минут в режиме реального времени он получает песню идущий. Это выглядит как тонна удовольствия.

Обертон Презентация Ссылка

другие виды использования будут, например: веб-сканирование / интеллектуальный анализ данных-разработка и уточнение алгоритмов извлечения информации в режиме реального времени, видя данные, возвращаемые на каждом шаге; Программирование робототехники-отправка команд роботу, пока он живет; распознавание лиц/изображений - с библиотекой, такой как OpenCV, наблюдайте за своими изменениями мгновенно обновляйте то, что библиотека распознает в изображении / видео, когда вы разработка кода; математическая работа (Clojure имеет "Incanter" для статистики); и любая среда, в которой вы хотите сразу увидеть, какое влияние ваши изменения оказали на данные, с которыми вы работаете.

Так что это самый забавный аспект наличия REPL перед вами. Вещи, которые не были осязаемыми, податливыми, интерактивными, начинают быть. Графический интерфейс, 3D-графика, программное производство звука, извлечение и преобразование данных, эти вещи обычно делались на расстоянии вытянутой руки. Но с Clojure (и в некоторой степени с другими динамическими языками тоже) это сделано, чтобы быть действительно ощутимым и немедленным; вы видите каждое изменение, как только вы пишете код, и если что-то не работает или вы не получаете назад результат, который вы ожидали, вы просто измените то, что вы пропустили, и немедленно выполните его.

Clojure очень ориентирован на это. Самое дикое, что вы можете использовать библиотеки Java в режиме реального времени таким же образом-несмотря на то, что сама Java не может! Так что обертон есть использование библиотеки синтезаторов Java в реальном времени несмотря на то, что вы никогда не могли в Java, Penumbra использует привязки Java OpenGL и т. д. Это связано с тем, что Rich Hickey разработал Clojure, чтобы он мог компилироваться в байт-код JVM на лету. Это удивительный язык - язык Clojure внес огромный вклад в то, как невероятно весело и продуктивно программировать можно.

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

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

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

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

вот инструмент, который дает мне более чем 100-кратное ускорение одной из самых медленных и наиболее распространенных вещей, которые я делаю как программист. Я не знаю, что еще тебе нужно. Мы можем, вероятно, сделать некоторые причины, но если это не достаточная причина, я не знаю, что будет. Эм, это тоже довольно круто? : -)

существует маркетинговый слоган для Lisp:

С Lisp и его методом инкрементной разработки стоимость изменения в программной системе зависит от размера изменения, а не от размера всего программного обеспечения.

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

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

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

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

в системе Lisp вы меняете класс в системе CAD, а затем он может быть немедленно активен. Когда люди спрашивают, работает ли Lisp для больших команд программного обеспечения, ответ может заключаться в том, что большая команда программного обеспечения не нужна, если вы работаете постепенно. Этот проблема тогда была/это действительно хорошие опытные разработчики программного обеспечения, знакомые с инкрементной разработкой были (есть?) редкий.

во многих приложениях есть отдельный скриптовый язык слой, иногда для оригинальных разработчиков (а не для пользователей). В Lisp это не обязательно,Lisp - это собственный язык расширения.

в реальном мире это в основном используется в разработке и, как и многие функции, его стоит только слюни в правильном контексте.

  1. личный программист просветление блаженство*
  2. истинное непрерывное развертывание.
  3. нулевые запланированные соглашения об уровне обслуживания простоев.
  4. отладка производственных серверов.

*не гарантия.


для меня, и я подозреваю, что некоторые другие здесь реальная польза от этого REPL driven development может быть непередаваемо весело. привыкание даже. Иногда это может действительно дать ощущение крафта-кода. дайте ему попробовать... давай, чувак, попробуй, первый РЕПЛ всегда свободен. :)


одна большая ничья в эти дни непрерывного развертывания.

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

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


еще слюни моментом является идея получения bennefit из исправления безопасности без необходимости объявлять любое время простоя. вы можете сделать обновление без того, чтобы оно стоило вашему SLA любого из вас драгоценного "запланированного простоя". Если вам нужно запланировать запланированный простой на шесть месяцев вперед, и вы получите только два часа, то (для этих бедных душ) это действительно может сделать они пускают слюни.
Если у вас есть доступ repl к запущенному приложению по мере его развертывания (потенциально (с разрешением) на сайте клиента), вы можете подключиться к приложению во время его работы и выполнить тесты на существующем коде в существующем контексте без необходимости останавливать и подключать отладчик. вы также не получите никаких потерь скорости от отладчика. Это можно сделать без REPL, хотя, когда вы получите repl там, вы можете легко создать новый код (некоторые скажут что инъекции динамических загрузчиков классов через отладчик легко), а затем исправить ситуацию. Таким образом, вы можете подключиться к работающему серверу. обнаружьте, что функция не смогла повторно подключиться к базе данных после короткого простоя, а затем снова подключить ее прямо там и тогда.


как и во всех конструкциях программирования там никогда не будет "серебряной пулей" и это постоянное развертывание / развитие имеет интересный недостаток: ваша программа может быть правильной в памяти и неправильной на диск. если вы компилируете функцию, а затем разбиваете ее и сохраняете, то единственной рабочей копией кода является запущенная. Мне не полезно знать об этом и повторно оценивать файлы сразу после их сохранения.
Это может показаться причудливым, так что идите проверить, как встроить Clojure REPL в ваше производственное приложение

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

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

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

Если вы посмотрите на что-то вроде Erlang, смысл в том, чтобы избежать времени простоя.

Он работает на таких вещах, как телефонные коммутаторы, которые вы не можете просто отключить на несколько секунд.

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

вы видите реальные данные. Это большое преимущество. Тогда вам не нужно размышлять.

потому что ты можешь?

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

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

Это в основном для развития, где это просто экономия времени.

но экономия времени ошеломляюще важна.

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

в промышленных системах это использовано для программирования ПЛК для того чтобы разрешить время простоя и небезопасные условия.

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

Это похоже на ответ Erlang для систем телефонных коммутаторов.

ну, представьте, что вам нужно исправить сервер и не остановить его.

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

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

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

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

Кейси Муратори просто сделал несколько уроков о том, как это сделать с C и компилятором C/C++ от Microsoft. Это на самом деле довольно просто, всего несколько десятков строк кода. Проверьте видео 22/24/25:

https://www.youtube.com/watch?v=WMSBRk5WG58

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