16

I searched accross all Emacs Lisp files in Emacs Git repo, and found (goto-char (point-min)) occurs 3621 times and (goto-char 1) occurs 31 times. Personally, I see lots of (point-min) but none 1, even in many cases, it's 100% sure that the region is not narrowed. So here is my question: is (point-min) still preferred than 1 even in un-narrowed buffer?

I guess 1 is faster than (point-min), no mater how slight it is, because 1 is constant while (point-min) is a function call. Besides, 1 is much shorter than (point-min), 1 character v.s. 11 characters.

  • 2
    Can you provide an example where "it's 100% sure that the region is not narrowed'? I guess you mean immediately after widenning? Is that really "many cases"? – Omar Nov 21 '16 at 16:43
  • 1
    I always thought the buffer starts at 0... – Omair Majid Nov 21 '16 at 17:16
28

How do you know that the buffer is not narrowed?

Unless you have widened it right before you called the function, you cannot be sure. Moreover, "great software" is often defined as "being used in ways the author has never envisioned" - so one should always be prepared for the unusual use of one's code.

Code readability is King

When you write (goto-char 1), the person reading the code (including you 6 months later) will spend precious brainpower thinking

  • "how do we know the buffer is not narrowed?" and
  • "is the first character 0 or 1?"

Basically, unless you have (widen) right before, you need a comment explaining why you are confident the buffer is not narrowed.

Cost is trivial

Unless you have profiled your code and found otherwise, a safe assumption is that the cost here will be trivial. Compared to all the other things ELisp does (network, disk access, even string matching), (point-min) will not have a meaningful cost (and might even be cheaper, see Stefan's answer).

  • 2
    +1, especially for emphasizing taking possible use in unexpected ways, and possible reuse in other contexts. A function that uses point-min is typically more general than one that uses 1 - it typically can work whether or not the region is narrowed. – Drew Nov 21 '16 at 21:38
19

To complement sds's answer (with which I fully agree), despite appearances, (point-min) can be more efficient than 1. In terms of execution speed, my tests don't see any measurable difference, but in terms of size:

ELISP> (byte-compile '(lambda () (goto-char (point-min))))
#[nil "eb\207" [] 1]

ELISP> (byte-compile '(lambda () (goto-char 1)))
#[nil "\300b\207" [1] 1]

ELISP> 

That's because point-min has its own byte-code, and is hence encoded and executed very efficiently compared to other function calls.

Of course, another reason for me to use point-min is that I consider the historical choice of 1 to be a mistake (buffers should have started at 0).

  • 2
    The reason you give is only that the byte code for point-min is slightly smaller? Seems like a pretty paltry reason. Why attach importance to that? Or maybe your answer was really meant as a comment, to just correct the assumption that one is more performant than the other or that 1 results in smaller byte code? – Drew Nov 21 '16 at 21:36

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.