From: pjb@informatimago.com (Pascal J. Bourguignon)
To: help-gnu-emacs@gnu.org
Subject: Re: identity function with an echo side effect
Date: Wed, 11 Aug 2010 22:43:58 +0200 [thread overview]
Message-ID: <87bp98anht.fsf@kuiper.lan.informatimago.com> (raw)
In-Reply-To: 106a3bf2-cd32-4b50-8e99-81e0cad8efa2@j8g2000yqd.googlegroups.com
bolega <gnuist006@gmail.com> writes:
> On Aug 11, 7:19 am, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Since CDR and PRINT are function, no implicit quotation occurs: the
>> result values are directly passed as argument to the next function.
>
> Then why does the following gives an error. Currently, I only have
> elisp working so we confine to emacs runs.
>
> (cdr (print (cdr (print (cdr (print (a b c d))))))) C-x C-e
>
> gives this error if I remove the quote. why ?
What are the rules of lisp evaluation?
> I get errors if I remove
> all prints. This means if the first cdr required quoted list,
No. cdr requires a LIST. Nothing more, nothing less.
> then the rest must also require it.
print may take any lisp object as argument. cdr mak take any list.
> Hence, an implicit quotation might be
> occurring as in setq ?
setq as its name implies indeed makes an implicit quotation. But not
the one you may think.
> Also, plz explain me the debugger output in
> detail so I can figure it out myself. may be a line by line comment
> and if there is a more comprehensive example you can cook, better for
> all the readers, once and for all.
>
> Debugger entered--Lisp error: (void-function a)
a is not a function, that is, the function slot of the symbol a is void.
The rest is the backtrace:
The error was detected when trying to evaluate this form:
> (a b c d)
which was to be evaluated because it was needed to evaluate this form:
> (print (a b c d))
etc.
> (cdr (print (a b c d)))
> (print (cdr (print ...)))
> (cdr (print (cdr ...)))
> (print (cdr (print ...)))
> (cdr (print (cdr ...)))
> eval((cdr (print (cdr ...))))
> eval-last-sexp-1(nil)
> eval-last-sexp(nil)
> * call-interactively(eval-last-sexp)
The rules of evaluation of lisp are something like:
(defun eval. (form)
(cond
((symbolp form) (symbol-value form))
((atom form) form)
(t (case (first form)
((quote function) (second form))
((if) (if (eval. (second form))
(eval. (third form))
(let ((result))
(dolist (subform (cdddr form))
(setf result (eval. subform)))
result)))
;; ... other special operator special rules here ...
(otherwise
(cond ((symbol-function (first form))
(apply. (symbol-function (first form))
(mapcar (function eval.) (rest form))))
((macro-function (first form))
(eval. (macroexpand form)))
(t
(error "(void-function %S)" (first form)))))))))
Quote is useless and worthless, you can write your programs without it.
To get the symbol named "a", you may use the function intern.
To build a list, you may use the function list.
(let ((my-list (list (intern "a")
(intern "b")
(intern "c")
(intern "d"))))
(cdr (print (cdr (print (cdr (print my-list)))))))
(a b c d)
(b c d)
(c d)
(d)
It just happen that when you read "(a b c d)", the lisp reader just
calls intern and list like you would. So you could also write, in
emacs lisp:
(let ((my-list (car (read-from-string "(a b c d)"))))
(cdr (print (cdr (print (cdr (print my-list)))))))
(in Common Lisp, READ-FROM-STRING returns two values, instead of
returning one cons cell with the two values, so the CAR would be
superfluous).
But also, it happens that:
(car (read-from-string "(a b c d)"))
returns:
(a b c d)
and that lisp programs are read by the same lisp reader used by
read-from-string. Therefore if you write
(a b c d)
in your program, what will be read is exactly the same as the list you
would build with list and intern, or read with read-from-string.
There's just a little problem, that what is read in a program is also
evaluated! And (a b c d) is not a symbol, it's not an atom, and its
first element is not quote, if, or any other special operator defined
in lisp, therefore eval will check if it is a function. Since a is
not defined as a function, and it is not defined as a macro, eval will
fall down in the latest case, were it will report the error that a is
not a function.
Any expression in a program will be executed! This is the point of
being a program, to be executed (by eval).
So how can we insert in a program some literal data. For example,
what happens when we evaluate the expression:
42
?
It is not a symbol. But it is an atom. And when it's an atom, eval
will return it as is. non-symbol atoms are self-evaluating.
Therefore the value (the result of evaluating) 42 is 42. We're quite
lucky that numbers are worth themselves!
For non atoms, we must use the special operator quote, because
otherwise they would be evaluated as an operator application.
(quote 42)
is not a symbol, is not an atom (it's a cons cell), but it's first
element is the symbol quote. In that case, eval returns the second
elements, that is, 42. Therefore:
(quote 42)
evaluates to
42
which is the same as what:
42
evaluates to.
(eql '42 42) evaluates to true! But this is something that is
specific to non-symbol atoms (and some symbols, that are bound to
themselves such as nil, t, or any other variable you'd bind to their
symbol).
(quote (a b c d))
is not a symbol, is not an atom, is a list whose first element is
quote, therefore eval returns the second elements, which happens to be
the list:
(a b c d)
Therefore (quote (a b c d)) evaluates to:
(a b c d)
Hence we have a way to produce a literal list in a program, by using quote.
(cdr (print (cdr (print (cdr (print (quote (a b c d))))))))
(a b c d)
(b c d)
(c d)
(d)
But there is no quoted lists, no more that there is any quoted number
or quoted string or quoted anything. The only thing there is, is
some literal data in a program. And you should not modify any literal
data because that would mean modifying the program in some
uncontrolled way, and you'd get unpreditable results. But apart from
this, literal data is data like any other data.
--
__Pascal Bourguignon__ http://www.informatimago.com/
next prev parent reply other threads:[~2010-08-11 20:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-10 20:56 identity function with an echo side effect bolega
2010-08-10 23:03 ` Pascal J. Bourguignon
2010-08-11 5:01 ` bolega
2010-08-11 14:19 ` Pascal J. Bourguignon
2010-08-11 17:42 ` bolega
2010-08-11 20:43 ` Pascal J. Bourguignon [this message]
2010-08-12 2:35 ` TheFlyingDutchman
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bp98anht.fsf@kuiper.lan.informatimago.com \
--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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).