Namespaces in Emacs Lisp - ohne den Interpreter zu ändern

» Adding namespace support to emacs lisp in a macro with just 15 lines of code - it’s things like this which make lisp feel like the mother of all languages.«1

(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)))
(provide 'namespace)
(require 'namespace)
(namespace foo
           (defun bar ()
             "bar")
           (defun foo (s)
               "foo"))
(foo-foo (foo-bar))

Disclaimer: This code is not perfect. It will likely fail in unpredictable ways, and the number of not supported corner-cases is probably huge - and unknown. But (and that’s the relevant result) you can do this right. Rainer Joswig gives pointers for that on Stackoverflow: “What you actually need is a so-called code-walker”. Also he shows examples where the code breaks.

(Der Hauptteil dieses Codes stammt von vpit3833 und konr und ich darf ihn verwenden. Er funktioniert dank einer Korrektur von Stefan. Er ist nicht perfekt, aber da er mir v.a. dazu dienen soll, meine eigenen Codeschnipsel besser zu organisieren, sollte ich das verschmerzen können)

Der Code mag schwer lesbar sein, hat aber riesige Implikationen: Du als einfacher Endnutzer des Lisp-Interpreters kannst Namespace-Support hinzufügen, ohne dass die Hauptentwickler dafür irgendetwas machen müssen.

Ich habe danach gesucht, weil ich in Python automatisch in jedem Modul einen Namespace habe, so dass der aktuelle Namensraum auch bei Verwendung von Zusatzmodulen sauber bleibt und ich immer weiß, woher eine Funktion oder Variable kommt, die ich verwende (das heißt, ich verwende kein from module import fun; fun(), sondern nur noch import module; module.fun oder bei sehr oft benutzten Modulen vielleicht noch import numpy as np; np.array()).

Um das in Emacs Lisp zu realisieren, musste ich bis heute jede Funktion explizit mit dem Namensraum definieren - und auch in dem Modul mit dem Namensraum aufrufen. Mit dem namespace macro kann ich jetzt diesen Code

(defun foo-bar ()
  "bar")
(defun foo-baz ()
  (foo-bar))
(defun foo-isastring (s)
  (stringp s))
(defun foo-foo (s)
  (if (foo-isastring s)
      "foo"))
(foo-foo (foo-bar))

In diesen Code umschreiben

(require 'namespace)
(namespace foo
           (defun bar ()
             "bar")
           (defun baz ()
             (bar))
           (defun isastring (s)
             (stringp s))
           (defun foo (s)
             (if (isastring s)
                 "foo")))
(foo-foo (foo-bar))

Spannend wäre jetzt noch ein require-namespaced, um dem Code von anderen nachträglich einen Namensraum geben zu können:

(require-namespaced 'feature)

PS: In Guile Scheme gibt es hierfür (use-modules ((foo) #:prefix foo-))


  1. Der Code stammt größtenteils aus einer Diskussion auf Stackoverflow

Use Node:

⚙ Babcom is trying to load the comments ⚙

This textbox will disappear when the comments have been loaded.

If the box below shows an error-page, you need to install Freenet with the Sone-Plugin or set the node-path to your freenet node and click the Reload Comments button (or return).

If you see something like Invalid key: java.net.MalformedURLException: There is no @ in that URI! (Sone/search.html), you need to setup Sone and the Web of Trust

If you had Javascript enabled, you would see comments for this page instead of the Sone page of the sites author.

Note: To make a comment which isn’t a reply visible to others here, include a link to this site somewhere in the text of your comment. It will then show up here. To ensure that I get notified of your comment, also include my Sone-ID.

Link to this site and my Sone ID: sone://6~ZDYdvAgMoUfG6M5Kwi7SQqyS-gTcyFeaNN1Pf3FvY

This spam-resistant comment-field is made with babcom.

Inhalt abgleichen
Willkommen im Weltenwald!
((λ()'Dr.ArneBab))



Beliebte Inhalte

Draketo neu: Beiträge

Ein Würfel System

sn.1w6.org news