1 2 TDDC10 Perspektiv på datateknik/datavetenskap TDDC79 Perspektiv på informationsteknologi TDP001 Handhavande av datormiljö (D, IT, C, IP) Breddgivande föreläsning Historik Datorspråk Programmeringsparadigmer Programmeringsspråk Konstruktioner i programmeringsspråk Datorspråk kommunikation människa - dator kommunikation dator - dator språk med textuell representation språk för att beskriva algoritmer = programmeringsspråk språk för att beskriva data eller layout = beskrivningsspråk => dessa kallas formella språk (CS sid 228) Jämför naturliga språk: Litteratur: Brookshear, Computer Science - an overview, kap 6 (CS) Sebesta, Concepts of Programming Languages människans ljudspråk textuell representation skriftspråk 3 4 Exempel på typer av datorspråk EXCEL programmeringsspråk finns 1000-tals språk ett 10-tal används klart mest ett 100-tal används kommersiellt frågespråk databaser (t e x SQL) kommandospråk operativsystemspråk (t ex Unix) inbyggda språk i tillämpningar kalkylspråk (t ex Excel) matematiska språk (t ex Mathlab) beskrivningsspråk dokumentstrukturer (t ex MIF-format, SGML, XML) www-sidestrukturer (t ex HTML, Java-script) utskriftsspråk dator till skrivare (t ex Postscript) datorkommunikationssspråk nätprotokoll
5 HTML 6 Postscript - utskrift på laserskrivare 7 8 Java Lisp
9 10 Formella språk (CS 6.4) Formella språk Hur är språket uppbyggt? Ett formellt språk måste vara entydigt. Vilka program / beskrivningar är korrekta i det formella språket. Språkets syntax beskriver hur de olika konstruktionerna får skrivas (som text). Syntaxen brukar skrivas i någon typ av grammatik. Exempel: Aritmetiska uttryck 3 - (4.5 * -2) / 1.56 Men vad är egentligen tillåtet? Får vi skriva följande uttryck? -(2+3) +3-2 3+(2) 3-+2 4*()-1 ((((2)))) Naturligt språk är ej entydigt. Sammanhanget avgör vanligen betydelsen. Syntaxen hos språk kan vara av olika komplexitet. Det finns olika klasser med grammatiker. Problemet är: Givet en grammatik och en följde med tecken. Kan man på ett effektivt sätt kontrollera om en följd av tecken uppfyller grammatiken och kan man bygga upp en intern struktur, som visar de ingående elementen och strukturen mellan dessa. Teckenrepresentationen kalla konkret syntax. Processen att kontrollera och bygga upp lämpliga strukturer kallas parsing och resultatet abstrakt syntax eller parseträd (parse tree). Mer om detta vid en senare breddföreläsning 11 12 Formella språk Vad betyder de olika konstruktionerna i språket. Kallas för språkets semantik. Detta är svårare att beskriva. Man brukar använda logik- och matematiskt baserade notationer för att beskriva semantiken av ett programspråk. Litet exempel: Hur beräknas ett aritmetiskt uttryck? Prioritet mellan operatorer i ett aritmetiskt uttryck är olika. Parenterser beräknas först. I vilken ordning beräknas delarna i ett uttryck? Programmeringsparadigmer Framväxten av olika abstraktionsmekanismer i programspråk och deras påverkan på programutvecklingsmetoder, från tidig analys och modellering, till kodning och testning. Olika stilar att skriva och strukturera program. 3+5*5 (3+4)*5 3+4+5=((3 + 4) + 5) eller (3 + (4 + 5))? 3-4-5 = ((3-4) - 5) eller (3 - (4-5))? I ett logiskt uttryck, beräknas alla delarna? (a = 0) eller (x/a > 10)
13 14 Programmeringsparadigmer (CS 6.1) flödesschema-programmering - goto Fortran, Basic Maskinnära programmering, C Strukturerad programmering Pascal, Ada, C Imperativ programmering = Flödesschema-programmering + Strukturerad programmering Objektorienterad programmering Simula, Smalltalk, C++, Java, Python, Ruby, C# Händelsestyrd (event-driven) programmering (CS sid 252) visual-språken (Basic, C, C++, Delphi), Java etc Processprogrammering (concurrent programming, parallel programming) PL/I, Modula, Ada, Java Deklarativ programmering funktionell programmering Lisp, ML, Haskell, F# 8Microsofts nya) logikprogrammering Prolog Vad vill man komma åt? Programmeringen skall höjas mot tillämpningen kalkylspråk, matematiska språk Begrepp i språket skall motsvara verkliga koncept från tillämpningen abstrakta datatyper, objektorientering Höja abstraktionen program skall bli lättare att förstå och därmed förhoppningsvis korrektare Bemästra komplexitet gömma information Programmen blir mer specifikation - what to do mer än hur man löser uppgiften how to do funktionell och deklarativ programmering, databasfrågespråk 15 16 Konstruktioner i programspråk (CS 6.2) deklarationer datatyper programspråkets inbyggda typer: primitiva datatyper heltal (integer), flyttal (float, real), tecken (character), logiska värden (Boolean) sammansatta datatyper sträng (string), arraystruktur (array), post (record), lista pekare (pointer) egendefinierade datatyper klasser / abstrakta datatyper grundläggande komponenter literaler (1234, 12.5, en sträng, true) konstanter (pi) variabler uttryck (expression) satser (statement) tilldelningssats (assignment statement) in- och utmatningssatser Konstruktioner i programspråk primitiva operationer beroende på språk finns primitiva operationer för t ex aritmetik (+, -,...), stränghantering, databasoperationer, kalkyloperationer styrstrukturer (control structures) hoppsatser (goto) villkorssats (if) repetitionssatser (for, while, repeat) rekursion iteratorer exekverbara enheter underprogram funktioner (function) procedurer (procedure) korutiner processer (process) moduler paket klasser filmoduler
17 18 Exempel på ett enkelt program i ett påhittat programmeringsspråk: program summera-talen-mellan; deklarationer datatyp variabler variabel programblock heltal första_tal, sista_tal, summa; satser block summa = 0; läsin (första_tal); läsin (sista_tal); för tal = första_tal till sista_tal utför summa = summa + tal; skrivut (summa); slut_program; tilldelningssats inläsningssats repetitionssats utskriftssats villkorssats tilldelningssats Exempel på ett enkelt program i ett Basicliknande (helt påhittat) språk. Med gå till (goto) hoppar man till nya rader: program summera_talen_mellan 100 summa = 0 variabler 200 läsin (första_tal) 300 läsin (sista_tal) 400 tal = första_tal 500 om tal > sista_tal gå till 900 600 summa = summa + tal 700 tal = tal + 1 800 gå till 500 900 skrivut (summa); slut program predikatuttryck hoppsats 19 20 repetitionssats Samma exempel beskriven med en procedur procedur summera (in tal, in sista_tal, ut summan); summan = 0; repetera tills tal > sista_tal summan = tal + summan; tal = tal + 1; slut-repetera; returnera; slut_procedur; avsluta procedur formella parametrar program summera_talen_mellan; läsin (först_tal); aktuella parametrar läsin (sista_tal); summera (första_tal, sista_tal, summa); skrivut (summa); slut_program; värde från proceduren Samma exempel beskriven med en rekursiv funktion (som gör en rekursiv processlösning) funktion summera (tal, sista_tal); om tal > sista_tal returnerar ett värde returnera 0 annars returnera tal + summera (tal + 1, sista_tal); slut_funktion; program summera_talen_mellan; läsin (första_tal); läsin (sista_tal); skrivut (summera (första_tal, sista_tal)); slut_program;
21 22 Historiska utvecklingen (CS Fig 6.2) 50- och 60-talet Maskinspråk Assemblyspråk flödesschema -programmeringen Imperativa programspråk Fortran språk för numeriska beräkningar Cobol språk för administrativa ändamål Algol inför blockstruktur, underprogram, rekursion PL/I inför processer, pekare och länkade strukturer Simula kommer med objektorientering med klasser och hierarkier (40 år för tidigt!) Maskinspråk (CS 6.1) Assemblyspråk Maskinberoende Först bara numeriska koder och adresser i minnet, sedan införs mnemoniska namn på dessa koder och identifierare, namn på minnesutrymmen. En assemblator översätter dessa namn till koder. LOAD ADD MULT STORE LOAD JMPZE EXCH Areg, a Areg, b Areg, c Areg, d Breg, a Breg, start Areg, Breg där LOAD etc är mnemoniska namn på operationskoder och a, b etc symboliska namn på direkta minnesadresser 23 24 flödesscheman -> strukturerad programmering flödesscheman - program konstrueras från flödesscheman som byggs upp av boxar, val och pilar. bild som visar Fortran - pilarna anger hopp (goto) i programmet spagetti-programmering goto considered harmfull strukturerad programmering (Wirth) - program konstrueras av 3 byggblock sekvens, repetition/iteration, val - goto förbjudet
25 26 bild som visar Algol Bild som visar Algol 27 28 Bild som visar Cobol Bild som visar Cobol
29 30 CS Fig 6.8 70-talet Basic kommer som mycket enkelt språk och som interaktivt språk Pascal. Repetitionsstrukturer, egendefinierade datatyper och strukturerade program C växer fram som systemimplementationsspråk för bl a Unix Ada. Den samlade erfarenheten efter 20 år ligger till grund för Ada som tas fram av en kommitté med paket, gömma representation, processer, generiska underprogram och paket 80-talet C++ tar över objektorientering. Visual Basic, Delphi mfl som underlättar programmering av användargränssnitt 90-talet Java. Internetspråket, portabilitet, stora programbibliotek (API). Idag konkurrent till C++. C# (C-sharp) Microsofts svar på Java. Pearl, Python, Ruby dynamiska språk och text/wwwbaserade språk med ökande spridning SEKVENS begin s1; s2 end s1 s1 s2 p s2 while p do s p s REPETITION Det fär bara finnas en ingång och en utgång till varje strukturprimitiv. Varje låda kan bytas ut mot en ny strukturprimitiv VAL if p then s1 else s2 31 32 Problemet delas upp i funktionella mindre delar Ada Stepwise refinement (Wirth) Levels of abstraction (Dijkstra, Liskov) Top-down design - fokusera på algoritmen - nedbrytning av problemet sker med de strukturerade primitiverna Strategi top-down: 1. Formulera funktionen för hela problemet 2. Dela upp i delproblem 3. Fortsätt tills primitiva operationer har uppnåtts, t ex satser i ett programspråk
33 34 Pascal Basic 35 36 C++ Python numbers = [] for number in range(100): numbers.append(str(number) + "\n") open("filnamn", "w").writelines(numbers) Indenteringen styr hur satser hänger samman (block), som i andra språk kan ha begin... end eller måsvingar { }
37 38 Abstrakta datatyper - specificera vilka värden/objekt som ingår i den abstrakta datatypen (se en datatyp som en mängd värden/objekt) - specificera vilka operationer som kan utföras på objekten - beskriv strukturen på värdena/objekten - separerar representationen med operationerna - möjliggör att ändra representation utan att tillämpningsprogrammen behöver ändras - gömma representationen (information hiding, encapsulation) Konstruktioner i programspråk Vanliga primitiva operationer är: konstruktorer (constructors) - skapar objekt skapa-datum, skapa-bil, skapa-tom-tabell, skapa-binärt-träd selektorer (selectors) - tar ut delarna av objekt dag, månad, antal-dörrar, vänster-del-träd igenkännare (recognizers) - testar på datatyp datum? bil?, löv? ändrare (mutators) - ändrar i objekt öka-dagnummer, ändra-namn, lägg-till-på-stack iteratorer (iterators) - går igenom alla elementen i ett objekt för-varje-element, för-varje-dörr - abstrakta datatyper är grunden för objektorienterad programmering genom begreppet klass 39 40 Objektorienterad programmering (CS 6.5) Fokus på dataobjekten (ej som tidigare på algoritmerna och de funktionella delarna) Studera tillämpningen, identifiera vilka dataobjekt som finns och kategorisera dessa. Från dessa bildas klasser/abstrakta datatyper och hierarkier mellan dessa datatyper. bilar: volvo, saab, opel,... lastbilar: scania,... bussar:.. Alla objekten i en klass har gemensamma egenskaper. En överordnad klass för dessa tre klasser kan vara fordon. Man skapar hierarkier av datatyper. Man kan ärva (inheritance) egenskaper från en överordnad klass. Objektorienterad programmering Program beräknas genom att dataobjekten kommunicerar med varandra genom meddelandesändning. Genom att skicka meddelandet "skriv-ut till ett objekt önskar man att objektets värde eller identitet skall skrivas ut på t ex terminalen. Objektorienterade designmetoder UML - Unified Modeling Language med grafiska symboler Objektorienterade programspråk Simula, Smalltalk, C++, Ada, Java, C#, Python Ruby
41 42 Deklarativ programmering Idealiserat: Skriv en specifikation som anger vad du skall göra och låt programmeringssystemet bestämma hur. Basera specifikationen på ett formellt system. Funktionell programmering: matematik. Funktioner och uttryck. Exekveringsmodell: beräkning som i matematik beräkna argument, applicera funktion Funktionella språk: pure Lisp, ML, Haskell Logikprogrammering: predikatlogik. Fakra som predikat och regler som logiska uttryck. Om A är FAR till B, och B är FAR till C, så är A FARfarTILL c Exekveringsmodell: slutsatsdragning (resolution) som i predikatlogik eller djupet först-sökning i träd Logikprogrammeringsspråk: (CS 6.7): Prolog, numera i kombination med constraint i form av samband. Lisp / Scheme Lisp (Johan McCarthy 1960) med dialekter Scheme och Common Lisp Har utvecklats inom forskningen för artificiell intelligens och runt programmeringshjälpmedel. används numera: - som grundläggande språk i många datautbildningar - som inbyggda språk i editorer (t ex emacs) och CAD-system (t ex AutoCAD) - som utvecklingsmiljö för dataspel Lisp har en speciell syntax, parenteser Data är vanligen listor. Program-data ekvivalens. Program representeras även det som data, 43 44 Funktionella språk Program skrivs ofta som rekursiva funktioner: { 1 om n = 0 n! = n*(n-1)! om n>0 (defun fak (n) (if (= n 0) 1 (* n (fak (- n 1))))) Data representeras ofta som skevenser eller trädstrukturer (binära träd) { 0 om sekvensen är tom längden (s) = 1 + längden(rest (s)) där rest(s) betyder sekvensen utom det första elementet. Funktionell programmering binära träd Formeluttryck, t ex aritmetiska uttryck kan lätt överföras till trädstrukturer. (2 + 4) * (/ (- 8 2) 3) + 2 4 * Att summera uttrycket kan göras med en binär-trädalgoritm: summera(uttr) = { uttr om uttr är ett tal (dvs löv) = summera(vänster(uttr)) + summera(höger(uttr)) om operatorn är + summera(vänster(uttr)) - summera(höger(uttr)) om operatorn är - etc. - 8 2 / 3
45 46 Beräkning / exekvering av program (CS sid 228, 6.4) Två modeller: Kompilator (compiler): Översätter program till ett annat programspråk, vanligen maskinspråk (datorns hårdvara). Det översatta programmet kallas då för objektprogram. Detta kan i sin tur exekveras på datorn. De flesta språk är kompilerande. Interpretator (interpreter): Programmet representeras i en internstruktur som direkt beräknas. De Lisp-baserade språken är ofta interpreterande. Interpretatorn kan i sin tur vara skrivet i godtyckligt programmeringsspråk. Många interpreterande språk har även kompilator. Beräkning / exekvering av program En nackdel med kompilator är att man behöver en kompilator för varje datortyp (med olika maskinspråk). För att erhålla maskinoberoende (plattformsobereonde) har man för Java följande strategi: Java kompileras till en mellannivå (Java Virtuella Maskinspråk). (CS sid 262) Denna mellannivå interpreteras av en Java Virtuell Maskininterpretator. Denna interpretator måste finnas för varje datortyp (och ingår t ex i web-läsaren). Denna mellannivå kan i sin tur kompileras till maskinkod (just-in-time kompilering). 47 48 Typning i programspråk Typning i programspråk Många språk är sk statiskt typade språk (Ada, C++, Java). Det betyder att användaren i programmet deklarerar vilken typ en variabel, parametrar och funktioners värde har. Kompilatorn kan då i ett försteg göra alla kontroller så att programmet är typkorrekt, dvs alla typfel upptäcks innan exekveringen. Antag att + är definierat att ta tal som argument deklarera s : tecken; s := 100;... s + 10... När programet är typkorrekt och har kompilerats så kan man i maskinkoden förutsätta att de data som olika instruktioner får är korrekta. En viktig fråga i ett språk är vad för slags typer kan skapas, dvs definieras. Stark typning kan ibland medföra svårigheter, t ex att skriva generella procedurer (Pascal-problemet). Vi har en lista med godtyckliga element. Vi vill räkna antalet element. En sådan procedur borde kunna ta alla listor, eftersom elementens datatyp ej är av intresse, då de endast skall räknas. Alla språk kan ej skriva en sådan generell procedur. Sedan har vi klassen dynamiskt typade språk (Lisp, Python, Ruby). Här kan en variabel antaga vilket värde som helst. Från själva dataobjektet måste typen kunna härledas (typmärkning). Varje operation måste sedan under exekveringen testa på att argumenten är av rätt typ. Här kan vi skriva en generell procedur som räknar alla elementen i en lista med godtryckliga element, Båda modellerna ger för- och nackdelar. I objektorienterade språk har man genom möjligheten med att skapa typhierarkier kunnat lösa detta problem med generella procedurer och möjligheten att kontrollera typer. Där finns en överordnat typ, t ex object, där alla andra typer är underordnade. Jag kan då skriva den generella proceduren som tar en lista, där elementen är av typen object. Denna funktion anropas sedan normalt med en lista med någon specifik typ, t ex en lista med tal eller en lista med strängar.