Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is the :eval form ?

48 views
Skip to first unread message

Philippe M. Coatmeur

unread,
Jun 8, 2012, 2:39:22 PM6/8/12
to
Hi ; I'm trying to get some information about this (e?)lisp form

(add-to-list 'global-mode-string
'(:eval (mail-bug-mode-line-all "2")))

But it appears to be really hard to google for it, as both

https://www.google.com/search?q=":eval"
https://www.google.com/search?q="eval"

Return the same results... (apparently google does not care for
punctuation)

How can I find information about this special form ? When I ask emacs
using C-h f with point over it, it acts like google and shows me the
"plain eval" info page... :(

BTW what I'm trying to do is to use a variable to pass the ("2" in the
example) argument to the function, to use it in a loop, like this :

(loop for i from 1 to 3 do
(add-to-list 'global-mode-string
'(:eval (mail-bug-mode-line-all (format "%s" i)))))

but i's value is always stuck at 1 :(

Phil

Eli Zaretskii

unread,
Jun 8, 2012, 1:56:58 PM6/8/12
to help-gn...@gnu.org
> From: Philippe M. Coatmeur <philippe...@gmail.com>
> Date: Fri, 08 Jun 2012 18:39:22 +0000
>
> Hi ; I'm trying to get some information about this (e?)lisp form
>
> (add-to-list 'global-mode-string
> '(:eval (mail-bug-mode-line-all "2")))
>
> But it appears to be really hard to google for it, as both
>
> https://www.google.com/search?q=":eval"
> https://www.google.com/search?q="eval"
>
> Return the same results... (apparently google does not care for
> punctuation)
>
> How can I find information about this special form ?

Search the Emacs Lisp manual instead.

C-h i m elisp RET C-s :eval C-s C-s ...

Drew Adams

unread,
Jun 8, 2012, 2:01:19 PM6/8/12
to Philippe M. Coatmeur, help-gn...@gnu.org
> I'm trying to get some information about this (e?)lisp form
> (add-to-list 'global-mode-string
> '(:eval (mail-bug-mode-line-all "2")))
>
> How can I find information about this special form ?
> When I ask emacs using C-h f with point over it

:eval is not a function here.

What you want to do is ask Emacs about variable `global-mode-string': `C-h v
global-mode-string'.

That help buffer includes a link to help on variable `mode-line-format'. If you
click that link you will find information about :eval.


Tassilo Horn

unread,
Jun 8, 2012, 2:02:38 PM6/8/12
to help-gn...@gnu.org
Philippe M. Coatmeur <philippe...@gmail.com> writes:

Hi Philippe,

> How can I find information about this special form ? When I ask emacs
> using C-h f with point over it, it acts like google and shows me the
> "plain eval" info page... :(

:eval is neither a function nor a special form, it is a keyword.

,----[ (info "(elisp)Symbol Type") ]
| A symbol whose name starts with a colon (`:') is called a "keyword
| symbol". These symbols automatically act as constants, and are
| normally used only by comparing an unknown symbol with a few specific
| alternatives.
`----

Some keywords have a special meaning for some variables such as
`global-mode-string', so let's check its docs instead of googling.

,----[ C-h v global-mode-string RET ]
| global-mode-string is a variable defined in `C source code'.
| Its value is ("" appt-mode-string)
|
| This variable is potentially risky when used as a file local variable.
|
| Documentation:
| String (or mode line construct) included (normally) in `mode-line-format'.
`----

Ah, so I might want to check out `mode-line-format'.

,----[ C-h v mode-line-format RET ]
| mode-line-format is a variable defined in `C source code'.
| Its value is shown below.
|
| Automatically becomes buffer-local when set in any fashion.
| This variable is potentially risky when used as a file local variable.
|
| Documentation:
| [...]
| For a list of the form `(:eval FORM)', FORM is evaluated and the result
| is used as a mode line element. Be careful--FORM should not load any files,
| because that can cause an infinite recursion.
| [...]
`----

So there's your :eval. Another way to find out about the meaning of
eval was to use the emacs info docs.

C-h i m elisp RET C-s :eval C-s [maybe repeatedly]

leads to:

,----[ (info "(elisp)Mode Line Data") ]
| A mode line construct may be as simple as a fixed string of text,
| but it usually specifies how to combine fixed strings with variables'
| values to construct the text. Many of these variables are themselves
| defined to have mode line constructs as their values.
|
| Here are the meanings of various data types as mode line constructs:
|
| [...]
|
| `(:eval FORM)'
| A list whose first element is the symbol `:eval' says to evaluate
| FORM, and use the result as a string to display. Make sure this
| evaluation cannot load any files, as doing so could cause infinite
| recursion.
`----

Bye,
Tassilo


Tassilo Horn

unread,
Jun 8, 2012, 2:08:29 PM6/8/12
to help-gn...@gnu.org
Philippe M. Coatmeur <philippe...@gmail.com> writes:

Hi Philippe,

> BTW what I'm trying to do is to use a variable to pass the ("2" in the
> example) argument to the function, to use it in a loop, like this :
>
> (loop for i from 1 to 3 do
> (add-to-list 'global-mode-string
> '(:eval (mail-bug-mode-line-all (format "%s" i)))))
>
> but i's value is always stuck at 1 :(

Not sure what you are trying to do, but since you quote (') the :eval
form, what's actually added to the `global-mode-string' list is
literally

(:eval (mail-bug-mode-line-all (format "%s" i)))

with i not substituted with 1, 2, or 3. And since `add-to-list' only
adds if that elements is not included already, you end up with exactly
one occurence.

I guess, you want this:

(loop for i from 1 to 3 do
(add-to-list 'global-mode-string
`(:eval (mail-bug-mode-line-all (format "%s" ,i)))))

Bye,
Tassilo


Drew Adams

unread,
Jun 8, 2012, 2:10:03 PM6/8/12
to Philippe M. Coatmeur, help-gn...@gnu.org
> what I'm trying to do is to use a variable to pass the
> ("2" in the example) argument to the function, to use
> it in a loop, like this :
>
> (loop for i from 1 to 3 do
> (add-to-list 'global-mode-string
> '(:eval (mail-bug-mode-line-all
> (format "%s" i)))))
>
> but i's value is always stuck at 1 :(

That's because you want to evaluate (format "%s" i) when the `loop' is executed,
but you have put it inside '(...). So your iterator puts this into
`global-mode-string' at each iteration:

(:eval (mail-bug-mode-line-all (format "%s" i)))

What you really want is this (or equivalent):

(loop for i from 1 to 3 do
(add-to-list
'global-mode-string
`(:eval (mail-bug-mode-line-all ,(format "%s" i)))))


Barry Margolin

unread,
Jun 8, 2012, 2:21:26 PM6/8/12
to
In article <lzvcj1tzqd.wl%philippe...@gmail.com>,
Philippe M. Coatmeur <philippe...@gmail.com> wrote:

> Hi ; I'm trying to get some information about this (e?)lisp form
>
> (add-to-list 'global-mode-string
> '(:eval (mail-bug-mode-line-all "2")))
>
> But it appears to be really hard to google for it, as both
>
> https://www.google.com/search?q=":eval"
> https://www.google.com/search?q="eval"
>
> Return the same results... (apparently google does not care for
> punctuation)
>
> How can I find information about this special form ? When I ask emacs
> using C-h f with point over it, it acts like google and shows me the
> "plain eval" info page... :(

It's not a special form, it's specific to the way the value of
global-mode-string is interpreted. If you read its documentation,
you'll see that it's used within mode-line-format. If you then read its
documentation, it describes all the special keywords that can be used
within it.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Philippe M. Coatmeur

unread,
Jun 8, 2012, 3:19:49 PM6/8/12
to
At Fri, 08 Jun 2012 20:08:29 +0200,
This worked perfectly. The magic is that even if the element has
changed, it gets replaced notheless. Big thanks to all of you guys
(boy that was fast), especially the documentation bits (now I can dig
in on that backtick/comma construct) :)

Phil

>
>

Philippe M. Coatmeur

unread,
Jun 8, 2012, 3:19:49 PM6/8/12
to help-gn...@gnu.org
At Fri, 08 Jun 2012 20:08:29 +0200,
Tassilo Horn wrote:
>

Richard Riley

unread,
Jun 9, 2012, 2:40:44 AM6/9/12
to help-gn...@gnu.org
Tassilo Horn <tas...@member.fsf.org> writes:

> Philippe M. Coatmeur <philippe...@gmail.com> writes:
>
> Hi Philippe,
>
>> How can I find information about this special form ? When I ask emacs
>> using C-h f with point over it, it acts like google and shows me the
>> "plain eval" info page... :(
>
> :eval is neither a function nor a special form, it is a keyword.
>
> ,----[ (info "(elisp)Symbol Type") ]
> | A symbol whose name starts with a colon (`:') is called a "keyword
> | symbol". These symbols automatically act as constants, and are
> | normally used only by comparing an unknown symbol with a few specific
> | alternatives.
> `----


Is that also true in a function call?

e.g

,----
| (notifications-notify :title "Wazzup!?" :message message))
`----

title and message are not keywords here.

Or is the keyword "symbol" here?


Thien-Thi Nguyen

unread,
Jun 9, 2012, 4:34:02 AM6/9/12
to help-gn...@gnu.org
() Richard Riley <ril...@gmail.com>
() Sat, 09 Jun 2012 08:40:44 +0200

Is that also true in a function call?

,----
| (notifications-notify :title "Wazzup!?" :message message))
`----

title and message are not keywords here.

Or is the keyword "symbol" here?

In Emacs Lisp keywords and symbols are not disjoint.
A keyword is a symbol whose name begins with colon.
That's all (conceptually).

;; -*- emacs-lisp -*-
(symbolp 'foo)
t

(symbolp :foo)
t

(keywordp 'foo)
nil

(keywordp :foo)
t

In this *scratch* excerpt, we see that relationship
and note that all occurances are "in a function call"
(i presume to mean "arg to a function"), the functions
being ‘symbolp’ and ‘keywordp’.

But design and implementation are likewise not disjoint:

In the prior example, ‘notifications-notify’ is called
with four args, the even-indexed keywords, the odd-indexed
a string and whatever ‘message’ happens to be.

If you instrument (advise) ‘notifications-notify’ to call
‘type-of’ on each of the args it receives, you will find
that ‘type-of’ is not so smart:

(type-of 'foo)
symbol

(type-of :foo)
symbol

You might be tempted, then, to write:

(defun excruciatingly-correct-type-of (object)
(let ((guess (type-of object)))
(case guess
(symbol (if (char-equal ?: (aref (symbol-name object) 0))
'keyword
guess))
(t guess))))

(excruciatingly-correct-type-of 'foo)
symbol

(excruciatingly-correct-type-of :foo)
keyword

Or not. Personally, i stressed about this a while back but now
have mellowed out a bit. Willful ignorance tastes different once
you go around the circle (at least once :-D).

Drew Adams

unread,
Jun 9, 2012, 10:08:07 AM6/9/12
to help-gn...@gnu.org
> > A symbol whose name starts with a colon (`:') is
> > called a "keyword symbol". These symbols automatically
> > act as constants,

when evaluated.

Debugger entered--Lisp error: (setting-constant :foo)
(setq :foo 42)

> Is that also true in a function call?

Is what true? A keyword symbol is just a symbol (a) whose name starts with `:'
and (b) that evaluates to itself.

> e.g (notifications-notify :title "Wazzup!?" :message message))
> title and message are not keywords here.

They are keyword symbols. When they are evaluated (during function
application), the values returned are those same symbols.

> Or is the keyword "symbol" here?

Yes, the key word here is "symbol". Whether or not a keyword symbol serves as a
keyword in some context depends on the context. It means what you want it to
mean. Like everything in Lisp, you can use a keyword symbol as anything you
like.

But it always has properties (a) and (b).


0 new messages