Возможен ли сброс пользовательского окружения в схеме REPL?

Схема вопроса новичку-

Есть ли способ сбросить текущую среду REPL (т.е. среду пользователя по умолчанию) без выхода и перезапуска REPL? По сути, мне нужен способ уничтожить мою текущую среду, чтобы ни одно из моих предыдущих определений не действовало. Это использует схему GNU / MIT.

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

Я нашел информацию о том, как это сделать в Clojure REPL, но были оговорки, и похоже, что это специфично для Clojure: Можно почистить ответ?

Спасибо!

Изменить: я могу функционально выполнить то же самое, выйдя и перезапустив сам процесс REPL. Я нашел способ сделать это, но сохранил соединение с моим редактором (vim) с помощью vim-screen. Это приемлемое решение, если нет возможности сделать это из REPL. Однако я оставлю вопрос открытым еще немного, чтобы посмотреть, есть ли способ сделать это внутри языка, поскольку я думаю, что это будет поучительно.


person Eliot    schedule 16.08.2011    source источник
comment
Сработает ли для вас просто остановить REPL и запустить его снова?   -  person compman    schedule 18.08.2011
comment
Да, но я предпочитаю решение, приведенное ниже, поскольку я могу сохранить это выражение в своем текстовом буфере и отправить его в REPL, не выходя из редактора, тогда как перезапуск REPL требует, чтобы я фактически переключил фокус на его окно, запустил команду выхода и затем вызовите новый REPL, который займет больше времени.   -  person Eliot    schedule 19.08.2011


Ответы (1)


Я думаю, что это зависит от конкретной реализации, но в схеме MIT вы можете очистить среду REPL с помощью:

1 ]=> (ge (make-top-level-environment))

Функция (ge [environment]) «Изменяет текущую среду цикла REP на [среду]». а функция make-top-level-environment «возвращает вновь выделенную среду верхнего уровня».

Схема MIT имеет набор функций управления средой, которые вы можете просмотреть здесь

Я тестировал это на Mac OS X (10.6.7) со схемой MIT 9.0.1, установленной через предварительно созданный двоичный файл с сайта GNU, со следующим сеансом REPL:

1 ]=> (define foo 1)

;Value: foo

1 ]=> foo

;Value: 1

1 ]=> (ge (make-top-level-environment))

;Value 13: #[environment 13]

1 ]=> foo

;Unbound variable: foo
;To continue, call RESTART with an option number:
; (RESTART 3) => Specify a value to use instead of foo.
; (RESTART 2) => Define foo to a given value.
; (RESTART 1) => Return to read-eval-print level 1.

2 error> 

Я думаю, что разные реализации имеют разные соглашения, но я не думаю, что есть что-то похожее на пакеты Common Lisp. Если вы не связаны со схемой MIT, вам следует попробовать Racket и Dr Racket, это хорошая IDE, которая может быть более мощной, чем простой REPL в командной строке, и я думаю, что у нее есть какая-то модульная система. Racket - это отдельный диалект Scheme, поэтому в зависимости от того, что вы делаете, он может быть неуместным. (языковой модуль по умолчанию в Racket отличается от MIT Scheme)

Я боролся со всем этим недавно (последние несколько месяцев), когда я искал схему, которая могла бы запускать код из Lisp в Small Pieces, который имеет кучу странных макросов. Гамбит оказался лучшим выбором. Если вам это не нужно, попробуйте Racket.

person michiakig    schedule 16.08.2011
comment
Я уже читал эту документацию раньше, и мне все еще было непонятно, как выполнить то, что я пытаюсь сделать. Вышеупомянутая процедура, похоже, работает, но работает только один раз и может иметь некоторые опасные побочные эффекты. Что он делает, так это переключает текущую среду на системную глобальную среду. После этого все мои определения вступают в силу в глобальной среде. Вдобавок REPL теперь находится в более опасном режиме, поскольку я могу переопределить стандартные процедуры во всем мире. Я бы хотел создать совершенно новую среду, которая является дочерней по отношению к system-global-environment, а затем переключиться на нее. - person Eliot; 16.08.2011
comment
Я использую схему MIT, потому что я следую за классом MIT OpenCourseware 6.001 ocw.mit.edu/courses/electrical-engineering-and-computer-science/ и это Лисп диалект, используемый в тексте и текущими студентами курса. Racket выглядит интересно ... могу ли я рассматривать его как эквивалент MIT-Scheme и игнорировать другие функции, пока они мне не понадобятся позже? - person Eliot; 16.08.2011
comment
Существует пакет SICP Racket, но вы также можете увидеть, что другие люди предлагали SO относительно этой конкретной комбинации, которая появлялась раньше: google.com/ - person michiakig; 17.08.2011
comment
Я не совсем понимаю, что вы имеете в виду под опасными побочными эффектами, вы можете привести пример? Я могу переопределить car, cdr и т. Д. На верхнем уровне свежего REPL, не испортив окружение. - person michiakig; 17.08.2011
comment
Вы также можете попробовать (ge (make-top-level-environment)), но я не знаю, в чем разница. - person michiakig; 17.08.2011
comment
Я думаю, что переключение на глобальную среду позволяет обойти это: хотя все привязки в system-global-environment видны циклу REP, определения, которые вводятся или загружаются в цикле REP, происходят в среде user-initial-environment. Отчасти это мера безопасности: если вы вводите определение, которое имеет то же имя, что и критическая системная процедура, ваше определение будет видимым только для процедур, которые вы определяете в среде user-initial-environment; системные процедуры схемы MIT / GNU, которые определены в system-global-environment, по-прежнему будут иметь исходное определение. - person Eliot; 17.08.2011
comment
(ge (make-top-level-environment)) похоже, то, что я искал. Он создает новую среду в системной среде, а затем переключается на нее! Все мои предыдущие определения больше не действуют в этой новой среде, и я могу использовать их неоднократно. Не стесняйтесь опубликовать это как новый ответ или добавить в свой текущий ответ, и я его приму! Разница в том, что (ge system-global-environment) переключается на глобальную среду системы, поэтому определения там вступают в силу во всех процедурах, и вы не можете запустить эту команду снова, чтобы сбросить свои определения, она работает только один раз. - person Eliot; 17.08.2011