From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,83242c369c5dc9b0 X-Google-Attributes: gid103376,public From: ok@goanna.cs.rmit.EDU.AU (Richard A. O'Keefe) Subject: Re: Book REview Date: 1996/05/09 Message-ID: <4msdf9$oc7@goanna.cs.rmit.EDU.AU> X-Deja-AN: 153862457 references: <4mk0vc$opp@goanna.cs.rmit.edu.au> <4mmfsu$b30@goanna.cs.rmit.EDU.AU> <4mp9j5$fs2@felix.seas.gwu.edu> organization: Comp Sci, RMIT, Melbourne, Australia keywords: textbook, cs1, review newsgroups: comp.lang.ada nntp-posting-user: ok Date: 1996-05-09T00:00:00+00:00 List-Id: mfeldman@seas.gwu.edu (Michael Feldman) writes: >There is some validity to your complaint about a US bias in the >text; it is odd, though, that the first edition of this book was >published nearly 5 years ago, and has been used by courses and >individuals around the world (including Australia), but nobody has >mentioned the US bias. In Australia there is something called "The cultural cringe". There is a widespread attitude that if things are different overseas they must be better, so it's our fault. >That said, >(1) I think the tone of your review is a bit harsh; On the same day I received four books for review. One was "The Little Schemer". I haven't looked very far into that one yet. "The Little Lisper" was a *great* book except for its "all the world is America and there are no Jews or Muslims" attitude. That's an MIT Press example. The other three all came from Addison-Wesley. Two of them were C textbooks by the same pair of authors. They had some good topics, and good or very good presentation, but in one 25-line example I found 8 outright errors, and a large chunk of one chapter is devoted to explaining a technique which has never been legal in ANSI C, and is likely to cause trouble in segmented architectures. I am talking _really_ bad. Frankly, I was outraged. So, I turned to your book. Imagine a poet turning from looking at a disgusting monster, to look in relief at a beautiful woman, and then he sees lice wandering over her face. I was angry: * for myself: it was such a disappointment * for our students: this _could_ have been such a big help to them * for you: there are no really fundamental problems that I can see with the book, the proof-reading and formal review process let you down. This may not _excuse_ the tone of the posting, but perhaps it _explains_ it. Let me publicly apologise for the tone. >(2) I don't think I'd ever write a review as critical as yours without > at least sending a cc to the author; that would just be courteous. >I don't read CLA every day (the signal/noise ratio is getting too low >and I've been very busy), and so I was caught quite by surprise when >a CLA acquaintance pointed me to your review. I see that I must apologise again. I had thought of you as a regular CLA reader, so I was (without, it turns out, adequate reason) quite sure that you would see it. It was certainly my _intent_ that you would see it. >You are, of course, entitled to your opinion, and I am thick-skinned >enough to handle a bad review. The thing that still has me angry is that at one level it _isn't_ (or isn't meant as) a bad review of the "World 3" book. It's really an angry review of the _proofreading_ and _review_ processes. How come such a well planned book by such great authors ended up with a flawed result? (By the way, talk to Addison-Wesley about the binding. I have had my copy for less than a week; I have handled it gently; but the back cover now resembles a capital C.) I am upset because I want to use the book you wanted to publish. >On the other hand, there's no need to blindside the >author by not even sending him a copy to respond to. As I have explained, I did not mean to blindside you. (I don't actually know what that means, but I think it means something like "do something behind your back".) I thought of posting to CLA as, amongst other things, an efficient way to get you a copy. I apologise again for being stupid about that. >Indeed, had you been courteous enough to ask me for an errata list, >I would have been happy to send it to you. To be honest, it appears I have been stupid again. It never occurred to me that a newly published book would _have_ an errata list, or that Addison-Wesley would have withheld it from a reviewer if it had. In my own defence, I can only say that I *did* visit http://www.aw,com/cseng/authors/feldman/cs1-ada2e/cs1-ada2e.sup.html and found the only supplements to be the source files in .tar.Z format for UNIX and .zip format for Dos,Windows,OS/2. There was no hint of the present or likely future existence of an errata sheet there, so I supposed there was none. I failed to download the sources "Transaction timeout". I've had a lot of trouble trying to download such sources from aw.com. >'Nuff said. Let me drag this out by pointing out one more example. I mentioned the "in Character range 'A' .. 'Z'" method of testing whether something is an upper case letter, and pointed out the flaw. I was considerably startled when the book fell open at page 466 just now, and I saw "FOR c IN UpperCase LOOP". Honest, the book did fall open at that page without any prompting. I then discovered that the example I quoted before wasn't an isolated slip. p463 Problem Specification --------------------- Write a program which draws a histogram for the frequency of occurrence of the letters of the alphabet. Uppercase and lowercase letters are to be counted separately; nonletter characters can be ignored. p785 PACKAGE Ada.Characters.Handling IS ... FUNCTION Is_Lower (Item: IN Character) RETURN Boolean; FUNCTION Is_Upper (Item: IN Character) RETURN Boolean; This seems like the perfect opportunity to point out that "the alphabet" in Ada 95 is ISO Latin 1 and that it contains a lot of letters and that there are some standard functions for handling them, and that a good way to handle this problem is type Character_Count_Table is array (Character) of Natural; Uppers: Character_Count_Table := (others => 0); Lowers: Character_Count_Table := (others => 0); Ch : Character; ... while not Ada.Text_IO.End_Of_File loop while not Ada.Text_IO.End_Of_Line loop Ada.Text_IO.Get(Ch); if Ada.Characters.Handling.Is_Upper(Ch) then Uppers(Ch) := Uppers(Ch) + 1; end if; if Ada.Characters.Handling.Is_Lower(Ch) then Lowers(Ch) := Lowers(Ch) + 1; end if; end loop; Ada.Text_IO.Skip_Line; end loop; ... for C in Character loop if Ada.Characters.Handling.Is_Lower(C) then Draw_Bar(Lowers(C)); end if; end loop; Draw_Bar(0); for C in Character loop if Ada.Characters.Handling.Is_Upper(C) then Draw_Bar(Uppers(C)); end if; end for; ... for C in Character loop if Ada.Characters.Handling.Is_Lower(C) then Ada.Text_IO.Put(C); end if; end loop; Ada.Text_IO.Put(' '); for C in Character loop if Ada.Characters.Handling.Is_Upper(C) then Ada.Text_IO.Put(C); end if; end for; ... Instead, the text goes out of its way to hammer home the unintended lesson that the 52 unaccented letters are the only letters in Ada and that all the upper case letters are contiguous and all the lower case letters are contiguous. - Uppers and Lowers in the book have non-overlapping index ranges, which won't work in Ada 95 if you try to handle _all_ letters. - the input loop in the book uses a CASE statement, and while an IF statement could have been adapted to Ada 95 letters, the CASE statement cannot. - the letters at the bottom of the display are in a string literal instead of being computed as above. Taken literally, in the context of Ada 95, the program of Figure 9.4 does not meet its specification. Do we call this a cultural matter (there are only 52 letters in the world) or a technical matter (there are only 52 letters in Ada)? Well, my father's name and my sister-in-law's name cannot be represented in ASCII, and they are both of British descent, and their names are genuine (not made up) names. Perhaps it is a cultural matter. On the other hand, in Ada 95 there are 114 letters, not 52, so perhaps it is a technical matter. Certainly, there are coding techniques that used to work in ASCII that no longer work, and one of the good things about Ada 95 is that it gives us the tools to do the job properly. Now, for this example, the histogram will only work if you have 120 columns on your screen, because 114 columns + a bit is more than will fit on an 80-column screen. Is it a good idea to restrict attention to the American letters so that the display will fit on the screen? Or is that another easy hack that breaks when you try to handle the full Ada 95 character set? I honestly don't know, and I'm glad it wasn't my decision. (Actually, my decision would have been to map upper case letters to lower case. I can now see that that would have been the wrong decision, because it merely delays the problem; my kluge won't adapt to Wide_Character.) Am I being paranoid about a minor point? Well, I have two 2nd-year C tutorials on Thursdays. I asked them "What can you tell me about this method of checking for an upper case letter in C? if ('A' <= x && x <= 'Z') ..." The only suggestion I got was "it needs more parentheses" (which of course it doesn't). I explained that the system they are using (a SPARC running Solaris, with X11) is configured to use an 8-bit character set, which has a lot more capital letters than 26, and that the PC systems some of them use at home has a _different_ 8-bit character set, which also has more upper case letters than 26. Next I asked "Can you suggest a way to test for _any_ upper case letter?" Some of them had K&R2 with them. It took some _very_ heavy hinting to get them to look in the index. Finally they understood that #include ... if (isupper(x)) ... would do the job. Next question: "Will you use this?" The answer: "The book doesn't; why should we?" (The book not= K&R2) The lesson for Ada text-book authors? "The book doesn't; why should we?" I checked the index of the Ada95 book. I could not find "letter", "Is_Upper", "Is_Lower", "case, alphabetic", "lower case" in the index, and the sole reference to "upper" was "uppercase and lower case, use of". Is it reasonable to tell the whole truth in a CS 1 textbook? No, it is not reasonable; it is not possible. Is it reasonable to omit any mention of the fact that the character set used by the language includes more letters than the American 26? Well, a _lot_ of CS1 books include a chart of the ASCII characters, and a chart listing all of the members of Character in Ada 95 would require only a one page appendix. In fact there _is_ an appendix "The Ada Character Set..." which says "a number of additional characters to provide for the additional letters used in non-English languages" but doesn't say what they _are_. A very small change to the book would eliminate most of my objections about letters and ranges thereof. (1) Change the third sentence in appendix A to say "This character set includes the usual upper case (A-Z) and lower case (a-z) letters. It also includes many other letters useful in some European languages, including English. For example .... Ada 95 identifiers should not use any of these extra letters. The examples in this book just use the letters found on US keyboards; if you want to use the other letters, you will have to find out locally how to get them on your computer or keyboard, AND YOU WILL HAVE TO CHANGE THE PROGRAMS." (2) Somewhere about here in appendix A, say "Ada 95 programs can tell what kind of character they have been given by using the functions in Ada.Characters.Handling whose names begin with 'Is_'; see appendix G." (3) At the end or appendix A, add a chart with all the ISO Latin 1 characters. I've seen it printed legibly on half a page. (4) Whenever the current text says or implies that A-Z a-z are the only letters, add a footnote "* Strictly speaking, there are 114 letters. See Appendix A." or something of the kind. (5) Put "letter", "letter, upper case", "letter, lower case" in the index, pointing to appendix A _and_ to all the examples in the main text that talk about letters. While I was looking for "letter" in the index, I found CASE STUDY: FINDING THE ALPHABETICALLY FIRST LETTER on p141. Now, the book is elsewhere quite clear that only the 52 character A-Z, a-z count as letters. I am rather sensitive to this issue because last year when I tutored the CS 1 class, an assignment required students to read "letters", and there was massive confusion. It turned out that, as here, the author meant by "letter" "any character whatsoever, whether it is a letter or not". The Ada code in program 4.2 - reads arbitrary characters, not letters. - does not check that they are letters. - does not compare the characters "alphabetically", but according to their codes in ISO Latin 1. This matters, because 'a' < 'F' _alphabetically_, because A precedes F in the (English) alphabet -- there is historic precedent for considering & to be part of the English alphabetic, for what it's worth -- but it's 'tother way around in ISO Latin 1. The alphabetically first _letter_ amongst "Ma!" is "a". The program will report '!'. The alphabetically first letter amongst "Max" is "a". The program will report 'M'. Surely a does come before m in the alphabet? Rename the case study to Finding the character with the smallest code replace "letter" by "character", "alphabet" by "character set", and the objection vanishes because the confusion vanishes. I am _not_ going to quarrel with the decision to use two IF statements instead of just AlphaFirst := Character'Max(Character'Max(Ch1, Ch2), Ch3); because it's a perfectly good educational decision to postpone details like 'Max to CS2. -- Fifty years of programming language research, and we end up with C++ ??? Richard A. O'Keefe; http://www.cs.rmit.edu.au/~ok; RMIT Comp.Sci.