ruffwork@orstcs.CS.ORST.EDU (Ritchey Ruff) (12/08/87)
Would you use a language that can arbitrarily ignore some of your code ??? Especially if different implementations ignored different statements in the same code ??? Even if it didn't TELL you what it was ignoring when ??? I have a bone to pick with Steele about something he left out of the Common Lisp definition. The above is *EXACTLY* what Common Lisp *DOES* !!! In the sections about the strong typing, "Common Lisp:The Language" says the compiler or interpreter can ignore many declarations. It should also state that there be a standard way to find out WHAT the compiler/ interpreter is ignoring (or using). Something like a compiler flag (":declares-ignored t/nil") or a global flag (*IGNORED-WARNINGS*) to force common lisp to show what it is ignoring. Why, you ask??? First, principle (I kind of like that ;-): when you put in strong typing statements (like "(the integer foo)") do you REALLY want them ignored in different ways, at different times, by different Common Lisps - and not even know which is ignoring what when ??? Second, I've just spent weeks tracking bugs caused by compilers/interpreters ignoring different parts of my declarations. Simply because an interpreter/compiler can IGNORE strong typing (like "(the integer foo)"), optimizer statements (like safety=3), and declarations (like "(declare (integer foo))") I found that code that ran ok on one version of Common Lisp would not even compile under another, run but go into a break on another, and run to completion but give wrong results on another !!!! For example - lots of people use Bill Shelters' excellent SLOOP looping macro package (thanks for all that work you put into an excellent package, Bill!). Its great, but because it tries to optimize (by default it expands with declarations that give type info on looping vars, etc.) it turns out to be non-portable. Here is a totally non-portable piece of code - (DEFUN TST (N M) (SLOOP FOR I FROM N TO M COLLECT I)) This is quite simple, right? When it expands N, M, and I get declared of type integer, and the iteration var gets checked by the "THE" statement each time it's incremented to see that it remains of type integer. Below are results from several different Common Lisps (all this was done with safety=3) --- ---------------------------------------- FranzExtendedCommonLisp> (tst 1 5) (1 2 3 4 5) FranzExtendedCommonLisp> (tst 1.0 5.0) Continuable Error: Object 2.0 is not of type FIXNUM. If continued with :continue, Prompt for a new object. [1c] <cl> ^D FranzExtendedCommonLisp> (compile 'tst) TST FranzExtendedCommonLisp> (tst 1.0 5.0) (1.0 2.0 3.0 4.0 5.0) FranzExtendedCommonLisp> (tst 1 5.0) (1 2 3 4 5) ---------------------------------------- KyotoCommonLisp> (tst 1 5) (1 2 3 4 5) KyotoCommonLisp> (tst 1.0 5.0) Error: 2.0 is not of type FIXNUM. Error signaled by THE. Broken at THE. Type :H for Help. KyotoCommonLisp>> :q KyotoCommonLisp> (compile 'tst) End Pass1. End Pass2. TST KyotoCommonLisp> (tst 1.0 5.0) (0) KyotoCommonLisp> (tst 1 5.0) NIL ---------------------------------------- AllegroCommonLisp> (tst 1 5) (1 2 3 4 5) AllegroCommonLisp> (tst 1.0 5.0) (1.0 2.0 3.0 4.0 5.0) AllegroCommonLisp> (compile 'tst) TST AllegroCommonLisp> (tst 1.0 5.0) (1.0 2.0 3.0 4.0 5.0) AllegroCommonLisp> (tst 1 5.0) (1 2 3 4 5) ---------------------------------------- So we have 3 different "Common Lisps" (and the quotes are intentional) that give radically different results for the SAME code !!! EVEN the interpreter (Help me, Spock ;-) !!! If the compiler and interpreter gave warnings when they ignored code the reason for the bugs that this type of behavior can cause would be so much easier to track down. When you have your code debugged and are looking for raw speed, a global flag could be set to stop displaying warnings of this type. MORAL OF THE STORY --- IF YOU WANT TRULY PORTABLE COMMON LISP CODE THAT WORKS THE SAME INTERPRETED AS COMPILED, *DO* *NOT* PUT STRONG TYPING OR OPTIMIZER STATEMENTS ANYWHERE IN YOUR CODE !!! IF *ANYTHING* *CAN* IGNORE A STATEMENT, *NEVER* USE THAT STATEMENT !!! I've gone on too long, but I think I've made my point. Thanks for the bandwidth, --Ritchey Ruff ruffwork@cs.orst.edu -or- "I haven't lost my mind, ruffwork%oregon-state@relay-cs-net -or- its' backed up on tape somewhere..." { hp-pcd | tektronix }!orstcs!ruffwork
kers@otter.HP.COM (Christopher Dollin) (12/09/87)
Re: > I have a bone to pick with Steele about something he left out of > the Common Lisp definition. The above is *EXACTLY* what Common > Lisp *DOES* !!! In the sections about the > strong typing, "Common Lisp:The Language" says the compiler > or interpreter can ignore many declarations. It should also > state that there be a standard way to find out WHAT the compiler/ > interpreter is ignoring (or using). Something like a compiler flag > (":declares-ignored t/nil") or a global flag (*IGNORED-WARNINGS*) to > force common lisp to show what it is ignoring. [etc] Doesn't Steel say that a program that violates type declarations "is in error" and that an implementaion is "encouraged but not required to detect such an error"? Your program is in error. As such, all bets are off. The latitude Steele permits to implementations is to allow them freedom to be efficient in their different contexts. Disclaimer: I HATE Common (Vulgar) Lisp. There are many worse things to complain about in it. In general, you need those type "declarations" (really they're "promises") to get fast enough code. By the way ... you, I, and most everyone else I know blames Steele for the problems of VL. It's not *all* his fault, just because he edited The Book. No single individual could make design a language *that* bad ... Regards, Kers | "Why Lisp when you can speak Poperly?"