From: pjb@informatimago.com (Pascal J. Bourguignon)
To: help-gnu-emacs@gnu.org
Subject: Re: conditionals in elisp
Date: Tue, 27 Oct 2009 22:14:00 +0100 [thread overview]
Message-ID: <8763a0tu93.fsf@galatea.local> (raw)
In-Reply-To: mailman.9577.1256672457.2239.help-gnu-emacs@gnu.org
Harry Putnam <reader@newsguy.com> writes:
> pjb@informatimago.com (Pascal J. Bourguignon) writes:
>
> [...]
>
>> Why can't you see these links on the first page returned by Google?
>
> Be damned if I know.. Maybe I do need new glasses...
>
>> http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html
>
> There they are, if/else examples... NICE!
>
> [...]
>
>> Just tell us when you have five minutes to learn all there is to know
>> about lisp ;-)
>
> OK, I'll bite, the only risk is looking a fool, and I'm so far into that
> at this point, it can't matter.
Ok. It's quite simple really.
Here the 5-minute all you need to know about lisp:
There are two kinds of data:
- atoms, and
- lists.
Atoms are numbers of various sort such as: 123 1.23 1.2e.3, vectors
such as [1 2 3], strings such as "abc", and other kind of objects such
as functions, predefined data structures (eg. hash-tables), or user
defined structures or objects, and symbols such as: foo print if
what-a-nice-day, +, -, etc, that are used to name the various things
such as variables or functions. (Symbol can contain mostly any
character that wouldn't be interpreted as another kind of atom or
list, including spaces (just escape them with \)).
Lists are sequences of data enclosed in parentheses:
(a list containing only symbols)
(a list containing (a sub list))
(1 list containing 2 numbers and a "string")
Programs are data of a certain form that is evaluated.
The evaluation rules are:
- symbols alone are considered to be variable references, so the value
bound to the variable named by the symbol is returned.
- the other atoms are self evaluating, that is, their value is themselves.
- lists are considered to be operator applications and have always the form:
(operator arguments...)
There are three kinds of operators:
- functions,
- macro,
- special operators.
When the operator is a function, all the arguments are evaluated in
turn (from left to right), then the function is called with the
values of the arguments passed as parameters.
(sin (/ pi 2))
sin is a function, so we evaluate the argument:
(/ pi 2)
/ is a function so we evaluate the arguments:
pi is a symbol, so we get the value bound to the variable named pi.
It's 3.141592
2 is a atom that is not a symbol, so its value is itself.
2
We call the function / with the argument 3.141592 and 2
We get the result: 1.570796
We call the function sin with the argument 1.570796
We get the result: 1.
When the operator is a macro, then the arguments ARE NOT evaluated,
but are passed directly to the macro function. The macro function
must return a new expression that will be evaluated instead of the
macro call. By consequence, the meaning and possible order of
evaluation of the arguments depend on the macro function itself:
you have to lookup the documentation or source of the macro to know
what the argument should be, and whether and when they are
evaluated.
For example, in: (dotimes (i 3) (insert "hi "))
dotimes is a macro, therefore the two arguments, the lists (i 3) and
(insert "hi ") are passed as-is to the macro function dotimes.
What this macro function will do, is to generate an expression that:
- will evaluate the second element of the first argument (eg. 3,
returning 3),
- will create a variable named i (the first element of the first
argument,
- and that will evaluate the remaining arguments (the form (insert
"hi "), and others if there were) the number of times indicated
by that value, by binding a counter from 0 to the variable named
i, for use by the body.
You can see that by using the macroexpand function:
(macroexpand '(dotimes (i 3) (insert "hi ")))
--> (let ((--dotimes-limit-- 3)
(i 0))
(while (< i --dotimes-limit--)
(insert "hi ")
(setq i (1+ i))))
A special operator is like a primitive macro: the evaluation of the
arguments depends on a rule specific to each special operator.
There is a small number of special operators (about 20 to 30), and
while macros are used to extend the language beyond this small number
of special operators, they represent only a small percentage of the
operators available in a typical lisp system.
That's it, that's all there is to know about lisp. (It could be
expressed more shortly, in two pages of lisp code for the eval
function too ;-)).
All the rest is rather accidental, it could be different, and it would
still be lisp. It may change from one kind of lisp to another too
(emacs lisp, Common Lisp, ISO-Lisp, Scheme, and older variants).
There's some operators that are common to most lisps, such as if, let
and lambda, and of course there's a whole culture, quite endearing
and interesting, that may take however some time to learn and integrate.
To know what an operator is (function, macro or special operator), and
how to use it in emacs lisp, use the C-h f command.
For if: C-h f if RET
if is a special form in `C source code'.
(if cond then else...)
If cond yields non-nil, do then, else do else...
Returns the value of then or the value of the last of the else's.
then must be one expression, but else... can be zero or more expressions.
If cond yields nil, and there are no else's, the value is nil.
Try the same on dotimes and on insert.
--
__Pascal Bourguignon__
next prev parent reply other threads:[~2009-10-27 21:14 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.9533.1256602126.2239.help-gnu-emacs@gnu.org>
2009-10-27 0:19 ` conditionals in elisp Pascal J. Bourguignon
2009-10-27 2:52 ` LanX
2009-10-27 10:36 ` Pascal J. Bourguignon
2009-10-27 12:09 ` Richard Riley
2009-10-27 17:03 ` Sean Sieger
2009-10-28 12:07 ` Richard Riley
[not found] ` <mailman.9555.1256645401.2239.help-gnu-emacs@gnu.org>
2009-10-27 12:31 ` Pascal J. Bourguignon
2009-10-27 13:02 ` Richard Riley
[not found] ` <mailman.9557.1256648714.2239.help-gnu-emacs@gnu.org>
2009-10-27 16:04 ` Pascal J. Bourguignon
2009-10-27 17:26 ` Harry Putnam
[not found] ` <mailman.9572.1256664440.2239.help-gnu-emacs@gnu.org>
2009-10-27 18:37 ` Pascal J. Bourguignon
2009-10-27 19:40 ` Harry Putnam
[not found] ` <mailman.9577.1256672457.2239.help-gnu-emacs@gnu.org>
2009-10-27 21:14 ` Pascal J. Bourguignon [this message]
2009-10-28 14:05 ` David Kastrup
2009-10-28 15:55 ` Harry Putnam
2009-10-28 17:45 ` Pascal J. Bourguignon
2009-10-27 0:08 Harry Putnam
2009-10-27 0:25 ` Richard Riley
2009-10-27 1:03 ` Drew Adams
2009-10-27 5:33 ` Harry Putnam
2009-10-27 7:37 ` Drew Adams
2009-10-28 9:10 ` Thien-Thi Nguyen
2009-10-28 14:03 ` Drew Adams
[not found] ` <mailman.9621.1256738653.2239.help-gnu-emacs@gnu.org>
2009-10-28 15:42 ` LanX
2009-10-28 20:42 ` Harry Putnam
2009-10-28 16:19 ` Harry Putnam
[not found] ` <mailman.9630.1256746811.2239.help-gnu-emacs@gnu.org>
2009-11-02 19:31 ` Joseph Brenner
2009-10-27 5:50 ` tomas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8763a0tu93.fsf@galatea.local \
--to=pjb@informatimago.com \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.