Ingewijden zien Eiffel als een superieure objectgeoriënteerde programmeertaal, die hoog uittorent boven C++, Smalltalk, Object Pascal of Java. De taal bestaat al ruim tien jaar en mag gerenommeerde namen tot haar gebruikers rekenen. Toch is zij nauwelijks bekend. Hoe kan dat? Is Eiffel gedoemd tot het voortbestaan als exotische curiositeit, vraagt een consultant zich af, of heeft zij de toekomst als een nieuwe Cobol?
Achter de lessenaar staat een man met grijzende krullen en een donkere bril, montuur ’72. Hij spreekt met een zwaar Frans-Amerikaans accent. Een beginnend buikje getuigt van wat de overgang van nouvelle cuisine naar een ‘Burger’-dieet aan het postuur van een veertiger aanricht. De man is een doorgewinterd spreker.
Zijn betoog is systematisch en stap voor stap opgebouwd. Hij doceert technische kost maar weet zijn publiek met pakkende voorbeelden en geestige tussenwerpsels bij de les te houden. Het type professor. Erudiet en polyglot. Niet te beroerd voor een citaatje Goethe of Montaigne hier en daar. Als de presentatie op zijn laptop plotseling crasht en hij even van zijn stuk raakt, herstelt hij zich met een beroep op zijn grondwettelijk recht op een stukje Microsoft-‘bashing’ op z’n tijd. Bertrand Meyer spreekt over kwaliteitssoftware.
Onvervulde belofte
Zijn toehoorders vormen een bont gezelschap. Ontwikkelaars van radarsystemen voor het Amerikaanse ministerie van Defensie. Een Indiër werkzaam voor de belangrijkste agrarische termijnmarkt ter wereld. Een docente aan een Iers technologie-instituut. Een Japanner die werkt voor een van ’s wereld grootste chipbakkers. Vijf jonge Franse softwarespecialisten die net zijn aangenomen om een compiler te optimaliseren. Een systeembeheerder van een Amerikaanse tapijtgarenfabrikant. En een Hollandse IT-adviseur, de schrijver dezes. Zij hebben twee dingen gemeen: de wens om de oude maar nog immer onvervulde belofte van industriële kwaliteitssoftware in te lossen, en een kritische houding tegenover de eerste de beste goeroe die weer eens het ware geloof komt verkondigen.
Wat is software-kwaliteit? Dat is software die correct is en robuust. Correct wil zeggen dat een softwaresysteem exact aan de specificaties beantwoordt. Robuust houdt in dat het systeem zich op een redelijke manier gedraagt in situaties die niet door de specificaties worden gedekt. Dat zegt nog niet veel. Waar het echt om gaat is: hoe produceren we kwaliteitssoftware, en dat tegen een aanvaardbare prijs? Vraag een civiel ingenieur hoe een kwaliteitsbouwwerk tot stand komt en hij antwoordt: met hoogwaardige materialen, het beste gereedschap en een goed bestek. En met een toegewijde en competente ploeg vaklui. Vertaal dit naar de bouw van softwaresystemen en we hebben het over de softwarecomponenten, de programmeertaal en de ontwikkelmethode. En die ploeg vaklui natuurlijk, want zelfs met de beste spullen kan prutswerk worden gemaakt.
Componenten
Component based development is een van de laatste buzzwords in onze van anglicismen vergeven branche. Zoals zo vaak gaat het hier om een oud begrip in een nieuw jasje. Componenten zijn niets anders dan met objectgeoriënteerde technieken ontwikkelde softwaremodules. Willen zij als hoogwaardig bouwmateriaal voor kwaliteitssoftwaresystemen dienst doen, dan moeten ze aan een aantal eisen voldoen. Naast efficiency zijn correctheid, herbruikbaarheid en uitbreidbaarheid elementair.
In zijn onlangs in Den Haag gehouden NWO/Huygenslezing beargumenteerde Tony Hoare, inmiddels een legende in de computerwetenschap, dat de correctheid van softwarecomponenten niet met statistische technieken, via steekproefsgewijs testen is vast te stellen. Softwareproducten zijn formele systemen waarvan de correctheid in theorie wèl wiskundig te bewijzen valt. Dat we daar in de dagelijkse praktijk nauwelijks in slagen, zegt Hoare met zoveel woorden, komt doordat de meeste softwarecomponenten niet naar mathematisch model, als abstract datatype met precieze specificatie van de geldige bewerkingen en axioma’s (asserties), zijn vormgegeven. Eigenlijk zouden asserties formeel in de softwaretekst vastgelegd moeten zijn.
Ook voor het hergebruik van componenten is een precieze specificatie en de aanwezigheid van asserties van belang. Wie niet precies weet wat een component doet en onder welke omstandigheden, zal niet snel tot hergebruik geneigd zijn.
Uitbreidbaarheid tenslotte is essentieel omdat componenten vaak wel in grote lijnen maar niet altijd exact doen wat de hergebruiker wil. Een component moet daarom aan diens wensen kunnen worden aangepast.
De programmeertaal
Het gereedschap om componenten te maken, te modificeren en tot een systeem aaneen te smeden is de programmeertaal. De ideale taal heeft de volgende kenmerken. Voor een optimale betrouwbaarheid: een assertiemechanisme als taalconstructie, waarmee de geldigheid van de aanroep door cliënten (precondities) en de uitkomst van bewerkingen (postcondities en invarianten) tijdens testen of desgewenst in ‘runtime’ worden bewaakt. Een soort semantische ‘debugger’ dus.
Verder statische typering om mogelijke ‘runtime type errors’ al tijdens compileren af te vangen, en een complete en consistente ‘garbage collector’ die loslopende objecten in de achtergrond opruimt en ongebruikt geheugen aan het besturingssysteem teruggeeft. Voor een optimaal hergebruik is van belang dat componenten als generieke types gedefinieerd kunnen worden. Dit om te vermijden dat we voor containerstructuren met een afwijkende inhoud telkens een nieuwe component moeten bouwen. Liever één ‘array’-klasse van het algemene type G dan een hele serie voor het verwerken van ‘strings’, ‘integers’, medewerkers, artikelen enzovoorts.
En dan, hoe leesbaarder de code, des te makkelijker het hergebruik. Een leesbare taal bevat een minimum aan verschillende taalconstructies, vermijd ‘onnatuurlijke’ symbolen en sluit spaghetticode uit. Dus géén globale variabelen, ‘main program’, ‘goto-‘, ‘exit-‘ en ‘return’-constructies, routines als argumenten en dergelijke.
Een vaak genoemd principe in de ontwikkeling van herbruikbare software is dat van ‘information hiding’. Alleen dat wat voor gebruik door de klant van nut is, moet publiek worden gemaakt. Van de implementatiedetails dient de klant te worden afgeschermd.
Uitbreidbaarheid en hergebruik gaan hand in hand bij overerving. Overerving is een mechanisme waarbij een softwaremodule eigenschappen erft van een supertype, wiens eigenschappen hij desgewenst kan herdefiniëren of uitbreiden. Meervoudige overerving biedt het maximum aan flexibiliteit. Componenten kunnen immers eigenschappen van meerdere typen in zich verenigen. Bijvoorbeeld: een ‘window’ is een rechthoek èn een boomstructuur, dus moet hij van beide kunnen erven.
De ontwikkelmethode
Van een werkbare methode verwachten we dat deze de gehele ontwikkelingscyclus van een softwaresysteem dekt en een project binnen de gestelde tijd en budgetten naar het beoogde doel leidt. De traditionele watervalmethode, in Nederland vooral bekend in de SDM-variant van het toenmalige Pandata, voert een project via een reeks plannen van aanpak en voortdurende terugkoppeling in vaak dikke rapporten langs definitiestudie, globaal- en detailontwerp naar de fase van realisatie, testen, operationalisering en onderhoud.
We weten inmiddels dat het in de praktijk niet zo werkt. Het voornaamste probleem van de methode is de scheiding van taken van analisten, ontwerpers, programmeurs en testers. De zorg voor kwaliteit is niet integraal, maar op de deeltaak georiënteerd. Bij elke overdracht gaat kostbare kennis verloren. Een ander probleem is dat het eigenlijke coderen pas relatief laat begint. Als de druk oploopt, komt van de geplande terugkoppeling van specificatiewijzigingen naar de deliverables uit de eerdere fasen niet veel meer terecht. Dat leidt tot onjuiste of onvolledig gedocumenteerde systemen.
Om de nadelen van deze aanpak te ondervangen, is prototyping in zwang geraakt. Men begint zo snel mogelijk te ontwikkelen en er is onmiddellijk feed-back. Maar na het prototype moet er een productieversie komen. Ook hier dus een continuïteitsbreuk en een potentiële mismatch. En net als in de watervalmethode vormt het softwareonderhoud, dat volgens sommigen uiteindelijk wel 70 procent van de totale softwarekosten uitmaakt, ook hier een ondergeschoven kindje.
Wat we zoeken is een methode waarin analyse, ontwerp, realisatie en onderhoud naadloos in elkaar grijpen. Dat kan alleen als voor het vastleggen van de activiteiten in al die fasen één consistente notatie wordt gehanteerd. Elke stap zou moeten voortbouwen op, en een verrijking vormen van hetgeen in de vorige fase is opgeleverd, in plaats van telkens een op zichzelf staand product op te leveren.
Eiffel
Eiffel heeft de mateloze pretentie zowel de ideale taal als de gezochte methode te bieden voor de ontwikkeling van hoogwaardige componenten en de daaruit te construeren softwaresystemen. Hoe denkt zij die waar te maken? Eiffel is een zuivere objectgeoriënteerde taal. Ze ondersteunt generieke datatypen, is strikt statisch getypeerd en kent mede daardoor, als een van de weinige objectgeoriënteerde talen, meervoudige overerving zonder enige beperkingen. Alle bekende begrippen in het OO-paradigma zijn op Eiffel van toepassing: ‘information hiding’, polymorfisme, dynamische binding, ‘garbage collection’, etcetera. Eiffel genereert C sourcecode, die op tal van platformen kan worden gecompileerd en is dus in hoge mate portable. Interessant, maar nog niet echt veel nieuws onder de zon.
Eiffel onderscheidt zich echter op twee gebieden wezenlijk van andere objectgeoriënteerde talen. Ten eerste is zij ondanks de krachtige eigenschappen een verbluffend simpele taal. In plaats van exotische symbolen hanteert zij een beperkt aantal begrijpelijke sleutelwoorden. De eenvoud van de taalconstructies en de combinatie van de ondermeer uit Pascal bekende dot.notatie met een heldere stijlconventie levert een compacte, esthetische brontekst op. Ook niet-triviale Eiffel-code is voor een beetje slimme leek na enige oefening goed te begrijpen. Kom daar bij C++ of Java maar eens om.
Het tweede fundamentele verschil is dat Eiffel als enige een in de taal verankerd assertiemechanisme kent. We zagen reeds dat dit om twee redenen van grote betekenis is: voor het waarborgen van softwarecorrectheid en voor de herbruikbaarheid van componenten. Maar er is meer. Met de mogelijkheid om de semantische karakteristieken van een datatype te specificeren in dezelfde notatie, die later wordt gebruikt om de eigenschappen van bewerkingen, en weer later de implementatiedetails vast te leggen of te wijzigen, beschikken we over een methode die specificatie, ontwerp, realisatie en onderhoud naadloos in elkaar laat overgaan.
‘High tech’ en ‘haute finance’
Als Eiffel zo goed is, waarom is zij dan zo weinig bekend? Heeft de taal het misschien nooit verder gebracht dan de tekentafel? Nee, Eiffel is inmiddels ruim veertien jaar oud. Het beheer van de taal berust bij een onafhankelijk non-profit consortium (NICE). In het ‘public domain’ is een complete hoog-kwalitatieve basis- en kernel-bibliotheek van Eiffel-componenten verkrijgbaar. Er bestaan inmiddels enkele commerciële implementaties van een Eiffel-compiler. Die van marktleider ISE uit Californië wordt geleverd met een complete ‘workbench’ en een visuele applicatiebouwer voor diverse platformen, en handlers voor de belangrijkste database-managementsystemen.
Vooral ISE’s case-tool is het vermelden waard. Volledig geënt op het specificeren van asserties volgens het idee van ‘design by contract’ en de grafische notatie van Bon, is dit het enige mij bekende case-tool dat de belofte van seamlessness en reverse engineering voor de gehele levenscyclus van de software waarmaakt.
Dus opnieuw, waarom breekt Eiffel dan niet door? Ik vraag het Bertrand Meyer, geestelijk vader van Eiffel en directeur van ISE. Zijn vermoeide reactie verraadt dat hij de vraag al meermalen heeft moeten beantwoorden. Hij vertelt dat de introductie van Eiffel vrijwel parallel liep aan die van Smalltalk en C++. Waar Smalltalk door Xerox, en C++ door AT&T tijdens de tweede Oopsla-conferentie in 1987 fel werden gepromoot, werd de aanwezigheid van het eigenwijze Eiffel door deze industriële giganten toen niet op prijs gesteld. Toch mag Eiffel thans bogen op een lange lijst van klanten waaronder respectabele namen in de wereld van de IT en ‘haute finance’: Hewlett-Packard, EMC, Bytex, Telecom Australia, Bank of New York, CALFP, AMP investments en de Chicago Board of Trade. Wat goed is komt er uiteindelijk toch, zegt Meyer.
Was dat maar waar! De geringe omvang van ISE werkt duidelijk in het nadeel van de verspreiding van de taal. Eiffel lijdt aan een omgekeerd ‘nobody ever got fired for buying IBM’ syndroom. Misschien niet helemaal ten onrechte. ISE wordt duidelijk door technici en niet door marketeers gedreven.
De nieuwe Cobol
In zijn nawoord op Hoare’s Huygensrede, maakte Jan Bergstra, hoogleraar ‘software engineering’ in Amsterdam en toegepaste logica in Utrecht gebruik van z�jn constitutionele recht op, in dit geval, Java-tuchtiging. Wanneer hij de aantrekkingskracht van die taal op het programmeursgilde met name verklaart uit Java’s complexiteit, toont hij een wel zeer cynische visie op zijn vakgenoten. Als hij gelijk heeft, verklaart dat waarom Eiffel in die kringen niet aanslaat. Maar hij heeft ongelijk.
Waarom is Cobol niet uit de wereld weg te branden? Om zijn eenvoud, leesbaarheid en effectiviteit. Eiffel heeft de potentie zich te ontwikkelen tot een modern objectgeoriënteerd Cobol. Als ik het mis heb, eet ik mijn schoen op. Of, een nog wredere straf, dan maak ik een compiler die Eiffel omzet in Java-bytecode. Alsof je je dochter uithuwelijkt aan een wildvreemde.
Frank Koldijk, IT-adviseur