I don't totally understand what you are trying to do here. If this were Python, it sounds like you want some kind of class that stores a variable and reuses it several different functions? Something kind of similar to that in elisp is a closure, which is like what you described. For example, here, we define a variable a, and then define two functions that use it persistently. #+BEGIN_SRC emacs-lisp (lexical-let ((a 5)) (defun f1 (x) (* a x)) (defun f2 (x) (+ a x))) (list (f1 2) (f2 2)) #+END_SRC #+RESULTS: | 10 | 7 | I think you can wrap this in a macro to make new functions, e.g. #+BEGIN_SRC emacs-lisp (defmacro f-maker (a) `(lexical-let ((a ,a)) (defun f1 (x) (* a x)) (defun f2 (x) (+ a x)))) (f-maker 3) (list (f1 2) (f2 2)) #+END_SRC #+RESULTS: | 6 | 5 | There is also a class system you can probably use like this called eieio, Here is one approach to doing this. #+BEGIN_SRC emacs-lisp (require 'eieio) (defclass Grade () ((:a :initarg :a))) (cl-defmethod gf1 ((g Grade) x) (* (oref g :a) x)) (cl-defmethod gf2 ((g Grade) x) (+ (oref g :a) x)) (let ((G (Grade :a 3))) (list (gf1 G 2) (gf2 G 2))) #+END_SRC #+RESULTS: | 6 | 5 | Finally, maybe the simplest thing to do is pass this information in as an argument, e.g. a plist or alist, or get them from a function that you only change in one place? John ----------------------------------- Professor John Kitchin Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu On Tue, Sep 17, 2019 at 7:31 AM Matt Price wrote: > I have a number of convenience functions define to help me with grading > assignments. As I go through the semester, i update all of these functions > modestly so that they'rehelpful for grading the current assignment. > > I big chunk of these simple functions is taken up just declaring variables > with (let (())) forms. Each function uses some ofhte same variables, e.g: > > (defun dh-find-files () > (interactive) > (let* ((base (org-entry-get (point) "ORG_LMS_ASSIGNMENT_DIRECTORY")) > (gh (org-entry-get (point) "GITHUB")) > (f2o `( ,(concat "Reflection/" gh ".md") ,(concat "students/" gh > ".json")))) ;;;; "01/index.html" "02/index.html" "03/style.css" > "04/style.css" > (message "%s" f2o) > ;; make more flexible for resubmits > (shell-command (concat "cd " base " && git checkout " gh "-master")) > (dolist (x f2o) > (if (file-exists-p (concat base "/" x)) > (find-file-other-window (concat base "/" x) ) > (message "File %s does not exist, not opening." x))))) > > (defun dh-tests () > (interactive) > (let* ((base (org-entry-get (point) "ORG_LMS_ASSIGNMENT_DIRECTORY" )) > (gh (org-entry-get (point) "GITHUB"))) > (with-temp-buffer (shell-command (concat "cd " base " && npm test") > t)) ;; the "t" lets us suppress buffer > (browse-url-of-file (concat base "/TestResults/testresults.html")) > ;; (dh-mocha-run) > > )) > > ---------- > > This semester I changed some elements of my workflow and I had to update > all the (org-entry-get) calls to new values. It makes me think the code is > less maintainable than it could be. I would like to do something like this: > > (lexical-let ((base `(org-entry-get (point) "ORG_LMS_ASSIGNMENT_DIRECTORY") > (gh `(org-entry-get (point) "GITHUB")) ) > (defun dh-find-files () > (with-temp-buffer (shell-command (concat "cd " base " && npm test") t)) ;; > the "t" lets us suppress buffer > (browse-url-of-file (concat base "/TestResults/testresults.html"))))) > > > Obviously it doesn't work this way. But is there any way to set macros > like this to be expanded later inside a function definition? I feel certain > there must be... > > Thanks, > > Matt >