Фон
Я написал взлом для Emacs, который позволяет мне отправить форму Clojure из буфера редактора в буфер REPL. Он работает нормально, за исключением того, что если два буфера находятся в разных пространствах имен, скопированный текст обычно не имеет смысла или, что еще хуже, он может иметь смысл, но имеет другое значение в буфере редактора.Могу ли я преобразовать форму Clojure из одного пакета в другой?
Я хочу преобразовать текст так, чтобы он имел смысл в буфере REPL.
раствора в Common Lisp
В Common Lisp, я мог бы сделать это с помощью следующей функции:
;; Common Lisp
(defun translate-text-between-packages (text from-package to-package)
(let* ((*package* from-package)
(form (read-from-string text))
(*package* to-package))
(with-output-to-string (*standard-output*)
(pprint form))))
И применение образца:
;; Common Lisp
(make-package 'editor-package)
(make-package 'repl-package)
(defvar repl-package::a)
(translate-text-between-packages "(+ repl-package::a b)"
(find-package 'editor-package)
(find-package 'repl-package))
;; => "(+ A EDITOR-PACKAGE::B)"
имя пакета квалификации в строка ввода и строка вывода различны - именно то, что необходимо для решения проблемы копирования и вставки текста между пакетами.
(BTW, есть информация о том, как запустить код перевода в общем процессе Lisp и переместить материал между миром Emacs и общим словом Lisp, но я в порядке с этим, и я не особо хочу получить в это здесь)
A Non-Solution в Clojure
Вот прямая трансляция в Clojure:.
;; Clojure
(defn translate-text-between-namespaces [text from-ns to-ns]
(let [*ns* from-ns
form (read-string text)
*ns* to-ns]
(with-out-str
(clojure.pprint/pprint form))))
И пример использования:
;; Clojure
(create-ns 'editor-ns)
(create-ns 'repl-ns)
(translate-text-between-namespaces "(+ repl-ns/a b)"
(find-ns 'editor-ns)
(find-ns 'repl-ns))
;; => "(+ repl-ns/a b)"
Таким образом, функция перевода в Clojure ничего не сделала. Это потому, что символы и пакеты/пространства имен в Common Lisp и Clojure работают по-разному.
В общих символах Лиспа относятся к пакету, и определение пакета символа происходит во время чтения.
В Clojure по уважительным причинам символы не принадлежат пространству имен, а определение пространства имен символов происходит во время оценки.
Возможно ли это сделать в Clojure?
Итак, наконец, мой вопрос: можно ли преобразовать код Clojure из одного пространства имен в другое?
Вы просмотрели https://github.com/clojure/tools.reader? – sw1nn
@ sw1nn: Я только что быстро посмотрел. Я не думаю, что там что-то может помочь - ничего о пространствах имен. Это касается разрешения символов, я думаю, что происходит во время оценки, а не для чтения времени. –
Am путать. Почему бы не оценить форму на месте - такие инструменты, как nrepl, сделают это в правильном пространстве имен, так что все работает. Какие результаты вы пытаетесь достичь? Если вам нужен интерактивный реплика, то перемещение текущего REPL в пространство имен текущего буфера также очень просто. –