12

And what can they be used for?

(interactive "p") takes a numerical argument from the universal argument right? And the universal argument is just an int either way, so what does capital (interactive "P") do?

Drew
  • 75,699
  • 9
  • 109
  • 225

3 Answers3

11

Hard to believe that people described this here without also giving you links to Emacs's own descriptions of this:

"Ask Emacs!": C-h i, choose a manual, i prefix argument RET.

In a nutshell, though this is said well enough by other answers here, and is described in detail in the manual:

  • The "raw" prefix arg provides Lisp values of different kinds, and in particular it distinguishes whether or not the user actually used a prefix argument (of any kind).

    Using it, a program can distinguish whether the user used one of {-, M--, C--} or one of {M-- 1, C-- 1, C-u -1} (both of which have the same numeric prefix value of -1), and distinguish whether s?he used C-u C-u or one of {M-16, C-16, C-u 16} (both of which have numeric value 16) - among lots of other distinctions.

    But the most important such distinction is nil vs non-nil: many commands act differently depending on whether the user uses a prefix arg.

  • The "numeric" prefix arg is really just the value that function prefix-numeric-value returns when applied to the raw prefix arg. IOW, it is best thought of as a mapping from the actual raw user interaction to an integer.

    It cannot tell you whether the user actually used a prefix argument, because the default of no prefix argument maps to the integer 1, just as does the use of C-u 1, M-1, or C-1.

Drew
  • 75,699
  • 9
  • 109
  • 225
10

When raw prefix Interactive Code "P" is used, the argument is passed on as it is whereas "p" converts the arg to a number.

After evaluating the below elisp, try out C-u M-x my/fn-with-num-arg and then C-u M-x my/fn-with-raw-arg to see the difference because C-u passes a list argument (4).

(defun my/debug-fn (arg)
  (let ((msg))
    (if (numberp arg)
        (setq msg (format "Argument is number %s. " (pp arg)))
      (setq msg "Argument is not a number. "))
    (if (listp arg)
        (setq msg (concat msg (format "Arg is %s." (pp arg))))
      (setq msg (concat msg "Argument is not a list.")))
    (message msg)))

(defun my/fn-with-num-arg (arg)
  (interactive "p")
  (my/debug-fn arg))
;; Result of C-u M-x my/fn-with-num-arg :
;; Argument is number 4. Argument is not a list.

(defun my/fn-with-raw-arg (arg)
  (interactive "P")
  (my/debug-fn arg))
;; Result of C-u M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is (4)
;; .

Also the argument defaults to 1 for numerical argument ("p") but defaults to nil or () for raw argument ("P").

My few cents: At times, the deciding factor for whether to use "p" or "P" is whether you want the default argument to be 1 or nil.

;; Result of M-x my/fn-with-num-arg :
;; Argument is number 1. Argument is not a list.

;; Result of M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is nil.
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • Thanks. I get that sometimes it is better to get `nil` than `1`, but never that having a wrapped `int` is preferable to an unwrapped `int`. (Can't upvote until I get 15 points, btw). – 24HrRevengeTherapist Jul 10 '15 at 20:37
  • @24HrRevengeTherapist: just up-voted ya', taking you past the magic 15 point threshold. Go out and do some up-voting on items that help you! – Dan Jul 10 '15 at 21:29
  • 1
    It's not about wrapped vs unwrapped ints. It's not about ints at all. And +1 to @kaushalmodi for emphasizing that you can tell whether the user used a prefix arg only by using the raw arg (by checking whether the value is `nil` or not). – Drew Jul 10 '15 at 22:38
  • What's the rationale for the C-u default argument being `(4)` and not, uhm, `(42)`, 42, or perhaps -23? I ask because the `(4)` is often dutifully mentioned but rarely explained. My working hypothesis is that Stallman happened to have four bits of toilet paper left when he came up with it. – Christian Mar 11 '22 at 18:16
  • My best guess is that `4` just hit the sweet spot for the use cases you might not be aware of: `C-u` is equal to `(4)`, `C-u C-u` gives `(16)` and `C-u C-u C-u` gives `(64)` and so on. This number might be empirically derived where the early emacs dev found 3^2 = 9 to be too small a number and 5^2 = 25 too large. E.g. `C-u C-u C-n` will move the cursor down by 16 lines, which could be roughly half the screen height in olden times. – Kaushal Modi Mar 11 '22 at 22:23
7

Just to add a bit more detail to @kaushalmodi's answer (and useful test case):

The raw argument lets you distinguish between arguments provided with universal-argument and digit-argument.

With a numeric prefix arg there is no way to distinguish the universal argument C-u from a prefix arg of 4 (i.e. C-4). With the raw argument these are different: (4) vs 4.

The same applies with negative-argument. As a raw argument you can distinguish between C-- and C-- 1: the first will give you - while the second -1. When converted to a numeric argument they will both be -1.

So the benefit of using a raw argument is it gives you more possible values. You can write commands that behave differently depending on how the argument is specified.

As an example, take a look at the doc string for yank. This command treats C-u and C-4 differently:

With just C-u as argument, put point at beginning, and mark at end. With argument N, reinsert the Nth most recent kill.

glucas
  • 20,175
  • 1
  • 51
  • 83