Programmeerparadigma’s Academiejaar 2006-2007 D. Janssens 1. Inleiding: de 4 belangrijkste paradigma’s • Paradigma’s = soorten van programmeertaal. A. B. C. D. • Imperatief programmeren Object-georiënteerd programmeren Functioneel programmeren Logisch programmeren Het gaat hier telkens om “hogere” programmeertalen abstractie van machinedetails bedoeld om programmeren gemakkelijker te maken uitvoerbaar via compilatie of interpretatie • • Niet chronologisch! Er zijn er veel meer, meestal voor gespecializeerd gebruik: bv. voor databases (SQL), tekstverwerking (TEX, postscript), scripting, … A. Imperatieve talen Deze sluiten het nauwst aan bij de Von Neumann architectuur (J. Von Neumann 1945, K. Züse 1936) Zie RAM-RASP, Register machine, Algoritmen en Complexiteit Imperatief programmeren: basisnoties • Geheugen = rij adresseerbare geheugenplaatsen, bevat programma en data • Toestand: functie die plaatsen (namen) afbeeldt op hun inhoud • Fundamentele instructie : assignment (x := e) betekenis: bereken waarde van expressie e in de huidige toestand, en plaats de bekomen waarde in de geheugenplaats met naam x. • Control flow instructies laten toe de volgorde waarin de instructies uitgevoerd worden te controleren (If B then S else R fi) • Uitvoering van een programma = rij opeenvolgende toestandsveranderingen Imperatieve talen: features • Datatypes enkelvoudige (char, bool, integer, real, …) samengestelde (array, record/struct, …) dynamisch gealloceerd geheugen type-checking • Control-flow subroutines, parameters extra control-flow instructies exceptions Typering Aan de objecten gemanipuleerd door een programma (expressies, namen) wordt een type toegekend dat bepaalt • hoeveel geheugen er nodig is • hoe de inhoud van het overeenkomstige stuk geheugen dient geïnterpreteerd te worden (bv real array of 3 dimensions, row-major) voordelen: • Hulpmiddel voor de programmeur • Hulpmiddel voor de compiler ontwerper • Bevordert sterk de detectie van vermoedelijke fouten(fout assignment, fout type van parameters, etc) • In talen met een sterk typesysteem (bv functionele talen) is een type-correct programma verrassend vaak fout-vrij Imperatieve talen: voor- en nadelen Voordelen: • Sluit dicht aan bij machinearchitectuur • Goed uitgewerkte theorie: eindige automaten (compilers), turing machines (complexiteitstheorie), algorithmiek, … • Veruit het meest gebruikt Nadelen: • Dwingt de programmeur te denken in termen van toestanden en toestandsovergangen, wat vaak niet goed aansluit bij het probleemdomein • Leidt al te vaak tot onoverzichtelijke programma’s (GOTO) Imperatieve (en OO) talen Cobol Fortran Algol 60 Algol 68 CPL Pascal BCPL Simula C Modula 2 ADA C++ Java Smalltalk B. Object-georiënteerde talen • Uitbreiding van het imperatieve paradigma, 3 principes: abstractie - inheritance - dynamische binding • Object: geheel van data (attributen) die slechts met behulp van welbepaalde methoden kunnen gemanipuleerd worden (encapsulatie) • Klasse: soort (type) van objecten, met zelfde attributen en methoden • Een OO programma is in essentie een verzameling klassen (klassedefinities) evt uit libraries. • Klassedefinities kunnen uitgebreid worden door gebruik te maken van inheritance: uit een meer algemene klasse een meer gespecialiseerde klasse maken door er bv methodes of attributen aan toe te voegen (re-use) Inheritance Vorm positie area Vierkant positie zijde area Method overriding (area) Cirkel positie straal area Dynamische binding Var x: vorm … x := v (vierkant) … opp := x.area … x := c (cirkel) … opp := x.area x.area verwijst naar 2 verschillende methodes Smalltalk (-80) In de taal Smalltalk werd de OO filosofie het verst doorgevoerd. Uitvoering = herhaal: 1. Stuur een message naar een object ob om een van de methoden van ob op te roepen. 2. Als reactie stuurt ob een object terug X 5+4 : stuur message “+” met als argumenten de objecten 4 en 5 naar het object x Smalltalk class name superclass instance variable names Polygon Object ourPen numSides sideLength new ^ super new getpen getPen ourpen Pen new defaultnib:2 draw numSides timesrepeat: [ourPen go: sideLength; turn: 360 // numSides] … Geïntegreerde programmeeromgeving, windows, muis ++ C - Java class sphereClass { public: sphereClass(double R): sphereClass(); … De method bodies zijn in essentie imperatieve programma’s double Radius(); void SetRadius(double R); … } class ballClass: public sphereClass { … private: char TheName[MAX_STRING+1]; }; OO paradigma: trends • OO analyse: beschrijving van het domein in termen van objecten • OO modellen - Unified Modeling Language • Model transformatie: van abstract, platform-onafhankelijk naar concreet, platform-specifiek (Model-Driven Engineering) • Aspecten, voor crosscutting concerns C. Functionele talen • basisidee: programmeren = functies bouwen • een programma definieert een functie (input output) • samenstellen van complexer functies uit eenvoudiger delen: opbouwen van functionele termen • eenvoudige datastructuren: lijsten • Het uitrekenen van expressies gebeurt door substitutie (2 + 3) * (23 - 17) 5 * (23 - 17) 5*6 30 Niet meer verder te “reduceren”: normaalvorm Functionele talen: kenmerken • De taal levert een mechanisme om functies te definiëren (op te bouwen uit eenvoudiger functies) • Functies zijn first class objecten: ze kunnen bv optreden als parameters van andere functies (= hogere orde functies) • Interactie met systeem: dialoog. Geef functiedefinitie(s) en een expressie, het systeem evalueert die expressie. • Uitgebreid typesysteem: elke expressie - en dus ook elke gebruikte functie - is getypeerd Andere issues: • Belangrijkste datastructuur: lijsten. Een aantal functies zijn voorgedefinieerd. Head [2,3,7,5] 2 Tail [2,3,7,5] [3,7,5] • Referential transparency: namen, expressies hebben gedurende de hele uitvoering, en overal in het programma (de term) dezelfde betekenis. Er is geen assignment. Er is wel een beperkt gebruik van lokale namen. • Anonieme en hogere orde functies (x.x+3) is de functie x x+3. (y.(x.x+y)) is de functie die y afbeeldt op de functie x x+y. - calculus en LISP • - Calculus is een formeel model voor berekenbaarheid, equivalent met Turing machines, gebaseerd op functies en substitutie (A. Church, 1941). • LISP (List Processing language - later Common LISP) werd rond 1959 ingevoerd (J. McCarthy), en werd snel populair in de AI (vòòr Prolog). • Een lijst ( A B C ) heeft 2 interpretaties: - letterlijk (met quote) - A toegepast op argumenten B en C ( + 5 7 8 ) geeft 20 QUOTE ( + 5 7 8 ) of `( + 5 7 8) geeft ( + 5 7 8 ) • Head en Tail heten traditioneel CAR en CDR in LISP • Lijsten kunnen als element opnieuw lijsten bevatten; op die manier kan men complexe lijststructuren bouwen. - calculus: voorbeelden x.x (de identiteitsfunctie) fun.arg.(fun arg) x.y.y (apply) (select tweede argument, false) y.(x.(y (x x)) x.(y (x x))) (Y combinator) LISP ( DEFINE ( equal lis1 lis2) (COND ( ( NOT (LIST? lis1 ) ) ( EQ? Lis1 lis2 ) ) ( ( NOT (LIST? lis2 ) ) ` ( ) ) ( ( NULL? lis1 ) ( NULL? lis2 ) ) ( ( NULL? lis2 ) ` ( ) ) ( ( equal (CAR lis1 ) (CAR lis2 ) ) ( equal ( CDR lis1 ) (CDR lis2 ) ) ) ( ELSE ‘ ( ) ) )) Functie voor gelijkheid van lijsten zonder sublijsten. ELSE staat voor #T (true). False wordt voorgesteld als de lege lijst ( ) Haskell: som Som van de integers 1 tot 10 in Java: total = 0; for (i = 1; i 10; ++i) total = total+i; Basisidee is daar dus assignment aan variabelen. In Haskell wordt dat: sum [1..10] met sum gedefinieerd door: sum[ ] = 0 sum[x:xs] = x + sum[xs] 22 Haskell: quicksort f [] = [] f (x:xs) = f ys ++ [x] ++ f zs where ys = [a | a xs, a x] zs = [b | b xs, b > x] 23 Functionele talen LISP ML SASL Standard ML Miranda Scheme Haskell Gofer Common LISP D. Logisch programmeren A. Colmerauer, Ph. Roussel, R. Kowalski (1975, 1981) • Basisidee: interactie = dialoog waarin - de gebruiker feiten, regels en een query geeft - het systeem de query beantwoordt op basis van de feiten en regels. Het systeem probeert de query te bewijzen. “Niet bewijsbaar” wordt gelijkgesteld met”neen”. • de regels zijn logische afleidingsregels, gebaseerd op predicaten- calculus • belangrijkste taal: Prolog Prolog: clauses • Atomaire predicaten : Functor + parameters Man(Fred) Dochter(An, Karl) • Clausale vorm : B1 v B2 v … v Bm A1 ^ A2 ^ A3 ^ … ^ An • Horn clauses: m = 0 of m = 1 Resolutie Als gegeven is: A1 , A2 , B1 A1 en B3 B1 ^ A2 , dan kan men, om B3 te bewijzen, als volgt tewerk gaan: - gebruik regel B3 B1 ^ A2 om te besluiten dat het volstaat B1 en A2 te bewijzen. - gebruik regel B1 A1 om te besluiten dat het volstaat A1 en A2 te bewijzen. - stel vast dat A1 en A2 gegeven zijn. In het algemeen heeft men dus telkens een aantal nog te bewijzen termen: die noemt men goals. Prolog: variabelen • Er mogen ook variabelen voorkomen: ouder(X,Y) :- moeder(X,Y) betekent: X,Y: ouder(X,Y) moeder(X,Y) Het prolog systeem gaat de variabelen instantieren (vervangen door meer concrete termen): . Vader(Bob) (feit) . Man(X) :- vader(X) Het resolutieproces beslist dat X vervangen (geinstantieerd) moet worden door Bob Unificatie In het algemeen moet men twee termen (hier Bob en X) proberen “gelijk te maken” door variabelen te vervangen door meer specifieke termen. Dit zal ook gebeuren in het pattern matching proces van het functioneel programmeren. A(Y,c) A(b,X) Y=b X=c A(b,c) Prolog append ( [ ] , List , List ) . append ( [ Head | List_1 ] , List_2 , [ Head | List_3 ] ) :append ( List_1 , List_2, List_3 ) . [ A | B ] is de lijst met A als head en B als tail. A is hier dus een lijstelement, B is zelf een lijst De query ? append ( [ a,b ] , [ c,d ] , X ) wordt als volgt opgelost. stap 1: instantiatie: Head = a List_1 = [ b ] List_2 = [ c,d ] X = [ Head | List_3 ] goal: append ( [ b ] , [ c,d ] , List_3 ) Prolog stap 2: instantiatie: Head' = b List'_1 = [ ] List'_2 = [ c,d ] List_3 = [ Head' | List'_3 ] goal: append ( [ ] , [ c,d ] , List'_3 ) stap 3: instantiatie: List = [ c,d ] List'_3 = [ c,d ] goal: nihil na substitutie: X = [ a | [ b | [ c,d ] ] ] = [ a,b,c,d ] Deel 1: Functionele talen - Haskell • Fundamenten: -calculus en recursieve functies • LISP en Common LISP - Haskell (naar Haskell B. Curry) • Evaluatiestrategieën, eager en lazy • Combinatorische logica • Monaden • Compilatie van functionele talen, continuaties • Features van Haskell