Permalink
Browse files

Initial commit of partially working code.

  • Loading branch information...
0 parents commit 63f2281a51899ecd866273c607fe69afafd282c0 @skeeto committed May 26, 2011
Showing with 91 additions and 0 deletions.
  1. +40 −0 example.el
  2. +51 −0 fakespace.el
@@ -0,0 +1,40 @@
+(require 'fakespace)
+
+;; Start be declaring a package. `defpackage' currently supports :use
+;; and :export. Anything listed in :use will be `require'd. You can
+;; make your own calls to require, but they should occur before
+;; `defpackage'. Otherwise the functions and variables defined in the
+;; require will become part of your package and won't get exported.
+
+(defpackage example
+ (:use cl ido)
+ (:export example-main example-var))
+
+;; Caveat: any functions or variables you declare *will* be defined in
+;; the main namespace (we're faking namespaces here), but the
+;; non-exported ones will be removed later. They can be redefined
+;; elsewhere without interfering with the definitions here.
+
+(defvar my-var 100
+ "A hidden variable.")
+
+(defvar example-var nil
+ "A public variable.")
+
+(defun my-func ()
+ "A private function."
+ my-var)
+
+(defun example-main ()
+ "An exported function. Notice we can access all the private
+variables and functions from here."
+ (interactive)
+ (list (list (my-func) my-var) example-var
+ (ido-completing-read "New value: " (list "foo" "bar"))))
+
+;; Unlike Common Lisp, rather than declaring your namespace with
+;; `in-package' you must end your package definition with
+;; `end-package'. This will hide all of your internal functions away
+;; from the main namespace.
+
+(end-package)
@@ -0,0 +1,51 @@
+;;; fakespace.el --- fake Emacs lisp namespaces
+
+
+;;; Code:
+
+(defun atom-list (&optional ob)
+ "Return given obarray OB as a list. Defaults to obarray."
+ (let ((lst ()))
+ (mapatoms (lambda (s) (push s lst)) ob)
+ lst))
+
+(defun atom-difference (a b)
+ "Like set-difference, but, for performance reaons, requires
+specially formed lists. Returns items that are in B and not A."
+ (let ((diff))
+ (while (and (not (null a)) (not (null b)))
+ (while (not (eq (car a) (car b)))
+ (push (car b) diff)
+ (setq b (cdr b)))
+ (setq a (cdr a))
+ (setq b (cdr b)))
+ diff))
+
+(defun package-hide-p (s)
+ "Return t if this symbol should be uninterned."
+ (or (functionp s)
+ (documentation-property s 'variable-documentation)))
+
+(defvar old-obarray ()
+ "List of all the items from obarray at some previous time.")
+
+(defmacro defpackage (name &rest args)
+ (let ((code (list 'progn)))
+ (dolist (arg args)
+ (let ((type (car arg)))
+ (cond ((eq type :exports) t) ; interning the symbols is enough
+ ((eq type :use)
+ (setq code (append code (mapcar
+ (lambda (s)
+ `(require (quote ,s)))
+ (cdr arg))))))))
+ (setq old-obarray (atom-list))
+ (append code (list `(provide (quote ,name))))))
+
+(defmacro end-package ()
+ (cons 'progn
+ (mapcar (lambda (s) `(unintern (quote ,s)))
+ (remove-if-not 'package-hide-p
+ (atom-difference old-obarray (atom-list))))))
+
+(provide 'fakespace)

0 comments on commit 63f2281

Please sign in to comment.