eintr: Determining the Element

 
 Determining the Element
 .......................
 
 Among other actions, the else-part of the ‘if’ expression sets the value
 of ‘kill-ring-yank-pointer’ to ‘ARGth-kill-element’ when the kill ring
 has something in it and the value of ‘do-not-move’ is ‘nil’.
 
    The code looks like this:
 
      (nthcdr (mod (- n (length kill-ring-yank-pointer))
                   (length kill-ring))
              kill-ring)))
 
    This needs some examination.  Unless it is not supposed to move the
 pointer, the ‘current-kill’ function changes where
 ‘kill-ring-yank-pointer’ points.  That is what the
 ‘(setq kill-ring-yank-pointer ARGth-kill-element))’ expression does.
 Also, clearly, ‘ARGth-kill-element’ is being set to be equal to some CDR
 of the kill ring, using the ‘nthcdr’ function that is described in an
 earlier section.  (Seecopy-region-as-kill.)  How does it do this?
 
    As we have seen before (Seenthcdr), the ‘nthcdr’ function works
 by repeatedly taking the CDR of a list—it takes the CDR of the CDR of
 the CDR ...
 
    The two following expressions produce the same result:
 
      (setq kill-ring-yank-pointer (cdr kill-ring))
 
      (setq kill-ring-yank-pointer (nthcdr 1 kill-ring))
 
    However, the ‘nthcdr’ expression is more complicated.  It uses the
 ‘mod’ function to determine which CDR to select.
 
    (You will remember to look at inner functions first; indeed, we will
 have to go inside the ‘mod’.)
 
    The ‘mod’ function returns the value of its first argument modulo the
 second; that is to say, it returns the remainder after dividing the
 first argument by the second.  The value returned has the same sign as
 the second argument.
 
    Thus,
 
      (mod 12 4)
        ⇒ 0  ;; because there is no remainder
      (mod 13 4)
        ⇒ 1
 
    In this case, the first argument is often smaller than the second.
 That is fine.
 
      (mod 0 4)
        ⇒ 0
      (mod 1 4)
        ⇒ 1
 
    We can guess what the ‘-’ function does.  It is like ‘+’ but
 subtracts instead of adds; the ‘-’ function subtracts its second
 argument from its first.  Also, we already know what the ‘length’
 function does (Seelength).  It returns the length of a list.
 
    And ‘n’ is the name of the required argument to the ‘current-kill’
 function.
 
    So when the first argument to ‘nthcdr’ is zero, the ‘nthcdr’
 expression returns the whole list, as you can see by evaluating the
 following:
 
      ;; kill-ring-yank-pointer and kill-ring have a length of four
      ;; and (mod (- 0 4) 4) ⇒ 0
      (nthcdr (mod (- 0 4) 4)
              '("fourth line of text"
                "third line"
                "second piece of text"
                "first some text"))
 
    When the first argument to the ‘current-kill’ function is one, the
 ‘nthcdr’ expression returns the list without its first element.
 
      (nthcdr (mod (- 1 4) 4)
              '("fourth line of text"
                "third line"
                "second piece of text"
                "first some text"))
 
    Incidentally, both ‘kill-ring’ and ‘kill-ring-yank-pointer’ are
 “global variables”.  That means that any expression in Emacs Lisp can
 access them.  They are not like the local variables set by ‘let’ or like
 the symbols in an argument list.  Local variables can only be accessed
 within the ‘let’ that defines them or the function that specifies them
 in an argument list (and within expressions called by them).