Emacs, пространства имен и определения функций - PullRequest
8 голосов
/ 10 декабря 2010

Единственное, что мне не нравится в Emacs - это отсутствие пространств имен, поэтому мне интересно, смогу ли я реализовать их самостоятельно.

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

Кроме того, почему мои функции не могут определить функцию? Нужно ли запускать что-то похожее на intern-symbol на каждом новом токене?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 04 ноября 2012

Так как это первый результат Google для elisp namespaces ...

Существует минималистичная реализация пространств имен, называемая fakespace , которую вы можете получить в elpa, которая выполняет базовую инкапсуляцию. Я сам работаю над чем-то амбициозным, что вы можете проверить здесь .

3 голосов
/ 07 ноября 2012

Чтобы обрабатывать такие вещи, как my-let или my-defun, вам необходимо макрорасширить эти определения, например, с помощью macroexpand-all.

. Если не удается определить функции, вам нужно использовать internиз make-symbol (потому что make-symbol всегда создает новый новый свежий непереданный символ).

1 голос
/ 12 декабря 2010

Добавление пространств имен займет больше, чем префикс идентификаторов с именами пространств имен.Переводчик должен уметь определять пространства имен.Немного повозится и с переводчиком.Это может потребовать подробного обсуждения на gnu.emacs.sources и / или #emacs на irc.freenode.org.

0 голосов
/ 06 февраля 2013

Это исправленная версия кода от @ vpit3833 для поддержки пространства имен (с помощью подсказки от @Stefan). Это слишком хорошо, чтобы оставить около половины исправлено:)

;; Simple namespace definitions for easier elisp writing and clean
;; access from outside. Pythonesque elisp :)
;; 
;; thanks to vpit3833 → http://6e5e5ae9206fa093.paste.se/

(defmacro namespace (prefix &rest sexps)
  (let* ((naive-dfs-map
          (lambda (fun tree)
            (mapcar (lambda (n) (if (listp n) (funcall naive-dfs-map fun n)
                                  (funcall fun n))) tree)))
         (to-rewrite (loop for sexp in sexps
                           when (member (car sexp)
                                        '(defvar defmacro defun))
                           collect (cadr sexp)))
         (fixed-sexps (funcall naive-dfs-map
                               (lambda (n) (if (member n to-rewrite)
                                               (intern
                                                (format "%s-%s" prefix n)) n))
                               sexps)))
    `(progn ,@fixed-sexps)))

;; (namespace test
;;            (defun three () 3)
;;            (defun four () (let ((three 4)) three))
;;            (defun + (&rest args) (apply #'- args)))

;; (test-+ 1 2 3)

(provide 'namespace)
...