How to create DSL in Elisp

I want to create a DSL in Elisp, looking something like this:

(install ;; do install ) (uninstall ;; do uninstall ) 

However, since Elisp has a global namespace, this is not a good idea. And the prefix of functions like this is so damn ugly.

 (package-install ;; do install ) (package-uninstall ;; do uninstall ) 

So, I thought that the compromise of all commands could be wrapped in command calls as follows:

 (commands (install ;; do install ) (uninstall ;; do uninstall ) ;; ... ) 

But since I don’t want to install and remove in the global namespace, I somehow have to replace all occurrences of commands in the command macros, perhaps, for example, prefix names, for example:

 (defmacro commands (&rest body) (mapcar (lambda (exp) (setcar exp (intern (concat "package-" (symbol-name (car exp))))) (setcdr exp (list (cons 'progn (cdr exp))))) body) `(progn ,@body)) (commands (install ;; do install ) (uninstall ;; do uninstall ) ;; ... ) 

It looks like such a hack. Plus, this will not work if there are any nested commands.

Is there any good solution for this or a hack way?

Thanks!

+6
macros emacs elisp
source share
1 answer

What about the local definition of install and friends? This will not hide the standard functions, but it does not look like what you really are after.

 (defmacro commands (&rest body) `(flet ((install (&rest args) (apply 'package-install args)) (uninstall (&rest args) (apply 'package-uninstall args))) ,@body)) 

Of course, you want to automatically generate this list of flet arguments. You need a list of your package elements somewhere, possibly using (feature-symbols 'package) .

+8
source share

All Articles