6

I have the feeling that Emacs Lisp macros are written in some different way than Common Lisp macros. This can't be true, but where is all the gensym things? Recently I was writing a macro and I needed to avoid capturing a lexical variable, so I started searching for gensym function. There is no such function! How can a Lisp that has macros don't have gensym? Maybe it's handled differently in Emacs Lisp?

I've found gensym in cl-lib, that's already something. But what I really need is with-gensyms. Do you know where can I find such a macro (third party package is fine if it's in ELPA or MELPA, although it should be built in Emacs by now, I think).

I'm ready to write these eight lines myself, but this sort of thing shouldn't be rewritten every time, IMHO.


Edit: to make it clear: I'm searching for a way to get this once and for all, that's a library that contains it that I can depend upon. If you think it's OK to rewrite it everywhere every time developer needs it -- that's your point of view. If you vote to close the question simply because there is no such library and

Lisp hackers generally do what is practical for them, such as writing a small utility macro and leaving it at that

-- I think your reasoning is fallacious. Lisp hackers generally don't like to redo something simply because that's how people do it. They create what they need and then use it everywhere.

There are quite a few different libraries that make life easier, and they often do more trivial things. Yet when I ask for something that's useful but missing I get this typical answer "well, don't you know, just copy paste it from Goggle because it isn't there".

You can of course close this question, but IMHO it's normal question asking for certain tool that Emacs Lisp developer might find useful in some cases. If you don't know decent solution, that doesn't mean that the question is bad.

  • 1
    Here's the EmacsWiki page on macro utilities that includes with-gensyms. It was the first hit from a Google search for "emacs with-gensyms". – Dan Jul 16 '15 at 18:37
  • 1
    Welcome to Emacs Lisp coding! – wasamasa Jul 16 '15 at 19:34
  • 2
    Please don't put it on MELPA unless there is overwhelming interest in yet another single-letter library. – wasamasa Jul 16 '15 at 20:09
  • 1
    Well, iirc with-gensyms is from Alexandria, it isn't standard CL either. Disclaimer: I didn't use this library, but I'm convinced that hygienic macros are better for many purposes than CL-style ones, and here's a library that claims to implement them in ELisp: github.com/ijp/mbe.el . Perhaps, if you are looking for a library to do a lot of macrology, this can come in handy. – wvxvw Jul 16 '15 at 21:13
  • 4
    Mark: M-x report-emacs-bug and suggest that org-with-gensyms be extracted and renamed to with-gensyms (or maybe cl-with-gensyms, depending on where it is most sensibly relocated to) for more general use. – phils Jul 16 '15 at 22:01
6

Take a look at Missing Macro Tools. It's available on MELPA.

The package provides the following classics:

  • mmt-gensym
  • mmt-make-gensym-list
  • mmt-with-gensyms
  • mmt-with-unique-names
  • mmt-once-only
  • 2
    Upvoted for providing the code for others, but (as before) please consider contributing them to Emacs if you feel that these are useful missing features from the standard libraries. – phils Jul 18 '15 at 6:31
  • 1
    @phils, If it proves useful for people, I will consider proposing it to FSF. The only thing that scares me is all this paper work. Too bad FSF cannot add something without having developers sign papers. – Mark Karpov Jul 18 '15 at 6:47
  • The copyright assignment is an added hurdle for sure, but it's really a very small amount of paperwork, and there's a reason for it. It does prove to be a sticking point for a few people; but I think most find it's something they're happy to do in order to be able to give something back to the FSF and GNU software. Your call, though. I just want to encourage it as an option (especially as it's easier to contribute code when it's entirely your own work -- if people start making pull requests, it might complicate matters). – phils Jul 18 '15 at 9:30
  • 1
    By the way, Emacs already comes with cl-gensym (from cl-lib). – npostavs Jul 18 '15 at 14:19
  • 2
    You can use defalias and pass a new docstring. I agree that minor duplication is OK, but in this specific case it's better not to have 2 gensyms that each use a separate counter. – npostavs Jul 18 '15 at 14:32
3

In my personal libraries, I also prefer to maintain a connection with Common Lisp idioms and syntax as much as possible, to avoid context switching. Of course, if I would develop public libraries I would try to avoid it. Common Lisp perspective seems not favoured by main Emacs developers, although I know a few representative ones that do favour cl-lib parlance.

In any case, I use el-get to manage the external packages. el-get allows to fecth directly from EmacsWiki. I have this in my init.el:

(el-get-bundle macro-utils)

Which nicely allows one to use with-gensyms, as you asked, and also once-only:

(defmacro double (x)
  (once-only (x)
    `(+ ,x ,x)))
  • 1
    +1, That's first normal answer out there. This is worth considering, although I don't really like idea of depending on Emacs wiki using el-get. I wouldn't mind using such a scheme in my init file, though. The thing is: in structured systems like (M)ELPA, there are explicit list of dependencies that those systems can analyse and manage installation of dependencies for you or show user dependencies of a package. I would like to follow the model. – Mark Karpov Jul 17 '15 at 8:05
  • @mark el-get take cares of dependencies too. See for example this recipe: github.com/dimitri/el-get/blob/master/recipes/org-sync.rcp I do use both, melpa and el-get, as they mix quite well. See the README at the link in the answer for more information. – gsl Jul 17 '15 at 9:14
1

Your question appears to be only "Where can I find with-gensyms?" If so, it should probably be closed, and in any case you seem to now have the answer, from Google.

As to the Emacs-Lisp way of doing things, the answer is make-symbol.

And in fact, org-with-gensyms, which you mention, just uses make-symbol:

(defmacro org-with-gensyms (symbols &rest body)
  `(let ,(mapcar (lambda (s)
                   `(,s (make-symbol (concat "--" (symbol-name ',s))))) symbols)
     ,@body))
  • 1
    Google didn't tell me name of reusable library that provides when-gensyms, thus I don't think this should be closed. – Mark Karpov Jul 16 '15 at 20:28
  • 3
    @Dan, This function is undocumented ad-hoc thing that developers of org-mode needed, and they coded it. It's not public API. Org is not a library for such macros by its nature. In principle if developers of org-mode decide to change something and remove this helper macro, what other people who depend on it should do? Should they say "Sorry our package doesn't work anymore because org-developers changed an internal ad-hoc macro that they needed"? I don't know how you @Drew, and @Dan can propose such ideas seriously. I regret asking the question because I see no understanding here. – Mark Karpov Jul 16 '15 at 21:02
  • 2
    +1 for make-symbol -- this is good tool to mention, but I don't think your post answers the question. You should understand that I knew how to implement this thing long before I asked my question, like any programmer knows how to program sort function, but never does it manually. You judge from position of user who needs to hack his/her init file, not from position of developer who needs collection of standard abstractions given without need to reimplement them again and again. If I don't get what I want, I will just write such a library myself on principle. And post its name as an answer. – Mark Karpov Jul 16 '15 at 21:13
  • 1
    @kaushalmodi, even if I do and they listen to me, this will take effect only in Emacs 25. What about older versions of Emacs that still will be used for quite some time, I think. This is a good think to do in long term, but it doesn't solve the problem in hand. – Mark Karpov Jul 17 '15 at 8:11
  • 1
    Mark: Sure it does. You previously argued that the org-mode maintainers might remove the macro. This way you would know that it was definitely available (in org-mode for a certain range of Emacs versions, and in its new location for subsequent versions), and therefore you know how to support all of those versions of Emacs. (If you want to support old versions of Emacs but you don't want to deal with any backward or forward compatibility issues with this macro, your only option is to include your own custom equivalent.) – phils Jul 17 '15 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.