all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: pjb@informatimago.com (Pascal J. Bourguignon)
To: help-gnu-emacs@gnu.org
Subject: Re: Emulating namespaces
Date: Thu, 03 Jun 2010 11:26:06 +0200	[thread overview]
Message-ID: <87typksc0h.fsf@kuiper.lan.informatimago.com> (raw)
In-Reply-To: e73e123d-3f0c-4a6f-bbac-b91fb71bf07d@f14g2000vbn.googlegroups.com

LanX <lanx.perl@googlemail.com> writes:
> I was meditating about how namespaces are realized in perl and now I'm
> wondering if this behaviour could be mimicked in elisp.

Actually, emacs has already the primitive mechanism needed to
implement packages.  This can AFAIK be done entirely in emacs lisp.

If only it had reader macros, we could provide the pack::sym and
pack:sym syntax too (and correct the :keyword syntax).



Emacs lisp stores symbols in obarrays.  The variable obarray is used
by intern, mapatom, etc.



So, basically:

(defvar *package-name-map* (make-hash-table :test (function equal)))

(defvar *list-all-packages* '())
(defun list-all-packages () (copy-list *list-all-packages*))


(defstruct (package (:constructor %make-package)) 
   name
   nicknames
   use-list
   used-by-list
   shadowing-symbols
   %obarray)

(defun* make-package (name &key nicknames uses size)
  (assert (notany (function find-package) (cons name nicknames)) 
          (name nicknames)
          "There is already a package with the same name or nickname")
  (let ((p (%make-package :name name
                          :nicknames nicknames
                          :use-list (or uses (find-package "EMACS-LISP"))
                          :%obarray (make-vector size nil))))
     (push p *list-all-packages*)
     (dolist (name (cons name nicknames))
         (setf (gethash name *package-name-map*) p))
     (internalize-used-symbols p)
     p))


;; bootstrap the emacs-lisp package:

(defvar *package* (let ((p (%make-package :name "EMACS-LISP"
                                          :nicknames '("ELISP")
                                          :use-list '()
                                          :%obarray obarray)))
                       (push p *list-all-packages*)
                       (dolist (name '("EMACS-LISP" "ELISP"))
                           (setf (gethash name *package-name-map*) p))
                       p))

(defmacro in-package (package-designator)
   `(progn
       (setf *package* (find-package ,package-designator))
       (setf obarray   (package-%obarray *package*))
       *package*))


So, if you take care to always :use "EMACS-LISP" to always have access
to in-package, you can skip from one obarray to another for further
reading, because without modifying the reader, you cannot use

   (elisp:in-package :elisp)

to come back.


You will need wrappers to map packages to obarray for function such
as intern.


Also, we could just use emacs-cl...
-- 
__Pascal Bourguignon__                     http://www.informatimago.com/


  parent reply	other threads:[~2010-06-03  9:26 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <143c6d28-4423-4e43-9fc5-c0fb3340043b@c11g2000vbe.googlegroups.com>
2010-05-31 15:44 ` About Emacs Modernisation Project Pascal J. Bourguignon
     [not found]   ` <0e994fe3-6dde-449f-879d-6701c7a195a9@e28g2000vbd.googlegroups.com>
2010-05-31 19:41     ` Alessandro Piras
     [not found]       ` <87iq63wsvt.fsf@kuiper.lan.informatimago.com>
2010-06-01  0:06         ` LanX
2010-06-01  8:44           ` Pascal J. Bourguignon
2010-06-01 11:19             ` LanX
2010-06-01 12:56               ` Pascal J. Bourguignon
2010-06-02  6:17         ` Xah Lee
     [not found]       ` <c41c63c0-b934-442d-8385-1abff6ab9b0b@s41g2000vba.googlegroups.com>
2010-06-01  0:40         ` Alessandro Piras
2010-06-02  6:07       ` Xah Lee
     [not found] ` <87ljazofkn.fsf@rapttech.com.au>
2010-05-31 23:33   ` LanX
2010-06-01 10:28     ` Helmut Eller
2010-06-01 11:27       ` LanX
2010-06-01 12:29         ` Helmut Eller
2010-06-01 12:55           ` LanX
2010-06-01 12:59             ` Pascal J. Bourguignon
2010-06-01 12:59           ` Pascal J. Bourguignon
2010-06-02 17:05       ` Xah Lee
2010-06-02 17:50         ` Helmut Eller
     [not found]     ` <87r5krh3e0.fsf@unm.edu>
2010-06-01  8:40       ` Pascal J. Bourguignon
2010-06-01 17:34         ` rustom
2010-06-02 12:47           ` B. T. Raven
2010-06-02 17:20             ` rustom
2010-06-01 19:50       ` Stefan Monnier
2010-06-01 23:22         ` LanX
     [not found]           ` <slrni0b8nm.9k6.bergv@u00.math.uiuc.edu>
2010-06-02 11:39             ` Pascal J. Bourguignon
     [not found]           ` <e73e123d-3f0c-4a6f-bbac-b91fb71bf07d@f14g2000vbn.googlegroups.com>
2010-06-03  9:26             ` Pascal J. Bourguignon [this message]
2010-06-03 15:33               ` Emulating namespaces LanX
2010-06-03 17:41                 ` Pascal J. Bourguignon
     [not found]         ` <87mxvegz12.fsf@unm.edu>
2010-06-01 23:36           ` About Emacs Modernisation Project Pascal J. Bourguignon
2010-06-02  5:58             ` Evans Winner
2010-06-04 18:33     ` Joseph Brenner
2010-06-05  2:55       ` Tim X

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87typksc0h.fsf@kuiper.lan.informatimago.com \
    --to=pjb@informatimago.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.