Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!igor!rutabaga!jls From: jls@rutabaga.Rational.COM (Jim Showalter) Newsgroups: comp.object Subject: Readability of Ada Message-ID: Date: 17 Apr 91 03:28:52 GMT Sender: news@Rational.COM Lines: 186 A short while ago, I posted an example of what I view as fairly typical C code and asked people what it did. Given that the code was, as usual, written with two-character "identifiers" and maximum utilization of C's cryptic syntax, it took people a while to figure out that the intent of the code was to compute the Julian date. Even then, all but a handful of people missed the two bugs planted in the code. Some attacked the example as a BAD example of C code, and the claim was made that C could be written quite readably (one poster claimed that C COULD be written as poetry). I asked for a representative sample of C poetry. None has been forthcoming (I'll settle for C++ poetry, if you prefer). One poster submitted a version of my original example that he felt was cleaned up--I thought it was still quite horrible; I also thought his belief that it was now okay was proof positive of what I'd been claiming about the C culture all along. Others challenged me to provide the same functionality in Ada, for comparative purposes. Very well--what follows is a skeleton of a Julian_Calendar package, written in Ada. I have not fleshed out the package with all the other functionality that would logically belong there (e.g. computation of what day of week it was on an arbitrary date, etc). [I have also stuck to the same basic algorithm as in the C example, to make the comparison straightforward--if I were really implementing a Julian_Calendar package for commercial consumption, I'd do so using a universal calendar algorithm, for speed.] The package does compile, execute, and give the correct results. In reviewing the example below, keep my claims in mind: 1) Programs are written for people, not for computers. PEOPLE, not computers, do maintenance and review code. It is the job of the COMPILER to translate human-readable code into machine- readable code: programmers who try to eliminate the middleman cost their company money (and write non-portable, non-reusable code). 2) The history of software engineering has been more profoundly warped by the simple fact that most programmers are only hunt-and-peck typists than by anything else. This explains constricted identifier names and an emphasis on notational compaction at the expense of understandability. Corollary: the term "verbose", applied to a programming language, is COMPLIMENTARY, not perjorative. 3) Some languages, by their very design and syntax, are superior to others in terms of support for readability. Writing as well as possible in C, one can still not write programs that are as readable and understandable as programs written in Ada by an equally competent programmer with the same objectives in mind. 4) C++ is scant improvement over C in terms of its support for readability. 5) A language does not exist independently from its culture. The culture that grew up around C is hackerish, egocentric, undisciplined, etc. The culture that has grown up around Ada is, like the language, software engineering oriented. I would be quite interested to see if anybody can write a C or C++ program to compute the Julian date that is as understandable as the Ada example shown below. I would also be interested in having the example below shown to beginning programmers (and even non-programmers) to see how readable it seems to them--and then the same experiment conducted with a version in C/C++. Finally, I'd like to see an example of this in Eiffel. =============================================================== package Julian_Calendar is -- Day stuff: subtype Day is Positive range 1 .. 31; type Names is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); subtype Weekdays is Names range Monday .. Friday; subtype Weekends is Names range Saturday .. Sunday; -- Month stuff: type Month is (January, February, March, April, May, June, July, August, September, October, November, December); type Days_Per_Month is array (Month) of Day; Normal_Year : constant Days_Per_Month := (January => 31, February => 28, March => 31, April => 30, May => 31, June => 30, July => 31, August => 31, September => 30, October => 31, November => 30, December => 31); Leap_Year : constant Days_Per_Month := (January => 31, February => 29, March => 31, April => 30, May => 31, June => 30, July => 31, August => 31, September => 30, October => 31, November => 30, December => 31); -- Year stuff: type Year is range 0 .. 2_000_000_000; function Is_Leap_Year (This_Year : in Year) return Boolean; -- Julian day stuff: subtype Julian_Day is Positive range 1 .. 366; function Julian_Day_For (This_Year : in Year; This_Month : in Month; This_Day : in Day) return Julian_Day; No_Such_Day : exception; end Julian_Calendar; package body Julian_Calendar is function Is_Leap_Year (This_Year : in Year) return Boolean is -- A leap year is any year evenly divisible by 4 that is -- not also evenly divisible by 400. begin return (This_Year mod 4 = 0) and not (This_Year mod 400 = 0); end Is_Leap_Year; function Julian_Day_For (This_Year : in Days_Per_Month; This_Month : in Month; This_Day : in Day) return Julian_Day is The_Day : Julian_Day := This_Day; begin if This_Year (This_Month) < This_Day then raise No_Such_Day; elsif This_Month = January then return The_Day; else -- Add up number of days in each month up to but not including -- the current month (current month is already taken care of -- by initial value of The_Day): for Current_Month in January .. Month'Pred (This_Month) loop The_Day := The_Day + This_Year (Current_Month); end loop; return The_Day; end if; end Julian_Day_For; function Julian_Day_For (This_Year : in Year; This_Month : in Month; This_Day : in Day) return Julian_Day is begin if Is_Leap_Year (This_Year) then return Julian_Day_For (Leap_Year, This_Month, This_Day); else return Julian_Day_For (Normal_Year, This_Month, This_Day); end if; end Julian_Day_For; end Julian_Calendar; -- * The opinions expressed herein are my own, except in the realm of software * * engineering, in which case I borrowed them from incredibly smart people. * * * * Rational: cutting-edge software engineering technology and services. *