1

I'm trying to create a function in elisp that returns another function. I looked at this answer to a similar question (how to return function in elisp) but did not understand the answer (I'm literally just starting learning elisp today, so please excuse my ignorance). I thought a simpler example would help. First, consider a function that test whether a number is divisible by 5:

(defun divisible-by-5 (x) 
  ;; tests whether a number is divsible by 5. 
  (setq remainder (% x 5))
  (if (= remainder 0) 1 0)
)

This works fine:

(divisible-by-5 25)
1

Now suppose I want to create a function that can create more of these kinds of test functions---something like:

(defun divisible-by-z (z)
  (lambda (z) 
  (setq remainder (% x z))
  (if (= remainder 0) 1 0))
 )

This does not work. E.g.,

(defun divisible-by-3 (divisible-by-z 3))
(divisible-by-3 4)

returns an error. I think even seeing an elisp-idiomatic example of how one would implement this pattern would be helpful.

3 Answers 3

4

First, make sure you have lexical-binding enabled. The simplest way to do so is to evaluate (setq lexical-binding t) in your current buffer. More information on the topic can be found here.

Your definition of divisible-by-z is basically correct except that you have a mistype (naming both parameters z; the lambda's parameter should be x). Also, it would be more idiomatic to introduce the binding for remainder with let - setq is generally reserved for mutating bindings that already exist. Here's the result:

(defun divisible-by-z (z)
  (lambda (x)
    (let ((remainder (% x z)))
      (if (= remainder 0) 1 0))))

You can't use defun to create divisible-by-3 in quite the way you've tried - it's expecting the argument list for a new function to be where you have the call to divisible-by-z.

You could either create a global, dynamic binding with

(defvar divisible-by-3 (divisible-by-z 3))

Or a local, lexical binding with

(let ((divisible-by-3 (divisible-by-z 3)))
  ...)

Either way, you'll then need to use funcall to call the function

(funcall divisible-by-3 9) ; => 1

Of course, you could also skip giving it its own name entirely and simply

(funcall (divisible-by-z 3) 10) ; => 0

funcall is necessary because Emacs Lisp is (basically) a Lisp-2, meaning it can attach both a function and a value to a given symbol. So when you're treating functions as values (returning one from a function or passing one in to a function as a parameter) you essentially have to tell it to look in that value "cell" rather than the usual function cell. If you search for "Lisp-1 vs Lisp-2" you'll find more than you want to know about this.

Sign up to request clarification or add additional context in comments.

Comments

3

A possible solution:

(defun divisible-by-3 (x)
  (funcall (divisible-by-z 3) x))

Comments

0

Another (perhaps simpler) method is to include x as a variable to be passed to the function:

(defun divisible-by-z (x z) "
Check if x is divisible by z.
If so, return 0.
If not, return the remainder."
   (if (% x z) (% x z) 0))

thus:

(divisible-by-z 5 2) --> 1
(divisible-by-z 4 2) --> 0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.