emacs/elisp: What is the hash (pound, number sign, octothorp) symbol used for?
Asked Answered
P

4

127

What does this do?

(add-hook 'compilation-mode-hook #'my-setup-compile-mode)

...and is it different than

(add-hook 'compilation-mode-hook 'my-setup-compile-mode)
Pimental answered 23/4, 2010 at 20:14 Comment(0)
P
122

There is no difference:

(eq 'my-add #'my-add)

yields t

The # can be used in front of a lambda expression indicating to the byte-compiler that the following expression can be byte compiled, see the docs for Anonymous Functions. But there's nothing to compile in the case of a symbol.

In general, it is used in the printed representation along with the left angle bracket (<) to indicate that the object printed is a description (but cannot be read). For example:

#<buffer foo.txt>

It is also used in constructs by the reader to represent circular structures. See the docs for Read Syntax for Circular Objects.

And then you have its use for denoting the base for integers, e.g. #x2c -> 44.

Plus more I'm sure.

Pang answered 23/4, 2010 at 20:19 Comment(3)
According to this article, one good reason for applying # to a lone symbol is to get diagnostics at compile time if that symbol is undefined.Egide
It's not quite true that "there's nothing to compile in the case of a symbol." The byte compiler interprets #'car to mean "I am always referring to the function `foo', not the symbol foo." It may then actually inline the definition of foo in the byte-compiled output. (Edit: nope, that's actually wrong. #'symbol will not be byte-compiled any differently than 'symbol -- it's just a marker of intent.)Rubdown
Perhaps still mention that 'symbol represents (quote symbol) and #'symbol represents (function symbol) syntactically.Conjurer
I
34

The should-be-comprehensive list can be found at the top of the Emacs lisp reference index.

Edit: Or even more conveniently, from within Emacs itself:

  • M-x info RET (open the info browser)

  • d m elisp RET (open the elisp manual)

  • I # RET (list the entries for # in the index)

Irishirishism answered 24/4, 2010 at 11:7 Comment(0)
T
32

I found this question while searching for what the hash meant in something I found while hacking mode-line-format:

#("-%-" 0 3
  (help-echo "Display as tooltip when mouse hovers or with display-local-help."))

which is a format used for text properties in strings where:

  • "-%-", text to be propertized: one dash and a %-construct that results in "dashes sufficient to fill the remainder of the mode line", resulting in the famous Emacs ------.
  • 0, the first character upon which the text properties apply.
  • 3, the last character upon which the text properties apply, i.e. the entire "-%-".
  • (help-echo "..."), a property and a string as its argument.

This can be created with the propertize function:

(propertize "Hover over me!" 'help-echo '"congratulations!")

(insert (propertize "Hover over me!" 'help-echo '"Congratulations!"))

would be the same as #("Hover over me!" 0 14 (help-echo "Congratulations!")):

Small example.

If you're using font lock mode, using the buffer-substring command might produce something like this:

(buffer-substring 1 28) ; First 27 characters in the current buffer
 ⇒ #(";; This buffer is for notes"
     0 3
     (fontified t face font-lock-comment-delimiter-face)
     3 27
     (fontified t face font-lock-comment-face))

So you could create something like:

Showing the corresponding propertize function for multiple properties.

Truculent answered 19/2, 2011 at 23:17 Comment(1)
Link for propertize seems broken. See this instead: gnu.org/software/emacs/manual/html_node/elisp/…Lymphangitis
H
1

There is a difference if you want to pass a closure around:

(setq lexical-binding t)

(defun foo () (message "outer"))
(let ((x 5))
  (cl-flet ((foo () (message "inner: %d" (+ x x))))
    (setq y 'foo)
    (setq z #'foo)))
(funcall y)
(funcall z)

Outputs

outer
inner: 10

Though I think that's only because the cl-flet macro has special handling for #' aka (function ...). When you macroexpand it you get:

(let*
    ((--cl-foo--
      (cl-function
       (lambda nil
         (message "inner: %d"
                  (+ x x))))))
  (progn
    (message "%S" #''foo)
    (setq y 'foo)
    (setq z --cl-foo--)))
Haland answered 2/9, 2023 at 8:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.