The context
-----------

I'm using the `after-make-frame-functions` hook to load properly the themes in an **emacs client/server configuration**. Specifically this is the code snippet that I use to make that (based in this [SO answer](https://stackoverflow.com/a/23668935/634816)):

```
 (if (daemonp)
      (add-hook 'after-make-frame-functions
          (lambda (frame)
              (select-frame frame)
              (load-theme 'monokai t)
              ;; setup the smart-mode-line and its theme
              (sml/setup))) 
      (progn (load-theme 'monokai t)
             (sml/setup)))

```

The problem
-----------

When a new `emacsclient -c/t` session is started the hook is executed not only in the new frame, but in all the previous existent frames (other *emacsclient* sessions) and **it makes a very annoying visual effect (the themes are loaded again in all those frames)**. Even worse, in the terminal clients already opened the theme color get completely messed up. Obviously that happens only on the emacs clients connected to the same emacs server. The reason for this behavior is clear, the hook is run on the server and all of its clients are affected.

The question
------------

Is there any way to execute this function only once or getting the same result without using the hook?

---

A partial solution
------------------

I have now this code, thanks to the @Drew's answer. But still has a problem, once you start a client session in the terminal, the GUI does not load the themes properly and vice-versa. After a lot of tests, I realized that the behavior depends on which emacsclient starts first, and after discard various things, I think that it is maybe related with the color palette that is loaded. If you reload manually the theme all works fine and that's the reason why this behavior does not appear when the function is called by the hook every time as in my initial configuration. 

```
(defun emacsclient-setup-theme-function (frame)
  (progn
    (select-frame frame)
    (load-theme 'monokai t)
    ;; setup the smart-mode-line and its theme
    (sml/setup)
    (remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))

(if (daemonp)
    (add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
    (progn (load-theme 'monokai t)
           (sml/setup)))

```

---

The final solution
==================

Finally I have totally working code that solves the behavior seen in the partial solution, to achieve this I run the function once by mode (terminal or gui) when then pertinent emacsclient is started for first time, then remove the function from the hook because is no needed any more. Now, I am happy! :)
Thanks again @Drew!

The code:

```
(setq myGraphicModeHash (make-hash-table :test 'equal :size 2))
(puthash "gui" t myGraphicModeHash)
(puthash "term" t myGraphicModeHash)

(defun emacsclient-setup-theme-function (frame)
  (let ((gui (gethash "gui" myGraphicModeHash))
        (ter (gethash "term" myGraphicModeHash)))
    (progn
      (select-frame frame)
      (when (or gui ter) 
        (progn
          (load-theme 'monokai t)
          ;; setup the smart-mode-line and its theme
          (sml/setup)
          (sml/apply-theme 'dark)
          (if (display-graphic-p)
              (puthash "gui" nil myGraphicModeHash)
            (puthash "term" nil myGraphicModeHash))))
      (when (not (and gui ter))
        (remove-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)))))

(if (daemonp)
    (add-hook 'after-make-frame-functions 'emacsclient-setup-theme-function)
  (progn (load-theme 'monokai t)
         (sml/setup)))

```