3

I have some difficulties to understand how Lisp wanted to receive the arguments. When I look into the documentation about arguments in functions, I need to name the arguments exactly as in the source code, when calling the same function.

When I look into the documentation of Emacs function indent-region, I get the following:

= runs the command indent-region, which is an interactive compiled
Lisp function in `indent.el'.

It is bound to =, <menu-bar> <emacs-lisp> <indent-region>, C-M-\.

(indent-region START END &optional COLUMN)

Indent each nonblank line in the region.
A numeric prefix argument specifies a column: indent each line to that column.

Then I create a function, that pass the arguments to the function itself, as described in the documentation:

(defun foo (start end)
  (interactive)
  (indent-region start end)
  )

I see no difference when comparing with how another custom functions handles the functionality. When I visually selected a region, and call the function, I got the error that the arguments are of the wrong type.

So this led me to wonder why the start and end arguments are not accepted in this case?

  • 3
    A number of your recent questions have received answers suggesting that you read either an intro to elisp, or else the elisp manual. Rather than learn elisp piecemeal by disconnected questions here, it will probably be more effective to read up on elisp systematically. The intro or the manual are good places to start, and there are also many tutorials available. – Dan Jun 2 '15 at 7:16
  • It's not about how you name the arguments, it's about the extra parens. The first thing to learn about LISP syntax is this: (functionname argument1 argument2 argument3). You can pass a list as an argument, but generally you need to quote it: (functionname '(item1 item2 item3)). Try experimenting with functions like + and apply. – Joe Corneli Jun 2 '15 at 10:50
  • Try this manual page: gnu.org/software/emacs/manual/html_node/elisp/… – nanny Jun 2 '15 at 13:12
  • 1
    FWIW - Suggesting that the OP learn Emacs Lisp elsewhere is fine - helpful. But it is not a good reason to close this question, IMO. It is a reasonable newbie question. Every level of question is OK here. And the OP has clearly been trying to learn to fish, rather than just expecting fish & chips to be served up on demand. IMO, this particular Q & A can help others. – Drew Jun 2 '15 at 13:38
10

This risks being closed as unclear. Show your code that provokes an error, as well as telling how you invoke it. Show a backtrace from setting debug-on-error to t.

Your function foo looks OK; bar does not, because indent-region needs two arguments and you are passing only one. What's more, that argument would be the result of evaluating the sexp (start end), which means applying function start to the value of variable end. If you wanted to pass the list (start end) as an argument then you would need to quote it: '(start end). But that's no good for indent-region, which expects separate arguments for the start and end positions.

A guess is that you tried to use M-x foo instead of M-: (foo (region-beginning) (region-end)).

If you want foo to be a command, so that you can bind it to a key or invoke it using M-x, then you need an interactive spec. Use C-h f interactive. That tells you that to pass the region start and end positions you can use (interactive "r") -- there is only one r there, but two arguments are passed to the function (e.g. foo).

I suggest doing C-h i, choosing Emacs Lisp Intro, and starting to read it. You can also get tips for learning Emacs Lisp on Emacs Wiki.

  • Drew, thanks for your helpful answer. On your question to add the interactive function, I did already added it, but for the sake of the simplicity on Emacs Stackexchange I removed it. The code could be found here: pastebin.com/eP6x9ktQ. After visually select the whole region, call it with M-x indent-whole-buffer. After setting debug-on-error tot, this is the output of backtrace at the error: pastebin.com/7Mf1aYfn. By the way, I have vacation the next week. I have full planned with to learn the Lisp and Elisp. – ReneFroger Jun 2 '15 at 16:12
  • 1
    You need (interactive "r"), not just (interactive). – Drew Jun 2 '15 at 16:39
  • Thanks, I wonder how you did knew that the (interactive) was the culprit for start and end arguments. Even the C-h f interactive is very detailed, I couldn't knew that the interactive declaration was faulty. How could I know that in the next time? I marked your very detailed answer as the validate one. Thanks, I appreciate it and I learned new things here ans will read the manual about Emacs Lisp. – ReneFroger Jun 2 '15 at 23:23
  • 1
    When you invoke a function (command) interactively, interactive is what provides the arguments to the function. If you see an error about the arguments received (wrong number or wrong type), then something is likely wrong with the interactive spec (if you invoked the function interactively). – Drew Jun 3 '15 at 1:04
6

Experimentation can only go so far without fundamentals. The first two chapters of SICP will teach you all the LISP you need to know for Emacs. It takes about half a day to go through it.

After this comes the easy part: learn the names of standard functions at your own pace. Some of them you already know, others you can look up with apropos.

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.