[implementations-list] Why can't I byte-compile (all of) Vimpulse?
Hello Vimpulse Developers, First of all -- congratulations on the new release of Vimpulse, keep the great job! There is a question I wanted to ask since a few revisions ago -- it's nothing really important, I'm just curious about it. The fact is that whenever I try to compile at least one of the following: * vimpulse-modal.el * vimpulse-operator.el * vimpulse-text-object-system.el * vimpulse-visual-mode.el the whole Vimpulse stops working correctly. Of course, compiling the bundle (vimpulse_big.el) doesn't work either. My question is: is this normal, or is it just me? Do you guys byte-compile Vimpulse at all? I'm currently using: GNU Emacs 24.0.50.1 (i686-pc-linux-gnu, GTK+ Version 2.18.3) of 2010-03-22 Cheers, -- José A. Romero L. [email protected] "We who cut mere stones must always be envisioning cathedrals." (Quarry worker's creed)
There is a question I wanted to ask since a few revisions ago -- it's nothing really important, I'm just curious about it. The fact is that whenever I try to compile at least one of the following:
* vimpulse-modal.el * vimpulse-operator.el * vimpulse-text-object-system.el * vimpulse-visual-mode.el
the whole Vimpulse stops working correctly. Of course, compiling the bundle (vimpulse_big.el) doesn't work either. My question is: is this normal, or is it just me? Do you guys byte-compile Vimpulse at all?
Haha, obviously nobody does... I'm attaching a patch that fixes some of the trivial problems spotted by the byte-compiler (including typos). Some of the others are benign, and for the rest, deeper understanding of the code is needed (which I don't have): 1. vimpulse-modal.el:338:8:Error: Wrong type argument: integer-or-marker-p, key-vector Here the problem is clear -- `kbd' is a macro, so it's not gonna work compiled like that. Some refactoring is needed. 2. vimpulse-operator.el:464:16:Warning: reference to free variable `operator' The `vimpulse-operator-repeat' function definition seems to be broken, but not obviously enough for me to know how to fix it. There might be other problems -- I wondered once about byte-compiling, too, noticing some of the macros, defadvices, eval-after-loads etc., but we'll see after the basic ones are fixed (or maybe Vegard knows better already). Štěpán
Date: Tue, 27 Apr 2010 12:16:43 +0200 From: [email protected]
Do you guys byte-compile Vimpulse at all?
Haha, obviously nobody does...
I don't, since I code on it. Anyway, this is a serious defect. José, thanks for bringing it to my attention. Please grab the latest commit, [db43aaed4e], and try to compile as a single file. Multiple files should work too, provided Vimpulse is already loaded. Compiling as multiple files from vanilla Emacs currently fails, however. The dependencies are quite entangled, and Emacs doesn't like self-referencing feature requirements (this feature requires that feature which requires this feature). Since the files are to be concatenated, "later" features cannot be required earlier in the code, or the single file complains. So the code has to be laid out in a more linear fashion for compilation to work in all cases. Štěpán: thanks for the tips. I spotted both quite early on, but there was a lot more to it. Vegard _________________________________________________________________ Få nye Windows Live™ Messenger. http://download.live.com/messenger
On Tue, Apr 27, 2010 at 04:34:11PM +0000, Vegard Øye wrote:
Date: Tue, 27 Apr 2010 12:16:43 +0200 From: [email protected] Compiling as multiple files from vanilla Emacs currently fails, however. The dependencies are quite entangled, and Emacs doesn't like self-referencing feature requirements (this feature requires that feature which requires this feature). Since the files are to be concatenated, "later" features cannot be required earlier in the code, or the single file complains. So the code has to be laid out in a more linear fashion for compilation to work in all cases.
Actually I'm not sure you should even try to make it work -- isn't the current single-file scenario just pathological in this respect? I don't think it makes sense to have multiple features (i.e. `provide' forms) in a single file (this issue was mentioned before). If you want to compile the single file version, shouldn't you instead remove all the provides except `vimpulse' (and reorder the code so it will work, if needed)? (And I guess you know about the (provide 'foo) (require 'foo) trick mentioned in sec. 15.7 of the Elisp manual.)
Štěpán: thanks for the tips. I spotted both quite early on, but there was a lot more to it.
Yeah, it was more of an attempt to save you some typing when I already looked at the output of the compilation... Štěpán
Date: Tue, 27 Apr 2010 20:14:05 +0200 From: [email protected]
Since the files are to be concatenated, "later" features cannot be required earlier in the code, or the single file complains. So the code has to be laid out in a more linear fashion for compilation to work in all cases.
Actually I'm not sure you should even try to make it work -- isn't the current single-file scenario just pathological in this respect?
Quite so, but it's also the preferred distribution format as of currently. So single-file compilation must work, even if it means struggling with the following (hope I got this right): When a file is compiled, it is /not/ evaluated, except for `defmacro' calls and `require' statements. However, if the compiled file requires other files, those files /are/ evaluated. This means, amongst other things, that if you compile a file which defines some variables with `defvar' and /uses/ those variables, you will get warnings about free variables. Those `defvar' declarations are not evaluated. The preferred way to handle this seems to be to place all the declarations in a separate file and then require it, forcing evaluation. (In Viper's case, that file is viper-init.el.) vimpulse-big.el can't do that, of course, since it's a single file. So there's another and uglier way to force evaluation during compilation: wrap the code in (eval-and-compile ...). Of course, you still have to do this /before/ you actually use the variables. (Interestingly, `defmacro' calls are evaluated regardless. This is so the compiler can substitute the macro expansion for subsequent macro calls. Why couldn't it make the same exception for `defvar'? According to the Reference, section 16.6, [Y]ou can tell the compiler that a variable is defined using `defvar' with no initial value. But it doesn't mention the need for using `eval-and-compile' in the compiled file! Way confusing.) So, yeah, vimpulse-big.el. If I got this right, I'll have to define all variables at the beginning of the code, wrapped in (eval-and-compile ...), to silence the compiler completely. Right now it complains a lot (warnings), although it does produce the .elc.
I don't think it makes sense to have multiple features (i.e. `provide' forms) in a single file (this issue was mentioned before). If you want to compile the single file version, shouldn't you instead remove all the provides except `vimpulse' (and reorder the code so it will work, if needed)?
If it could be automated, sure. All the makefile would have to do is remove the last two lines of every file (one `provide' statement and one blank line) before concatenating them. Do you think that's possible as stated, or would one have to use awk or sed and search for "(provide "? (I've never used awk or sed.) Vegard _________________________________________________________________ Windows 7: Du får hjelp til gjøre mer. Utforsk Windows 7. http://windows.microsoft.com/windows-7
On Wed, Apr 28, 2010 at 12:52:43PM +0000, Vegard Øye wrote:
When a file is compiled, it is /not/ evaluated, except for `defmacro' calls and `require' statements. However, if the compiled file requires other files, those files /are/ evaluated. This means, amongst other things, that if you compile a file which defines some variables with `defvar' and /uses/ those variables, you will get warnings about free variables. Those `defvar' declarations are not evaluated. The preferred way to handle this seems to be to place all the declarations in a separate file and then require it, forcing evaluation. (In Viper's case, that file is viper-init.el.)
No; when a file is compiled, *all* the macros are expanded (i.e. evaluated); that's one of the points of macros, after all -- to be expanded at compile time, not run time. And `defvar's are recognized by the compiler, too, so you definitely should *not* get any warnings, as long as all the `defvar's are put before the variables are first used.
vimpulse-big.el can't do that, of course, since it's a single file. So there's another and uglier way to force evaluation during compilation: wrap the code in (eval-and-compile ...). Of course, you still have to do this /before/ you actually use the variables.
(Interestingly, `defmacro' calls are evaluated regardless. This is so the compiler can substitute the macro expansion for subsequent macro calls. Why couldn't it make the same exception for `defvar'? According to the Reference, section 16.6,
[Y]ou can tell the compiler that a variable is defined using `defvar' with no initial value.
But it doesn't mention the need for using `eval-and-compile' in the compiled file! Way confusing.)
Yeah, it doesn't mention that because it is not the case AFAIK, see above.
So, yeah, vimpulse-big.el. If I got this right, I'll have to define all variables at the beginning of the code, wrapped in (eval-and-compile ...), to silence the compiler completely. Right now it complains a lot (warnings), although it does produce the .elc.
I don't think it makes sense to have multiple features (i.e. `provide' forms) in a single file (this issue was mentioned before). If you want to compile the single file version, shouldn't you instead remove all the provides except `vimpulse' (and reorder the code so it will work, if needed)?
If it could be automated, sure. All the makefile would have to do is remove the last two lines of every file (one `provide' statement and one blank line) before concatenating them. Do you think that's possible as stated, or would one have to use awk or sed and search for "(provide "? (I've never used awk or sed.)
I don't think `make' can do that on its own -- `cat' is an external program, too ;-). You could e.g. just replace `cat' in the makefile with sed "/^(\(provide\|require\) 'vimpulse-/d" That would do what `cat' does, except for all lines providing or requiring 'vimpulse-something, i.e. it would leave `(provide 'vimpulse)' in. Štěpán
Date: Wed, 28 Apr 2010 16:06:35 +0200 From: [email protected]
According to the Reference, section 16.6,
[Y]ou can tell the compiler that a variable is defined using `defvar' with no initial value.
But it doesn't mention the need for using `eval-and-compile' in the compiled file! Way confusing.)
Yeah, it doesn't mention that because it is not the case AFAIK, see above.
You're right, it isn't. Phew! I can't tell you how relieved that makes me. :) On closer inspection, `defvar' statements in the compiled file are indeed recognized by the compiler (even if they are part of macro expansions), but they aren't evaluated. So if you have a macro which depends on the /value/ of a same-file variable to produce its expansion, you do need to use `eval-and-compile'. (Vimpulse doesn't have this, but the test code I wrote did.) Anyway, I moved all variable definitions to vimpulse-dependencies.el in commit [c757a0e4ff], and that helped things immensely.
All the makefile would have to do is remove the last two lines of every file (one `provide' statement and one blank line) before concatenating them.
You could e.g. just replace `cat' in the makefile with
sed "/^(\(provide\|require\) 'vimpulse-/d"
Thanks for this! Added in commit [701ac452c9]. Vegard _________________________________________________________________ Nye Windows 7: PCen som passer for deg. Finn ut mer. http://windows.microsoft.com/shop
On Wed, Apr 28, 2010 at 07:50:55PM +0000, Vegard Øye wrote:
According to the Reference, section 16.6,
[Y]ou can tell the compiler that a variable is defined using `defvar' with no initial value.
But it doesn't mention the need for using `eval-and-compile' in the compiled file! Way confusing.)
Yeah, it doesn't mention that because it is not the case AFAIK, see above.
You're right, it isn't. Phew! I can't tell you how relieved that makes me. :)
On closer inspection, `defvar' statements in the compiled file are indeed recognized by the compiler (even if they are part of macro expansions), but they aren't evaluated. So if you have a macro which depends on the /value/ of a same-file variable to produce its expansion, you do need to use `eval-and-compile'. (Vimpulse doesn't have this, but the test code I wrote did.)
Anyway, I moved all variable definitions to vimpulse-dependencies.el in commit [c757a0e4ff], and that helped things immensely.
Great.
All the makefile would have to do is remove the last two lines of every file (one `provide' statement and one blank line) before concatenating them.
You could e.g. just replace `cat' in the makefile with
sed "/^(\(provide\|require\) 'vimpulse-/d"
Thanks for this! Added in commit [701ac452c9].
Yeah, sed & AWK are fun, although unfortunately I rarely use them and am far from proficiency in either one. The renowned one-liner files might be of interest: http://www.osnews.com/story/21004/Awk_and_Sed_One-Liners_Explained BTW, good luck with the "trailing newlines" removal -- are you now going to unset `require-final-newline' every time you edit the files? ;-) Štěpán
Date: Wed, 28 Apr 2010 23:01:31 +0200 From: [email protected]
BTW, good luck with the "trailing newlines" removal -- are you now going to unset `require-final-newline' every time you edit the files? ;-)
Erm, bad commit message. Originally, each file had /two/ trailing newlines (i.e., a blank line at the end), while with the updated Makefile they only need one. Vegard _________________________________________________________________ Windows 7: Se direkte-TV fra den bærbare PCen. Finn ut mer. http://windows.microsoft.com/windows-7
On Wed, Apr 28, 2010 at 09:08:20PM +0000, Vegard Øye wrote:
Date: Wed, 28 Apr 2010 23:01:31 +0200 From: [email protected]
BTW, good luck with the "trailing newlines" removal -- are you now going to unset `require-final-newline' every time you edit the files? ;-)
Erm, bad commit message. Originally, each file had /two/ trailing newlines (i.e., a blank line at the end), while with the updated Makefile they only need one.
Heh, yeah it's obvious from the diff... it's just me being silly again. Sorry for the noise. Štěpán
2010/4/27 Vegard Øye <[email protected]>:
Date: Tue, 27 Apr 2010 12:16:43 +0200 From: [email protected]
Do you guys byte-compile Vimpulse at all?
Haha, obviously nobody does...
I don't, since I code on it.
Anyway, this is a serious defect. José, thanks for bringing it to my attention. Please grab the latest commit, [db43aaed4e], and try to compile as a single file. Multiple files should work too, provided Vimpulse is already loaded.
(...) Great. I have just pulled the latest revision, built vimpulse‐big.el, compiled it (with only one minor warning), modified my load path and restarted emacs. So far Vimpulse seems to be working OK. I will keep you informed if I notice anything weird in the next few days. Thanks. Cheers, -- José A. Romero L. [email protected] "We who cut mere stones must always be envisioning cathedrals." (Quarry worker's creed)
participants (3)
-
José A. Romero L. -
Vegard Øye -
Štěpán Němec