* Re: Why (eval-when-compile (require 'foo)) does not bind functions during compilation?
[not found] <mailman.180.1440909671.19560.help-gnu-emacs@gnu.org>
@ 2015-08-30 7:23 ` Pascal J. Bourguignon
2015-08-30 19:18 ` Barry Margolin
0 siblings, 1 reply; 4+ messages in thread
From: Pascal J. Bourguignon @ 2015-08-30 7:23 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski <mbork@mbork.pl> writes:
> As in the subject. The manual says that it does define macros from the
> library “foo”, but not functions. Why is that so? I would think that
> the above form actually evaluates the (require 'foo) part during
> compilation, so in particular it should evaluate all the defuns there –
> but both experiments and manual confirm that I’m wrong. Where is my
> mental model incorrect?
Your mental model should be that compilation is reading data and
producing data, and there's no reason for that process to modify the
compiler.
A compiler is a machine like that:
+--------------------------------+
| source ---> object |
| language language |
+---------+ +---------+
| |
| |
| |
| machine |
| language |
+------------+
+------------+
\ machine /
\language/
\ / <-- machine
\ /
\ /
\/
It takes a program written in the source language:
+-----------+
| program 1 |
| |
| |
| |
| source |
| language |
+-----------+
+--------------------------------+
| source ---> object |
| language language |
+---------+ +---------+
| |
| |
| |
| machine |
| language |
+------------+
+------------+
\ machine /
\language/
\ / <-- machine
\ /
\ /
\/
And produce an equivalent program in object language:
+-----------+ +-----------+
| program 1 | | program 1 |
| | | |
| | | |
| | --> | |
| source | | object |
| language | | language |
+-----------+ +-----------+
+--------------------------------+
| source ---> object |
| language language |
+---------+ +---------+
| |
| |
| |
| machine |
| language |
+------------+
+------------+
\ machine /
\language/
\ / <-- machine
\ /
\ /
\/
There's no reason to incorporate this program in object language into
the compiler itself. For one thing, it's possible the object language
and the machine language to be different, so there would be no use of
merging them. For another, you could be compiling a function of a new
version of the compiler, and if you merged it with the running compiler,
you could easily break it.
+------------------------------+ +------------------------------+
| source ---> object | -> | source ---> object |
| language language | | language language |
+---------+ +---------+ +---------+ +---------+
| | | |
| | | |
| | | |
| source | | object |
| language | | language |
+----------+ +----------+
+-----------------------------------------------+
| source ---> object |
| language language |
+----------------+ +-----------------+
| |
| |
| |
| machine |
| language |
+------------+
+------------+
\ machine /
\language/
\ / <-- machine
\ /
\ /
\/
Therefore it's a good feature that compiling a function doesn't install
it in the environment used to compile it.
Instead, you should use load to instal compiled functions into the
run-time environment, after compiling:
(load (byte-compile-file "source.el"))
(load "source.elc")
Of course, the case of macros is different since they are explicitely
and well delimited compiler hooks. The compiler has to take them into
account, to be able to further process the source. And those macros may
need to use to compute their expansion some functions defined in that
source, therefore you should either load those functions before using
the macros, in a separate file, compiling and loading each file in
turn, or using eval-when-compile to define those functions.
Which is exactly the opposite of what you say it does. I don't know what
documentation you're reading, but it's wrong.
----(example.el)----------------------------------------------------------------
(eval-when-compile
(defun gen-form (x)
`(progn
(insert ,(format "%S" x) "\n")
(insert ,(format "%S" x) "\n")
',x)))
(defmacro m (x)
(gen-form x))
(defun f ()
(m "life?")
(m 42))
--------------------------------------------------------------------------------
(byte-compile-file "~/Desktop/example.el")
(gen-form '(+ 30 3))
--> (progn (insert "(+ 30 3)" "
") (insert "(+ 30 3)" "
") (quote (+ 30 3)))
;; The object defined in eval-when-compile are incorporated into the
;; compiler environment.
(f) --> Debugger entered--Lisp error: (void-function f)
;; The others are not (unless they're macros). The compiler still notes
;; that f will be fbound though.
(load "~/Desktop/example.elc")
(f)
inserts:
"life?"
"life?"
42
42
--> 42
--
__Pascal Bourguignon__ http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk
^ permalink raw reply [flat|nested] 4+ messages in thread