I have packages variables that have list of github users and package names.

(defvar packages '('("auto-complete" . "auto-complete")
                   ("defunkt" . "markdown-mode")))

I want to git clone if the file is not exist yet.

(defun git-clone (author name)
  (let* ((repo-url (concat "git@github.com:" author "/" name ".git")))
    (print repo-url)
    (unless (file-exists-p (concat "~/.emacs.d/git/" name))
      (shell-command (concat "git clone " repo-url " ~/.emacs.d/git/" name)))))

And I want to apply git-clone to all packages variable to packages list. But I could not figure out how to apply with arguments.

; This obviously doesn't work
(mapcar `git-clone `packages)
  • 2
    By the way, you have an extra ' in your defvar declaration.
    – Dan
    Dec 13 '15 at 13:57
  • 1
    FWIW, this has got to be a duplicate, but I don't have time to search for it. ;-)
    – Drew
    Dec 13 '15 at 17:44

You can create an anonymous lambda function to take each element of your list and apply your function to it.


(defvar packages '(("auto-complete" . "auto-complete")
                   ("defunkt" . "markdown-mode")))

(defun toy-fnx (author name)
  "Just testing."
  (message "Package %s by author %s" name author)
  (sit-for 1))

(mapcar (lambda (package)
          (funcall #'toy-fnx (car package) (cdr package)))

Note that, if you don't care about the return values (ie, your function is only for side effects, which appears to be the case here), you can use mapc in place of mapcar:

(mapc (lambda (package)
        (funcall #'toy-fnx (car package) (cdr package)))

For your specific purposes, a loop may be simplest:

(cl-dolist (package packages)      ; or dolist if you don't want to use cl-lib
  (funcall #'toy-fnx (car package) (cdr package)))
  • There's no advantage to cl-dolist over plain dolist here.
    – npostavs
    Dec 13 '15 at 14:09
  • @npostavs: edited.
    – Dan
    Dec 13 '15 at 14:30
  • Thanks! I totally forgot about funcall.
    – ironsand
    Dec 13 '15 at 15:00
  • 3
    Hmm, I skipped over the funcall before, but looking again it seems redundant, why not just call toy-fnx directly?
    – npostavs
    Dec 13 '15 at 15:24
  • @npostavs: correct. It was just a way to illustrate mapcar and friends.
    – Dan
    Dec 13 '15 at 16:26

If you're happy using dash.el you can use -each and destructuring -let:

(require 'dash)

(--each packages
  (-let [(author . name) it]
    (git-clone author name)))

Alternatively, you can use -lambda from dash.el to create an anonymous function with destructuring:

 (-lambda ((author . name)) (git-clone author name))

Building on the answer by Dan, if you do this kind of thing often it may be useful to define a 'starred' variant of mapcar, as one does in e.g. Python:

(defun my-mapcar* (func arglist)
     (lambda (args)
       (apply func args))

so that e.g.

(my-mapcar* #'+ '((1) (1 1) (1 1 1) (1 1 1 1))
      ⇒ (1 2 3 4)  

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.