From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: Emulating namespaces Date: Thu, 03 Jun 2010 11:26:06 +0200 Organization: Informatimago Message-ID: <87typksc0h.fsf@kuiper.lan.informatimago.com> References: <143c6d28-4423-4e43-9fc5-c0fb3340043b@c11g2000vbe.googlegroups.com> <87ljazofkn.fsf@rapttech.com.au> <04eff456-349f-4840-b0f7-d1784f6b7058@d12g2000vbr.googlegroups.com> <87r5krh3e0.fsf@unm.edu> <66c5242b-d254-4646-9537-6c669c6616bb@d12g2000vbr.googlegroups.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1291826902 18569 80.91.229.12 (8 Dec 2010 16:48:22 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 8 Dec 2010 16:48:22 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Dec 08 17:48:17 2010 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PQNBf-0002w8-5e for geh-help-gnu-emacs@m.gmane.org; Wed, 08 Dec 2010 17:48:15 +0100 Original-Received: from localhost ([127.0.0.1]:35474 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PQNBe-0008Br-EA for geh-help-gnu-emacs@m.gmane.org; Wed, 08 Dec 2010 11:48:14 -0500 Original-Path: usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 82 Original-X-Trace: individual.net vHXp93C12oQzPTQT5VTYJA5Uy3+niep9VOP9WzBPSvHJ8GSe0d Cancel-Lock: sha1:NWMxMTFkNzRmMGRmZDg0MWM4NmQ2NTEyZTg1NTAyN2JmOTI2MzE5Yg== sha1:CVIgQJZI3uPTr2S8GqrCV0oZmno= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.101 (Gnus v5.10.10) Emacs/23.1 (gnu/linux) Original-Xref: usenet.stanford.edu gnu.emacs.help:178584 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:75642 Archived-At: LanX 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/