REPL
REPL (Read-eval-print loop — цикл читання-обчислення-друку, мовна оболонка) — просте інтерактивне середовище програмування для комп’ютера, яке приймає однокористувацькі введення, виконує їх і повертає результат користувачеві; програма, написана в середовищі REPL, виконується поштучно. Цей термін зазвичай вживається стосовно інтерактивного середовища мови програмування Lisp, але може застосовуватись і до інтерактивних середовищ мов Smalltalk, Python, Ruby, Haskell, JavaScript та ін.
В такому середовищі користувач може вводити вирази, які середовище одразу обчислить, а результат обчислень відобразить користувачеві. Назва read-eval-print loop походить від імен примітивів мови Lisp, що реалізують таку функціональність:
- Функція read читає один вираз і перетворює його в відповідну структуру даних у пам'яті. Наприклад, користувач може ввести S-вираз
(+ 1 2 3)
, який аналізується у зв'язаному списку, що містить чотири елементи даних. - Функція eval (evaluate) приймає цю внутрішню структуру даних і обчислює вираз, що відповідає їй. У Lisp обчислення S-виразу, що починається з імені функції, означає виклик цієї функції з аргументами, що складають решту виразу. Отже, функція
+
викликається з аргументами1 2 3
, що дає результат6
. - Функція print приймає результат обчислення виразу, отриманий від eval, і друкує його користувачеві. Якщо це складний вираз, він може бути форматованим, щоб його було легше зрозуміти.
Потім середовище розробки повертається до стану читання, створюючи цикл, який завершується, коли програма закрита.
REPL полегшує дослідницьке програмування та налагодження, оскільки програміст може перевірити результат, перш ніж вирішити, який вираз надати для наступної перевірки. Цикл read–eval–print залучає програміста частіше, ніж класичний цикл edit-compile-run-debug.
Оскільки функція print
виводиться в тому самому текстовому форматі, що функція read
використовує для введення, більшість результатів друкується у формі, яку можна скопіювати та вставити назад у REPL. Однак іноді доводиться друкувати нечитабельні об’єкти, такі як дескриптор сокета або складний екземпляр класу. У цих випадках повинен існувати спеціальний синтаксис. У Python це позначення <__module__.class instance>
, а в Common Lisp - #<whatever>
.
REPL можна створити для підтримки будь-якої текстової мови. Підтримка REPL для скомпільованих мов зазвичай досягається впровадженням інтерпретатора поверх віртуальної машини, який забезпечує інтерфейс для компілятора. Наприклад, починаючи з JDK 9, Java включала JShell як інтерфейс командного рядка до мови. Інші мови мають для завантаження сторонні інструменти, які забезпечують подібну взаємодію оболонки з мовою.
Як оболонка, середовище REPL дозволяє користувачам отримувати доступ до відповідних функцій операційної системи на додаток до надання можливостей програмування. Найбільш поширене використання REPL за межами оболонок операційної системи - для миттєвого прототипування. Інші сфери використання включають математичний розрахунок, створення документів, що включають науковий аналіз (наприклад, IPython), інтерактивне обслуговування програмного забезпечення, порівняльний аналіз та дослідження алгоритмів.
Мінімальне визначення:
(define (REPL env)
(print (eval env (read)))
(REPL env) )
Де env
являє собою початкове eval
-uation середовище. Також передбачається, що eval
може деструктивно оновити env
.
Типова функціональність, надана Lisp REPL, включає:
- Історію вхідних та вихідних даних.
- Змінні встановлюються для вхідних виразів та результатів. Ці змінні також доступні в REPL. Наприклад, у Common Lisp * посилається на останній результат, ** і *** на попередні результати.
- Рівні REPL. У багатьох системах Lisp, якщо під час зчитування, обчислення або друку виразу виникає помилка, система не повертається на верхній рівень із повідомленням про помилку. Натомість у контексті помилки запускається новий REPL, на один рівень глибше. Потім користувач може перевірити проблему, виправити її та продовжити - якщо це можливо. Якщо в такому налагоджувальному REPL виникає помилка, запускається інший REPL, знову на глибший рівень. Часто REPL пропонує спеціальні команди налагодження.
- Обробка винятків. REPL забезпечує перезапуск. Ці перезапуски можна використовувати, коли виникає помилка, для повернення до певного рівня REPL.
- Введення та виведення об'єктів даних за допомогою миші.
- Редагування введення та специфіка контексту перед символами, іменами шляхів, іменами класів та іншими об'єктами.
- Довідка та документація для команд.
- Змінні для управління зчитувачем. Наприклад, змінна *read-base* керує тим, що базові числа читаються за замовчуванням.
- Змінні для управління принтером. Приклад: максимальна довжина або максимальна глибина виразів для друку.
- Додатковий синтаксис команди. Деякі REPL мають команди, які слідують не синтаксису s-виразу, але часто працюють з даними Lisp як аргументами.
- Графічні REPL. Деякі REPL Lisp (приклад прослуховувач CLIM) також приймають графічні вхідні та вихідні дані.
- Опис реалізації REPL [Архівовано 30 січня 2021 у Wayback Machine.] у Common Lisp (Paul Graham).
- c-repl [Архівовано 11 лютого 2009 у Wayback Machine.] REPL для мови C
- [1] [Архівовано 26 вересня 2010 у Wayback Machine.] REPL для мови JavaScript