2010-12-10 10 views
8

Emacs hakkında sevmediğim tek şey isim alanlarının eksikliğidir, bu yüzden onları kendi başıma uygulayıp uygulayamayacağımı merak ediyorum.Emacs, namespaces ve defuns

This benim ilk denememdir, ve öntanımlı bir sürümü olan bir adın her eşlemesini değiştiremediğim açıktır, ancak ne kontrol etmeliyim? Tüm alt ağacı işaretleyin (izin ver) ile bağlayıcıları kontrol edebilirim, ama ne olursa olsun kullanan bir (my-let) işlevi oluşturursa? Çabalarım başarısız olmaya mahkum mu? :(

Ayrıca

, neden benim defuns işlevini tanımlamak için başarısız oluyor? Her yeni belirteci üzerinde stajyer-sembole benzer bir şey çalıştırmak zorunda mıyım?

teşekkürler!

+1

Emacs olan bir metin düzenleyicisinde ad boşluklarıyla ne kastediyorsunuz? Yoksa aslında atıfta bulunulan dil elisp mi? – vpit3833

+5

Elisp'in isim alanlarından yoksun olduğu ve bazı elisp kodlarına ilişkin soruların ve elisp formları ve 'let', 'defun' ve 'intern-symbol' gibi işlevler hakkında soru sorduğu göz önüne alındığında, bu sorunun elisp ile ilgili olduğunu kabul etmenin güvenli olduğunu düşünüyorum. . – Porculus

+0

@ vpit3833: Bu oldukça hoş görünüyor! –

cevap

1

ekleme ad daha alacak Tanımlayıcıların ad alan adları ile ön eklenmesi Tercümanların ad alanlarını anlatabilmeleri gerekir.Konuşmanın bir kısmı da yorumlayıcıya gitmelidir.Onun gnu.emacs.sources ve/veya #emacs adresinden kapsamlı bir tartışmaya girmesi gerekebilir.

+1

Hayır, bir makro kullanır ve yorumlayıcı derleyicinin yanı sıra makroları da genişletir, böylece yaklaşımı kesinlikle işe yarayabilir. – Stefan

5

Bu ilk 0 sonuçtan beri, elisp namespaces ...

Temel kapsülleme olan elpa'da alabileceğiniz fakespace ad alanlarının minimalist bir uygulaması vardır. Ben kendimi iddialı bir şey üzerinde çalışıyorum, here kontrol edebilirsiniz.

+0

Harika görünüyor! – konr

+0

Hem sahte uzay hem de ad alanlarınız kapsam belirleme yerine, yan etkilere dayanır. Bu bakış açısından vpit3833'ün yaklaşımını çok tercih ediyorum. – Stefan

+0

Evet, yan etkilerle _very_ funky alıyorum. Ama ben görüşlü bir pozisyondan geliyorum: Esmer'e bir miktar değişmezlik yapıp, paket yazarlarının kendi kamusal arayüzlerini açık bir şekilde belgelemelerini sağlamaya çalışıyorum. –

3

my-let veya my-defun gibi şeyleri işlemek için, bu tanımları makro olarak çoğaltmanız gerekir, ör. macroexpand-all ile. işlevleri tanımlamak için başarısızlık için

, siz ( make-symbol her zaman yeni bir ayrı taze uninterned işareti oluşturuyor çünkü) intern yerine make-symbol kullanmak gerekir.

0

Bu, ad alanı desteği sağlamak için @ vpit3833 kodunun sabit bir sürümüdür (@Stefan öğesinden ipucu kullanarak). Yarı-sabit kalması çok iyidir :)

;; 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) 
+0

Chris Barrett, makroya '(declare (indent defun))' eklemeyi önerdi, böylece kod, bir ad alanı ilan ettikten sonra derin bir şekilde girintiye alınmaz. Yine de, derin girintiyi severim - ama aynı zamanda bunu kabul etmek ve onu seçenek olarak göstermeye yetecek kadar itibara sahip değilim (yorumda bulunur). –

+1

Eh, bu işe yaramaz. Aslında ihtiyacın olan bir kod yürüyüşü. Kod yürüteç, Lisp sözdizimini gerçekten anlayan bir Lisp kodu parçasıdır. Kodu yürümek ve işlev çağrılarını ve/veya değişken adlarını değiştirmeniz gerekir. Ama sadece bunlar. (macroexpand '(isim testi (defun testi()' testi))) -> Son test değiştirilmemelidir. –

+0

Bunun gibi bir şey mi var? http://www.merl.com/publications/TR1993-017/ (Makroexpand-All) –