Institutionen för datavetenskap
|
|
- Gerd Mattsson
- för 6 år sedan
- Visningar:
Transkript
1 Institutionen för datavetenskap Department of Computer and Information Science Examensarbete Implementation och utökning av en typhärledningsalgoritm för Common Lisp av Simon Ståhlberg LIU-IDA/LITH-EX-G--10/018--SE Linköpings universitet SE Linköping, Sweden Linköpings universitet Linköping
2 Linköpings universitet Institutionen för datavetenskap Examensarbete Implementation och utökning av en typhärledningsalgoritm för Common Lisp av Simon Ståhlberg LIU-IDA/LITH-EX-G--10/018--SE Handledare: Anders Haraldsson Examinator: Anders Haraldsson
3 Sammanfattning Programmeringsspråk har oftast ett typsystem och kan välja att använda olika statiska verktyg att analysera koden. Statiska språk utför typkontroller innan körtillfället och kan då ge garantier att typfel inte kan förekomma, dynamiska språk gör däremot dessa kontroller under körtillfället och om ett dåligt beteende upptäcks avbryts programmet. Eftersom kontrollerna görs under körtillfället skrivs inte typsignaturer ut i dynamiska språk. Ett dynamiskt språk kan vara mer exibelt än ett statiskt språk eftersom inga garantier ges. Eftersom inga typsignaturer skrivs ut går det att skriva program på ett mer koncist sätt. I statiska språk tvingas oftast användaren att skriva ut typerna explicit för variabler och funktioner. Typhärledning är processen att härleda typer för uttryck. En typhärledningalgoritm kommer att undersökas, hur kraftfull algoritmen är samt hur algoritmen kan utökas för att klara av era konstruktioner och ett kraftfullare språk. Typhärledningsalgoritmen kommer att implementeras för Common Lisp. Common Lisp ger inga typgarantier och inga typsignaturer skrivs ut. Alla typer kommer att härledas vilket innebär att vi gör om en delmängd av Common Lisp till ett statiskt språk. Algoritmen kommer att utökas för att klara av polymorsm, closures, listor och par. Rapporten undersöker vilka ändringar som behöver göras för att stödja konstruktionerna, hur vi kan göra ändringarna hur de kan implementeras. Fördelar med att ha typhärledning är att användaren slipper skriva ut typsignaturer och kan få ökad produktivitet. Den mest generella typsignaturen kommer alltid att härledas och funktioner som är polymorfa kommer att upptäckas automatiskt. Typhärledningsalgoritmen kommer att även typkontrollera programmet, och kan ge garantier att inga problem kommer att uppstå. Verktyget kommer även att skapa ett nytt program med typsignaturer utskrivna som kompilatorn kan använda för att generera eektivare kod.
4 Förord Typhärledning introducerades för mig under kursen data- och programstrukturer på Linköping tekniska högskola av Anders Haraldsson. Det kändes magiskt och det var en ögonöppnare att få se att sådan information kan framställas ur själva koden. Jag vill tacka min handledare, Anders Haraldsson, för att ha inspirerat och utformat examensarbetet. Samt för den hjälp som Haraldsson har gett mig under arbetet.
5 Innehåll 1 Introduktion Bakgrund Syfte och frågeställning Avgränsningar Struktur Förutsättningar och notation Teori Typer och typsystem Typhärledning Implementation Typer Omgivningar Ekvationer och uniering Substitution Generera ekvationer Lambda och högre ordningens funktioner Polymorsm Listor och par Topploopen Tillämpningar Typdeklarationer Resultat Analys och slutsatser Avslutande diskussion Diskussion Framtida arbete
6 A Källkod 45 B Körexempel 46 B.1 Fakultetsfunktionen B.2 Primtalsfaktorisering
7 Kapitel 1 Introduktion 1.1 Bakgrund För att förstå sig på typer ska vi först ta reda på hur typer uppstår. Ett exempel på ett otypat område är bitsträngar i en dator. Dessa bitsträngar kan ha olika betydelse beroende på hur strängarna används. En bitsträng kan vara en pekare, ett värde eller en instruktion. 'Otypat' betyder egentligen att det bara nns en enda typ [4] och att bitsträngar är den typen. Det är dock oftast orimligt att en bitsträng är tänkt att användas till olika saker. Att använda en pekare som en instruktion är oftast inte meningen att göras. Så fort vi arbetar i ett otypat område börjar vi att ordna och lägga upp bitsträngar i olika typer beroende på syfte [4]. Potentiella typer som redan har nämnts är pekare, värden och instruktioner. Sedan kan värden organiseras till era typer som bokstäver, heltal, yttal, sanningsvärden, funktioner, med mera. Typer uppstår således naturligt. Det är viktigt att inse att datorn i grunden är fortfarande otypat och skiljer inte på bitsträngar. Vi har endast en illusion att det är typat. Ett typfel är när datorn utför en operation med eller på någon bitsträng som är tänkt att användas för något annat. För att garantera att inga typfel kan uppstå, i en dator som annars är otypat, använder vi oss av verktyg som kontrollerar att de operationer som utförs aldrig utförs med eller på fel typer. Denna process kallas för typkontroll. Syftet med ett typsystem är att förbjuda situationer där typfel kan uppstå [4]. Denitionen av typsystem varierar, men följande denition av Benjamin C. Pierce stöter man på ofta och är allmänt accepterad: [A type system is a] tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute.[6] 1
8 Typer kan således ses som en rustning som skyddar den underliggande representationen från oavsiktlig användning [4]. Ett programmeringsspråk där typen av varje uttryck kan bestämmas av en statisk analys av programmet säges vara statiskt typat. Statisk typning är en attraktiv egenskap, men kravet att typerna måste kunna bestämmas vid kompileringstillfället kan begränsa språket för mycket. Kravet kan ändras till ett svagare genom att garantera att alla uttryck kommer att vara typkonsekventa trots att typen inte är känd vid kompileringstillfället. Typkonsekvens menas att om ett typfel uppstår så stannar programmet. Programmet är konsekvent på så sätt att operationerna alltid utförs på rätt typer. Detta implementeras oftast genom att utföra typkontroller under körtillfället. Ett programmeringsspråk där typkontrollen utföres under körtillfället säges vara dynamiskt typat. Det nns fördelar och nackdelar med att göra typkontrollen vid båda tillfällena. Dynamiskt typade språk kan vara exiblare, dock ges det ingen garanti att inga typfel kommer att uppstå. Statiskt typade språk kan således hitta era felaktigheter i programmet utan att ens exekvera det. Istället ges garantin att om ett typfel uppstår kastas ett fel. Statiskt typade språk kan optimera den kompilerade koden; inga typkontroller behöver göras under körtillfället och inga typsignaturer behöver associeras till alla värden (mindre minnesanvändning). Genom att också veta hur mycket plats ett värde kommer att ta kan andra optimeringar göras. Statiskt mot dynamiskt typade språk är ett omdebatterat område. Dynamiskt typade språk har också fördelen med att de kan utelämna typsignaturer i koden då det enda viktiga är att alla värden har rätt typ vid alla tillfällen. Detta låter användaren att skriva program på ett mer koncist sätt. I statiska språk tvingas oftast användaren att skriva ut typerna explicit för variabler och funktioner. Vi kommer då in på typhärledning. Typhärledning är processen att härleda typen av ett uttryck. Ett statiskt språk med typhärledning har då alla fördelar som statiska språk har men samtidigt är det möjligt att skriva program på ett mer koncist sätt genom att utelämna typdeklarationer. För att demonstrera konceptet med typhärledning kan vi titta på fakultetsfunktionen med typsignaturer skriven i Haskell: f a c t o r i a l : : I n t e g e r > I n t e g e r f a c t o r i a l n = i f n > 0 then n f a c t o r i a l ( n 1) e l s e 1 Om vi använder oss av typhärledning kan vi ta bort typsignaturen och skriva fakultetsfunktionen som följande: f a c t o r i a l n = i f n > 0 then n f a c t o r i a l ( n 1) e l s e 1 Typsignaturen kommer att härledas av typhärledningsalgoritmen. 2
9 1.2 Syfte och frågeställning Det nns era fördelar med att ha en typhärledare till Common Lisp. Först och främst får vi typsäkerhet och garanterar att inga typfel kan ske. Felaktigheter kan även hittas i programmet om vi gör en statiskt typhärledning. Vi kan även få en prestandaökning genom att lägga till typdeklarationer i programmet som kompilatorn kan ta del av. Vi ställer frågan om det är rimligt att göra en typhärledare till ett dynamiskt språk. Rapporten utforskar de algoritmer som nns idag för typhärledning och undersöker en av algoritmer som nns i detalj. En av algoritmerna kommer att implementeras för en delmängd av Common Lisp. Vi utreder även vad som går och inte går att typhärleda samt vilka begränsningar vi måste göra på språket. Algoritmen kommer att utökas för att stödja nya konstruktioner och vi kommer att undersöka vilka konsekvenser det ger. Vid Linköpings tekniska högskola används Common Lisp och Scheme som första programmeringskurs för C, D och Y programmen. Kurserna fokuserar på funktionell programmering och introducerar rekursion, listor, högre ordningens och lambda funktioner samt closures. Verktyget skulle kunna användas av studenter för att typkontrollera sina program eller användas som en laboration i en kurs som följer den klassiska SICP-boken (Structure and Interpretation of Computer Programs) [3]. 1.3 Avgränsningar Vi kommer undersöka och implementera en typhärledningsalgoritm och vi kommer att koncentrera oss på att typhärleda den funktionella delen av Common Lisp. De utökningar som vi gör på typhärledaren kommer inte att matematiskt bevisas att vara korrekta. Vid typfel kommer vi inte att skriva ut var eller vad för typfel som uppstod, utan bara att det nns ett eller era. Indata till typhärledaren antas vara syntaktiskt korrekta program och fullständigt makroutvecklade. Vi antar också ett förenklat Common Lisp. Symbolerna nil och () är sanningsvärdet falskt. I Common Lisp är allt skilt från nil sant, vi antar att endast symbolen t är sanningsvärdet sant. Uttrycken ' nil och '() innebär en tom lista. Symbolen nil får inte heller returneras implicit, exempelvis av en tom progn eftersom vi inte kan veta om det är menat att vara ett sanningsvärde eller en tom lista. Grenarna av ett if -uttryck måste ha samma typ, samt att båda grenarna måste nnas. Uttrycket let måste tilldela ett värde till variabeln. Vi tillåter inte hellre några destruktiva operationer. 3
10 1.4 Struktur Rapporten tar först upp en komprimerad version av den teori som nns idag för typer och typsystem. Typer och typsystem är ett forskningsområde och rapporten kommer att endast beröra området ytligt. Sedan går rapporten in på typhärledning, vilka algoritmer som nns och en av algoritmerna i detalj, med exempel som visar vad algoritmen klarar av. Därefter implementeras typhärledaren, där teorin översätts till en implementation och utökas för att stödja era konstruktioner. De utökningar som tas upp är författarens egna utökningar och ingår således inte i grundalgoritmen. Verktyget i sig får även stöd för att skapa ett nytt program med typdeklarationer utsatta i programmet. I kapitlen diskuteras även olika lösningar för problemen, och programexempel ges för att illustrera problemen. Avslutningsvis analyseras verktyget, vad vi har gjort och klarar av samt vad som behöver förbättras. De problem och uppgifter som återstår diskuteras samt hur dem kan tänkas att lösas. 1.5 Förutsättningar och notation Rapporten förutsätter att läsaren har kunskaper om Common Lisp och SICPmodellen [3], samt grundläggande matematiska kunskaper. Notationen X Y betyder att X ska ersättas med Y i en substitution. Abstrakta datatyper kommer att följa en namngivning. För en abstrakt datatyp X med fälten Y och Z kommer denna namngivning för konstruktor, selektorer och tester att följas: Konstruktorn har namngivningen: make X Selektorerna har namngivningen: X Y samt X Z Tester har namngivningen: X? 4
11 Kapitel 2 Teori Vi kommer att titta på typer och typsystem. Hur typer uppstår och vad ett typsystem är, samt vad vi kan uträtta med ett typsystem. Sedan kommer vi att undersöka en typhärledningsalgoritm. För att underlätta undersökningen denerar vi ett språk som vi kallar µscheme. Vi går igenom typhärledningsalgoritmen för µscheme, ser hur algoritmen fungerar och vad den klarar av. 2.1 Typer och typsystem I en dator nns det bara en typ och det är en bitsträng. Datorn skiljer inte på instruktioner, pekare, heltal med mera men typer uppstår naturligt när vi börjar skilja och organisera data. Det är inte rimligt att använda data som vi har tänkt att vara pekare som instruktioner. Eftersom detta inte är rimligt har vi därmed två olika typer. Det är vanligt att se typer som en uppskattning för vilka värden som kan antas eller en abstraktion utav en mängd värden. Denitionen av typsystem varierar, men följande denition av Benjamin C. Pierce stöter man på ofta och är accepterad: [A type system is a] tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute.[6] Ett typsystem tilldelar alltså typer till värden och bevisar att vissa beteenden inte kan ske med hänsyn till typerna. Varje uttryck i programmet kommer att ha en typ. Vi vet inte det exakta värdet men vi vet att uttrycket kommer att anta ett av värdena ur mängden. Eftersom vi vet detta kan vi välja att inte tillåta program där den förväntade mängden (typen) inte är en delmängd av den givna för något uttryck. 5
12 Exempelvis kommer följande program inte att tillåtas: (+ 5 ( lambda ( x ) x ) ) Eftersom addition förväntar sig element ur mängden av alla komplexa tal och funktionsobjekt inte ingår i den mängden kommer uttrycket inte att godkännas. Vi skulle kunna välja att inte tillåta program där division med noll kan ske om noll är ett av värdena i typen, men detta ger ett alltför begränsat språk och eftersom typer endast är en approximation tillåter vi oftast denna risk. Att utforma ett typsystem är en övervägning. Genom att ha mer information kan vi uppskatta programmets beteende mer noggrant och därmed kan vi neka mindre korrekta eller godkänna färre felaktiga program. Dock kommer detta med en kostnad eftersom att få denna statiska information kan kräva att vi måste; göra språket mindre expressivt, göra beräkningar dyrare eller tvinga programmeraren att ge extra information i programmet. Det är viktigt att typsystemet är utformat på ett sådant sätt att vi endast nekar felaktiga och inte giltiga program. Ett dåligt utformat typsystem kan neka många giltiga program, vilket leder till frustration för programmeraren om han/hon måste slåss mot typsystemet för att få igenom sitt program. Ett bra utformat typsystem minskar däremot tiden för felsökning. Typkontroll är processen att veriera och upprätthålla restriktioner för typer. Denna kontroll ingår i typsystemet men programmeringsspråk kan välja att göra denna kontroll vid två olika tillfällen: antingen vid kompileringstillfället (statisk) eller körtillfället (dynamisk). Ett språk som gör denna kontroll vid kompileringstillfället eller vid körtillfället sägs vara statiskt typat respektive dynamiskt typat. Det nns fördelar och nackdelar med båda metoderna. Fördelar med att göra kontrollen vid kompileringstillfället är att man kan fånga upp fel innan programmet ens har exekverats och kunna bevisa att inga typfel kommer att kunna ske under körningen. Om man kan ge denna garanti sägs språket vara typsäkert. 1 Kompilatorn kan även ta del av denna garanti och anta att alla värden har rätt typ vid alla tillfällen. På så sätt kan kompilatorn göra optimeringar som att ta bort typkontroller och veta hur mycket minne som behöver allokeras. Nackdelar med statisk typkontroll är att giltiga program kan nekas eftersom de inte vid det statiska tillfället kan avgöras vara typsäkra eller inte. Med andra ord kan statiska språk behövas vara mindre exibla än dynamiska för att kunna ge denna garanti. Fördelar med att göra kontrollen vid körtillfället är som sagt att språket kan bli exiblare än statiskt typade språk. Det enda kravet är att alla värden har rätt typ vid alla tillfällen. Eftersom det är det enda viktiga behövs inga 1 Många statiska språk har kryphål som gör att programmet kan få typfel. 6
13 typsignaturer i programmet, detta gör att man kan skriva sina program mer koncist och därmed ökar produktiviteten. Nackdelar med dynamisk typning är att ingen garanti kan ges att inga typfel kommer att ske och därefter måste vi göra typkontroller under körtillfället vilket kostar processorkraft. Vi måste även spara typinformation för varje värde, och så kräver det mer minnesutrymme. Eftersom ingen garanti ges kompenseras detta oftast genom unit testing, på så sätt hoppas vi fånga upp typfelen under testerna istället men ändå ha tillgång till det mer exibla språket. Det är dock svårt att få samma täckning som statisk typkontroll. 2.2 Typhärledning I många statiska språk behöver användaren skriva ut typsignaturer för uttryck, men detta tvingar användaren att skriva ut information i form av typdeklarationer om koden, i koden. Detta är dock inte nödvändigt då informationen redan nns i koden implicit; vi kan härleda typsignaturer från användningen och sammanhanget. Vi skulle alltså kunna skriva ett program utan typdeklarationer likt de dynamiska språken men ändå ha typsäkerhet. Typhärledning går löst ut på att inspektera hur uttryck sitter ihop och operationer används. Utifrån att vi vet vilka typsignaturer de operationer vi använder har, kan vi härleda vilka krav som ställs på den nya funktionen. De vanligare algoritmer som nns idag är Damas-Milner (kallas även algoritm W) [5] och Wands [9] typhärledningsalgoritmer. I rapporten kommer vi att titta närmare på Wands algoritm. Algoritmen är förvånandsvärt enkel. Det nns två steg: första steget är att generera ekvationer och det andra är att lösa dessa. Vi kommer att ändra lite i algoritmen för våra ändamål, så de bevis som nns i Wands artikel [9] blir inte giltiga. Algoritmen är egentligen för lambdakalkyl. För våra ändamål kommer vi istället att använda ett eget språk likt Scheme som vi kallar µscheme. µscheme har tre bastyper: sanningsvärden, heltal och funktioner. Funktioner tar ett argument och returnerar ett värde (alltid samma typ). Symbolerna för sanningsvärdena är true och false. Denition 1. V är mängden av alla variabler (typiskt x, y, z, e.t.c.). Λ är mängden av alla program i µscheme och denieras på följande vis: 1. V Λ 2. Z Λ 3. true, false Λ 7
14 4. E 1, E 2 Λ (E 1 E 2 ) Λ 5. E 1, E 2 Λ (= E 1 E 2 ) Λ 6. C, E 1, E 2 Λ (if C E 1 E 2 ) Λ 7. E Λ, x V (lambda (x) E) Λ 8. E 1, E 2 Λ, x V (let (x E 1 ) E 2 ) Λ Lägg märke att det ingår program som inte är typkorrekta, exempelvis (lambda (x) (5 x)) ett syntaktiskt korrekt uttryck men 5 är uppenbarligen ingen funktion och är således inte typkorrekt. Inga typsignaturer skrivs ut i detta språk. Vi skulle kunna deniera ett liknande språk där typsignaturerna skrivs ut, uppgiften för typhärledning blir då att översätta från ett språk till ett annat och fylla i de typsignaturer som saknas. Denition 2. T V = {τ 1, τ 2,... } är mängden av alla typvariabler. T E är mängden av alla typuttryck som deneras på följande vis: 1. {Integer, Boolean} T E 2. T V T E 3. t 1, t 2 T E (t 1 t 2 ) T E Mängden T E är alltså alla olika möjliga typsignaturer vi kan ha. Exempelvis Integer Boolean och (τ 1 Integer) Integer ingår i T E. Vi har endast funktioner som tar ett argument, en funktion som tar ett godtyckligt antal argument har typsignaturen t 1 t 2 t n t. Låt oss inte luras att ett argument är en begränsning, vi kan skriva om funktioner som tar ett godtyckligt antal argument till en funktion som tar ett argument genom att låta den nya funktionen returnera en funktion som tar det andra argumentet (och så vidare). Detta kallas för currying 2. Denition 3. A : V T E är en partiell funktion med en ändlig domän. Vi kallar A för typomgivning.vi kommer att skriva A[x : t] för att utöka funktionen A där variabeln x som är associerad med typuttrycket t. Typomgivningen fungerar likt omgivningar i programmeringsspråk (avbildar variabler till ett värde normalt), men avbildar till ett typuttryck istället. Algoritmen för att generera ekvationer består av två komponenter; en loop för att stega igenom programmet och en tabell med regler. Vi kommer att hänvisa denna algoritm som Wands algoritm. 2 Namngivit efter Haskell Curry. 8
15 För att gå igenom programmet används följande algoritm: Indata: Ett uttryck E 0 Λ Initalisering: Sätt EQ = och G = {(A 0, E 0, t 0 )}, där A 0 är en tom typomgivning och t 0 T E. Loop: Om G =, avsluta och returnera EQ. Annars, välj ett element (A, E, t) från G och ta bort elementet från G. Lägg till nya element i EQ och G enligt tabellen av regler med hänsyn på elementet som valdes. EQ är en mängd med ekvationer. Det är denna mängd som vi kommer att behöva lösa, om det går, för att få ut typuttrycken. I G kommer nya deluttryck av programmet att läggas till med en typomgivning och typuttryck, det går att se denna mängd som en kö av uttryck som vi ska inspektera. Algoritmen är hållbar (sound på engelska, innebär att endast korrekta typsignaturer härleds) och fullständig (complete på engelska, innebär att om uttrycket är typkorrekt så härleds typsignaturen) [9] om tabellen med regler alltid terminerar och bevarar hållbarheten och fullständigheten. Vad vi nu behöver är en tabell med regler som algoritmen kan använda sig av. För µscheme kan tabellen se ut: Fall 1. (A, x, t), där x V. Lägg till ekvationen t = A(x). Fall 1. (A, z, t), där z Z. Lägg till ekvationen t = Integer. Fall 2. (A, (M N), t), där M, N Λ. Låt τ vara en ny typvariabel. Lägg till elementen (A, M, τ t) och (A, N, τ) i G. Fall 3. (A, (lambda (x) E), t), där x V och E Λ. Låt τ 1 och τ 2 vara två nya typvariabler. Lägg till ekvationen t = τ 1 τ 2 och elementet (A[x : τ 1 ], E, τ 2 ). Fall 4. (A, (= E 1 E 2 ), t), där E 1, E 2 Λ. Låt τ 1 och τ 2 vara två nya typvariabler. Lägg till ekvationerna τ 1 = Integer och τ 2 = Integer, samt elementen (A, E 1, τ 1 ) och (A, E 2, τ 2 ). Fall 5. (A, (if C E 1 E 2 ), t), där C, E 1, E 2 Λ. Låt τ 1, τ 2 och τ 3 vara tre nya typvariabler. Lägg till ekvationerna τ 1 = Boolean, τ 2 = t och τ 3 = t, samt elementen (A, C, τ 1 ), (A, E 2, τ 2 ) och (A, E 3, τ 3 ). Fall 6. (A, (let (x E 1 ) E), t), där x V och E Λ. Låt τ vara en ny typvariabel. Lägg till elementen (A, E 1, τ) och (A[x : τ], E, t). 9
16 Vi matchar elementet vi valde i loopen med reglerna som nns (om era matchar, ta den mest specika). Enligt reglerna lägger vi till ekvationer och element i EQ och G, sedan fortsätter vi loopen. Vi kan exempelvis typhärleda följande uttryck: ( lambda ( x ) ( lambda ( y ) ( i f (= y 0) ( x 5) 1 0 ) ) ) Följande tabell visar hur algoritmen går igenom uttrycket och bestämmer typsignaturen: Typuttryck Typomgivning Uttryck Ekvationer t 0 (lambda (x)... ) t 0 = t 1 t 2 t 2 {x : t 1 } (lambda (y)... ) t 2 = t 3 t 4 t 4 {x : t 1, y : t 3 } (if (= y 0)... ) t 5 = Boolean, t 4 = t 6, t 5 {x : t 1, y : t 3 } (= y 0) t 4 = t 7 t 5 = Boolean, t 8 = Integer, t 9 = Integer t 8 {x : t 1, y : t 3 } y t 3 = t 8 t 9 {x : t 1, y : t 3 } 0 t 9 = Integer t 6 {x : t 1, y : t 3 } (x 5) t 10 = t 11 t 6 t 10 {x : t 1, y : t 3 } x t 10 = t 1 t 11 {x : t 1, y : t 3 } 5 t 11 = Integer t 7 {x : t 1, y : t 3 } 10 t 7 = Integer Tabell 2.1: Exempel på hur typhärledningsalgoritmen beter sig Nu har vi gått igenom hela uttrycket och skapat ekvationerna (alla ekvationer som står till höger). Andra fasen i algoritmen är att lösa ekvationerna och för att lösa göra detta använder vi oss av uniering. Algoritmen kommer ifrån matematisk logik och ger en substitution som gör att vänster- och högerledet ser likadana ut. Om algoritmen misslyckas har ett typfel upptäckts. Genom att använda uniering kommer vi även få den mest generella typen (eftersom vi kommer att få den mest generella substitutionen), kallas även för principal type. Efter unieringen får vi ut följande: Typvariabel t 0 t 1 (x) t 3 (y) Substitution (Integer Integer) (Integer Integer) Integer Integer Integer 10
17 Typuttrycket t 0 är vad vi börjar med och är därmed typuttrycket för hela uttrycket. Substitutionen som t 0 får är typsignaturen för uttrycket. Uttrycket är alltså en högre ordningens funktion som tar en funktion och returnerar en funktion. Båda funktionerna går från ett heltal till ett heltal. Typuttrycken t 1 och t 3 är för variablerna x respektive y och deras substitution är typsignaturerna för variablerna. Variabeln x ska vara en funktion som går från ett heltal till ett heltal, och y ska vara ett heltal. För att lösa ekvationerna använder vi som sagt uniering. Algoritmen för uniering är [2]: Indata: En mängd ekvationer E. Initialisering: S = där S är en mängd av substitutioner. C = E där C är en stack utav ekvationer. Loop: Om C =, avsluta och returnera S. Annars ta en ekvation X = Y från C: 1. Om X och Y är identiska, gör ingenting. 2. Om X är en typvariabel och X inte förekommer i Y, ersätt då alla förekomster av X med Y i S och C. Lägg sedan till X Y i C. 3. Om Y är en typvariabel och Y inte förekommer i X, ersätt då alla förekomster av Y med X i S och C. Lägg sedan till Y X i C. 4. Om X och Y har formen C(X 1,..., X n ) respektive C(Y 1,..., Y n ) för någon konstruktor C, lägg då till ekvationerna X i = Y i för alla 1 i n på stacken. 5. X och Y unierar inte. Ge ett felmeddelande. Om unieringen inte lyckas innebär detta att ett typfel har uppstått. Uttrycket är således inte typkorrekt. Lägg märke till att detta innebär att en typkontroll utförs implicit i algoritmen. Detta är för att algoritmen endast kan typhärleda giltiga typuttryck och om programmet inte är typkorrekt nns det inget giltigt typuttryck. Omgivningsmodellen för språket tas hand om typomgivningen och kommer att referera till rätt variabel genom den. Om typomgivningen inte är denerad för variabeln (partiell funktion trots allt) betyder det att variabeln inte har deklarerats. Det går bra att lägga in fördenerade funktioner i typomgivningen innan vi typhärleder och kan på så sätt utöka språket på ett väldigt enkelt sätt. 11
18 Säg att vi vill utöka språket med zero?-funktionen. Vi kan då lägga till i typomgivningen att A(zero?) = Integer Boolean. Detta är allt som algoritmen tar upp [9], men det nns mer att lägga till och vi behöver utöka den. Exempelvis så nns även funktioner som är polymorfa. Polymorfa funktioner har egenskapen att de inte ställer några krav på vilken typ argumenten har, utan fungerar på era. Exempelvis identitetsfunktionen som tar ett värde och returnerar samma värde. Funktionen är polymorsk och har typsignaturen X X, där X innebär att funktionen är polymorf och vilken typ som helst kan substitueras in istället för X. Algoritmen klarar av att typhärleda typsignaturen men ett känt problem med polymorsm är let-polymor. Problemet uppstår när vi använder samma polymorfa funktion era gånger: ( lambda ( ) ( l e t ( i d ( lambda ( x ) x ) ) ( i d 5) ( i d i d ) ) ) Funktionen id är identitetsfunktionen och vid första anropet skapar vi en ekvation som säger att x ska vara ett heltal, vid andra anropet skapar vi en till ekvation som säger att x ska vara en funktion. Detta innebär att vid uniering kommer vi att misslyckas eftersom ett heltal ska unieras med en funktion vilket är omöjligt. Problemet uppstår för att vi använt samma typvariabel för x för båda anropen, men programmet är typkorrekt! För att lösa problemet räcker det i detta fall med att substituera in id:s värde på de platser variabeln förekommer. Unieringen kommer att lyckas och uttrycket är korrekt typhärlett. Lösningen kommer dock att ge problem vid rekursion och är därför ingen bra lösning, men det löste problemet. Det som gjorde att det fungerade var att vid användning av id användes nya typvariabler. Vi vill göra så att när vi i typomgivningen slår upp ett uttryck ska vi också ersätta alla fria typvariabler med nya. Detta fungerar bra så länge det inte nns någon typvariabel som är beroende av något utanför räckviden för funktionen. Vi kommer att återvända till detta problem under implementationen. 12
19 Kapitel 3 Implementation Common Lisp är ett stort språk som är dynamiskt typat. Det är omöjligt att typhärleda hela Common Lisp eftersom Common Lisp är dynamiskt typat, om det hade gått skulle vi eektivt ha gjort Common Lisp till ett statiskt typat språk. Vi kommer att fokusera på den funktionella delmängden av Common Lisp. De esta språk som använder sig av typhärledning är funktionella språk och stödjer saker som rekursion, polymorsm, homogena listor, tupler, högre ordningens funktioner, algebraiska datatyper, closures (engelska, skulle kunna översättas till tillslutning/stängning) med mera. Vi implementerar en typhärledare som klarar av dessa konstruktioner. Först översätter vi teorin till Common Lisp. Variabler i Common Lisp är symboler skilda från t och nil. Mängden Λ från teoridelen blir mängden av alla syntaxtiskt korrekta program (begränsas dock till de operationer vi stödjer). Vi kommer att implementera algoritmen annorlunda utifrån Wands algoritm, och istället följa SICP-modellen [3] för att slå upp regler och generera ekvationer. Kapitlet kommer att presenteras likt SICP-boken [3]. Vi börjar med att stödja en delmängd av Common Lisp och sedan utökar vi algoritmen för att stödja er och er konstruktioner. De utökningar som görs på algoritmen tas inte upp i Wands artikel [9] och är författarens egna utökningar. Matematiska bevis kommer inte att presenteras för utökningarna och vi vet således inte om dem är korrekta. 13
20 3.1 Typer Vi skapar en abstrakt datatyp typevariable som håller typvariabeln. Typvariabeln är en symbol som är tänkt att vara unik skapas av gensym. ( defun make t y p e v a r i a b l e ( var ) ( box ' t y p e v a r i a b l e var ) ) ( defun get t y p e v a r i a b l e ( ) ( make t y p e v a r i a b l e ( gensym ) ) ) Funktionen box returnerar helt enkelt en lista taggad med första argumentet och omsluter andra argumentet. Funktionen unbox används för att få ut objektet igen. Abstraktionen används för att skapa egna datatyper som går att göra tester m.m. på. Vi har inga bastyper i samma mening som i teoridelen. Typuttryck och bastyper är starkt sammankopplade. Vi representerar typuttryck som en trippel (name type variables). Attributet name är namnet på typen och ska vara en symbol. Attributet type används för att bygga upp typhierarkin och ska vara ett typuttryck eller en typvariabel. Topptypen (mest generella typen) är innerst och typhierarkin byggs utåt. Undantaget är object som alltid är ytterst för att få polymorfa egenskaper. Attributet variables är en lista av typuttryck som används av typer som listor, funktioner och tupler som behöver mer information. Exempelvis en funktion som behöver information om vilka typuttryck argumenten ska vara och ett typuttryck för vad funktionen avbildar till. ' ( o b j e c t ( i n t e g e r ( t y p e v a r i a b l e x ) ( ) ) ( ) ) ' ( o b j e c t ( l i s t ( t y p e v a r i a b l e x ) ( ( o b j e c t ( t y p v a r i a b l e y ) ( ) ) ) ) ( ) ) Första exemplet representerar typuttrycket för heltal och andra en lista av typen object. Vi skapar även en ny typ object som är unionen av alla typer och agerar som topptypen (vi skulle lika gärna välja att ha en typvariabel som topptyp). Typvariabeln gör det möjligt att uniera ekvationer X = Y där X och Y är olika typuttryck. Om en funktion tar ett argument som är av typen object innebär det att funktionen är polymorsk. Eftersom vi har typvariabler i alla typuttryck klarar vi även av F-Bounded polymorsm. Genom att ge två eller era typuttryck samma typvariabler, exempelvis identitetsfunktionen säger vi att typen som anropas med är samma typ som returneras. Ett annat exempel på F-Bounded polymorsm kan vara funktionen =, som kan kräva att båda argumenten ska vara av samma typ. Med denna representation skulle vi kunna göra en hierarki av typer och tillåta undertypspolymorsm, men det är tyvärr inte möjligt. 14
21 Det är lockande att representera typhierarkin på följande sätt: ' ( o b j e c t ( complex ( r e a l ( r a t i o n a l ( i n t e g e r ( t y p e v a r i a b l e x ) ( ) ) ( ) ) ( ) ) ( ) ) ( ) ) Och sedan utnyttja unieringsalgoritmen. Exempelvis hade typhärledningsalgoritmen korrekt härlett uttrycket (= x 5), och påstått att x måste vara ett heltal. Dock fungerar det inte med uttrycket ( if x ). Typhärledaren hade påstått att uttrycket ger ett heltal trots att den korrekta och mest generella typen är ett reellt tal. Vi kommer att uniera ett reellt tal med ett heltal, vilket ger ett heltal. Det är uppenbarligen fel. Om vi vänder på typhierarkin löser vi detta problem. ' ( o b j e c t ( i n t e g e r ( r a t i o n a l ( r e a l ( complex ( t y p e v a r i a b l e x ) ( ) ) ( ) ) ( ) ) ( ) ) ( ) ) Anta att funktionerna foo och bar har typsignaturerna Real Boolean respektive X Complex. Uttrycket (foo (bar x)), enligt typhärledaren, skulle lyckas och inte ha några typfel. Detta är uppenbarligen fel då funktionen foo får ett komplext tal. Anledningen till varför det lyckas är för att komplexa och reella tal unierar. Således går det inte att representera typhierarkin på det sättet. Antagligen måste vi utöka unieringsalgoritmen för att kunna förstå typhierarkin och lösa ekvationssystemet på ett annat sätt. 3.2 Omgivningar Common Lisp har två omgivningar, en för variabler och en för funktioner. En abstrakt datatyp skapas för båda omgivningarna som vi kallar för typomgivning och kallar de riktiga typomgivningarna för variabelomgivning och funktionsomgivning respektive. Vi kommer även att ha en omgivning för ekvationer som vi kallar för ekvationsomgivning. Senare i rapporten redovisas det varför vi vill ha en omgivning för ekvationer. ( defun make type environment ( cenv venv f e n v ) ( box ' type environment ( l i s t cenv venv fenv ) ) ) En omgivning består av en ram, en inneslutande omgivning, lista på omgivningar som utökar omgivningen samt det uttryck som skapade omgivningen. Ramarna består av ett par av listor; första listan består av variabel/funktion namn, och den andra av typuttryck. Den inneslutande omgivningen är den omgivning som det utökades ifrån. Vi har valt att spara en referens till de omgivningar som utökar omgivningen eftersom vi inte vill att ramarna ska förstöras efter att de använts. Det är också intressant att spara uttrycket 15
22 som skapade ramen. Vi kommer att se senare i implementationen varför vi vill spara omgivningarna och uttrycket. ( defun make environment ( frame e n c l o s i n g e x p r e s s i o n &o p t i o n a l ( e x t e n d i n g ( empty extending l i s t ) ) ) ( l i s t frame e n c l o s i n g e x p r e s s i o n e x t e n d i n g ) ) ( defun make frame ( v a r i a b l e s v a l u e s ) ( cons v a r i a b l e s v a l u e s ) ) ( defun extend environment ( v a r s v a l s base env &o p t i o n a l ( e x p r e s s i o n n i l ) ) ( i f (= ( l e n g t h v a r s ) ( l e n g t h v a l s ) ) ( l e t ( ( frame ( make frame v a r s v a l s ) ) ( env ( make environment frame base env e x p r e s s i o n ) ) ) ( cons e x t e n d i n g! env ( extending environments base env ) ) env ) ( e r r o r ' extend environment ) ) ) Vi utökar typomgivningar med extend type environment. Den returnerar en ny typomgivning där de tre omgivningarna som den kapslar in är utökade. ( defun extend type environment ( v v a r s v v a l s env ) ( l e t ( ( cenv ( environment cenv env ) ) ( venv ( environment venv env ) ) ( fenv ( environment fenv env ) ) ( cenv2 ( extend environment ' ( ) ' ( ) cenv ) ) ( venv2 ( extend environment v v a r s v v a l s venv ) ) ( fenv2 ( extend environment ' ( ) ' ( ) fenv ) ) ) ( make type environment cenv venv fenv ) ) ) Den globala typomgivningen är en utökning av den tomma typomgivningen. I den globala funktionsomgivningen kan vi lägga fördenerade funktioner som exempelvis +,, mapcar, list, cdr, cons, equal och så vidare. Det blir väldigt lätt att utöka språket med funktioner genom att lägga dem i den globala funktionsomgivnigen. 16
23 Tabell 3.1 listar de funktioner som arbetar på typomgivningar, omgivningar och ramar. Namnen är självförklarande. Typomgivningar Omgivningar Ramar get function value extend environment frame variables get variable value the empty environment frame values add variable! empty environment? make frame add function! get global environment add constraint! rst frame get global type environment fetch constraints make global type environment make empty type environment extend type environment enclosing environment environment expression extending environments add binding to frame lookup variable value set variable value! dene variable! make environment Tabell 3.1: Funktioner som arbetar på typomgivningar, omgivningar och ramar. 3.3 Ekvationer och uniering En ekvation består av ett vänster- och ett högerled där leden ska vara ett typuttryck. En abstrakt datatyp constraint för ekvationer skapas. Vi har även en abstrakt datatyp substitution för substitutioner, likt ekvationer har substitutioner ett vänster- och högerled där vänsterledet är en typvariabel och högerledet är ett typuttryck. ( defun make c o n s t r a i n t ( l e f t r i g h t ) ( box ' c o n s t r a i n t ( l i s t l e f t r i g h t ) ) ) ( defun make s u b s t i t u t i o n ( var s u b s t ) ( box ' s u b s t i t u t i o n ( l i s t var s u b s t ) ) ) Unieringsalgoritmen följer nästan exakt algoritmen i teoridelen. Typvariabler motsvarar variabler och typuttryck motsvarar termer. Funktionen list constraints tar två listor och skapar elementvis ekvationer. Uttrycket (rec substitute new old obj) går rekursivt igenom typuttryck och ersätter typvariabeln old med new i obj. Unieringsfel betyder att ett typfel har uppstått och att programmet inte är typsäkert. 17
24 ( defun u n i f i c a t i o n ( s t a c k &o p t i o n a l ( s u b s t s ' ( ) ) ) ( i f ( n u l l s t a c k ) s u b s t s ( l e t ( ( c o n s t r ( f i r s t s t a c k ) ) ( x ( c o n s t r a i n t l e f t c o n s t r ) ) ( y ( c o n s t r a i n t r i g h t c o n s t r ) ) ) ( cond ( ( and ( t y p e v a r i a b l e? x ) ( t y p e v a r i a b l e? y ) ( equal t y p e v a r i a b l e s? x y ) ) ( u n i f i c a t i o n ( r e s t s t a c k ) s u b s t s ) ) ( ( and ( t y p e v a r i a b l e? x ) ( not ( occurs check x y ) ) ) ( u n i f i c a t i o n ( rec s u b s t i t u t e y x ( r e s t s t a c k ) ) ( cons ( make s u b s t i t u t i o n x y ) ( rec s u b s t i t u t e y x s u b s t s ) ) ) ) ( ( and ( t y p e v a r i a b l e? y ) ( not ( occurs check y x ) ) ) ( u n i f i c a t i o n ( rec s u b s t i t u t e x y ( r e s t s t a c k ) ) ( cons ( make s u b s t i t u t i o n y x ) ( rec s u b s t i t u t e x y s u b s t s ) ) ) ) ( ( and ( t y p e e x p r e s s i o n? x ) ( t y p e e x p r e s s i o n? y ) ( equal t y p e e x p r e s s i o n s? x y ) ) ( u n i f i c a t i o n ( append ( cons ( make c o n s t r a i n t ( t y p e e x p r e s s i o n type x ) ( t y p e e x p r e s s i o n type y ) ) ( l i s t c o n s t r a i n t s ( t y p e e x p r e s s i o n v a r i a b l e s x ) ( t y p e e x p r e s s i o n v a r i a b l e s y ) ) ) ( r e s t s t a c k ) ) s u b s t s ) ) ( t ( e r r o r ' u n i f i c a t i o n f a i l u r e ) ) ) ) ) ) 3.4 Substitution Av unieringen fås en substitution. Vi vill substituera på typomgivningen (alla tre omgivningar), för att göra detta denerar vi funktionerna rec substitute! och typeexpression substitute! samt frame substitution!, environment substitution! och ext environment substitution!. Funktionen rec substitute! tar tre argument; det nya typuttrycket, den typvariabel som ska ersättas och ett typuttryck. Den går igen typuttrycket och ersätter alla typvariabler som motsvarar typvariabeln och ersätter med det nya typuttrycket. 18
25 Funktionen typeexpression substitute! tar två argument; ett typuttryck och en substitution och applicerar substitutionen på typuttrycket. Funktionen frame substitution! tar en substitution, en ram och en funktion. Vi behöver funktionen för att ramarna i funktionsomgivningen är ekvationer och inte typuttryck. Funktionen frame substitution! applicerar substitutionen på varje typuttryck i ramen. För variabel- och funktionsomgivningen ska funktionen vara identitetsfunktionen men för ekvationsomgivningen behöver vi en funktion som tar en lista av ekvationer och returnerar en lista med typuttryck (vänster- och högerleden). Funktionen environment substitution! tar tre argument; en substitution, en omgivning och en funktion. Funktionen anropar frame substitution! på sin ram och inneslutande omgivningars ramar rekursivt. Funktionen ext environment substitution! tar tre argument; en substitution, en omgivning och en funktion. Denna gör tvärtom emot environment substitution! och substituerar rekursivt i de utökande omgivningarna istället. Vi kommer att se senare varför vi vill ha detta. ( defun rec s u b s t i t u t e! ( new o l d t e ) ( l a b e l s ( ( l s t s u b s t! ( l i s t ) ( i f ( not ( endp l i s t ) ) ( rec s b u s t i t u t e! new o l d ( c a r l i s t ) ) ) ) ) ( l e t ( ( type ( t y p e e x p r e s s i o n type t e ) ) ( v a r s ( t y p e e x p r e s s i o n v a r i a b l e s t e ) ) ) ( cond ( ( and ( t y p e v a r i a b l e? type ) ( equal t y p e v a r i a b l e? type o l d ) ) ( s e t f ( t y p e e x p r e s s i o n type t e ) new ) ( l s t s u b s t! v a r s ) ) ( t ( rec s u b s t i t u t e! new o l d type ) ( l s t s u b s t! v a r s ) ) ) ) ) ) ( defun t y p e e x p r e s s i o n s u b s t i t u t e! ( t e s u b s t s ) ( cond ( ( endp s u b s t s ) t e ) ( t ( rec s u b s t i t u t e! ( s u b s t i t u t i o n s u b s t ( c a r s u b s t s ) ) ( s u b s t i t u t i o n i d e n t ( c a r s u b s t s ) ) t e ) ( t y p e e x p r e s s i o n s u b s t i t u t e! t e ( r e s t s u b s t s ) ) ) ) ) ( defun frame s u b s t i t u t i o n! ( s u b s t s frame fun ) ( l a b e l s ( ( aux ( t e l i s t ) ( i f ( not ( endp t e l i s t ) ) ( progn ( t y p e e x p r e s s i o n s u b s t i t u t e! ( c a r t e l i s t ) s u b s t s ) ( aux ( r e s t t e l i s t ) ) ) ) ) ) ( aux ( frame v a l u e s ( f u n c a l l fun frame ) ) ) ' ok ) ) 19
26 ( defun environment s u b s t i t u t i o n! ( s u b s t s env &o p t i o n a l ( fun ( lambda ( x ) x ) ) ) ( l a b e l s ( ( env loop ( env ) ( i f ( not ( empty environment? env ) ) ( progn ( frame s u b s t i t u t i o n! s u b s t s ( f i r s t frame env ) fun ) ( env loop ( e n c l o s i n g environment env ) ) ) ) ) ) ( env loop env ) ' ok ) ) ( defun ext environment s u b s t i t u t i o n! ( s u b s t s xenv &o p t i o n a l ( fun ( lambda ( x ) x ) ) ) ( l a b e l s ( ( aux ( ext envs ) ( cond ( ( empty extending l i s t? ext envs ) ' ok ) ( t ( ext environment s u b s t i t u t i o n! s u b s t s ( c a r ext envs ) ) ( aux ( r e s t ext envs ) ) ) ) ) ) ( frame s u b s t i t u t i o n! s u b s t s ( f i r s t frame xenv ) fun ) ( aux ( extending environments xenv ) ) ) ) Vi denierar även en funktion tenv substitution! som tar en substitution, en typomgivning och substituerar i alla typuttryck i omgivningen och även i alla utökningar: ( defun tenv s u b s t i t u t i o n! ( s u b s t s env ) ( l e t ( ( cenv ( environment cenv env ) ) ( venv ( environment venv env ) ) ( fenv ( environment fenv env ) ) ) ( environment s u b s t i t u t i o n! s u b s t s venv ) ( environment s u b s t i t u t i o n! s u b s t s fenv ) ( environment s u b s t i t u t i o n! s u b s t s cenv ) ( ext environment s u b s t i t u t i o n! s u b s t s venv ) ( ext environment s u b s t i t u t i o n! s u b s t s fenv ) ( ext environment s u b s t i t u t i o n! s u b s t s cenv ( lambda ( x ) ( append ( mapcar #' c o n s t r a i n t l e f t x ) ( mapcar #' c o n s t r a i n t r i g h t y ) ) ) ) ' ok ) ) 3.5 Generera ekvationer Vi kommer inte att implementera Wands algoritm som nns i teoridelen för att gå igenom programmet utan implementerar något som liknar en interpretator. Idén med att separera algoritmen och tabellen i teoridelen är att det är lätt att bevisa att algoritmen kommer att göra rätt med antagandet att tabellen är korrekt. Sedan behöver vi endast bevisa att tabellen är korrekt, 20
27 det gör beviset enklare. Vi kommer dock att indirekt ha en tabell med regler i vår algoritm. Indata till vår typhärledare är det Lisp-uttryck som vi ska härleda, uttrycket är ett S-uttryck och vi kommer att använda de interna funktionerna i Lisp för att känna igen kod. För att granska om ett uttryck är en variabel ska det vara en symbol skilt från nil och t. Liknande denitioner kan göras för andra uttryck, exempelvis ska defun vara en lista där det första elementet ska vara lika med symbolen defun. Detta räcker för att känna igen syntaktiskt korrekt kod men vi kan välja att göra nogrannare tester och ge felmeddelanden om programmet är syntaktiskt inkorrekt. Alla uttryck känns igen på liknande sätt. Kom ihåg att ' x och #'x är syntaxtiskt socker för (quote x) respektive (function x) och känns igen genom att titta efter symbolerna quote och function. ( defun l i s p v a r i a b l e? ( expr ) ( and ( symbolp expr ) ( not ( e q u a l t expr ) ) ( not ( l i s t p expr ) ) ) ) ( defun l i s p defun? ( expr ) ( and ( l i s t p expr ) ( eq ( c a r expr ) ' defun ) ) ) ( defun quoted? ( expr ) ( and ( l i s t p expr ) ( e q u a l ( f i r s t expr ) ' quote ) ) ) Nu när vi kan känna igen vad det är för uttryck kan vi granska vilka regler som gäller och anropa den funktion tar hand om uttrycket. Precis som i teoridelen vill vi ha ett uttryck, typuttryck och en typomgivning. När vi startar typhärledningen kommer typuttrycket att vara ett object-typuttryck. Det går att se variabeln som att vi skickar in det typuttryck som vi förväntar oss. Vi har inget returvärde från algoritmen då vi gör allt destruktivt i typomgivningen (kom ihåg att vi har en omgivning för ekvationer). ( defun generate c o n s t r a i n t s! ( expr type env ) ( cond ( ( l i s p c o n s t a n t? expr ) ( constant c o n s t r a i n t s! expr type env ) ) ( ( l i s p v a r i a b l e? expr ) ( v a r i a b l e c o n s t r a i n t s! expr type env ) ) ( ( l i s p lambda? expr ) ( lambda c o n s t r a i n t s! expr type env ) ) ( ( l i s p f u n c t i o n? expr ) ( f u n c t i o n c o n s t r a i n t s! expr type env ) ) ( ( l i s p f u n c a l l? expr ) ( f u n c a l l c o n s t r a i n t s! expr type env ) ) ( ( l i s p progn? expr ) ( progn c o n s t r a i n t s! expr type env ) ) ( ( l i s p i f? expr ) ( i f c o n s t r a i n t s! expr type env ) ) ( ( l i s p cond? expr ) ( cond c o n s t r a i n t s! expr type env ) ) ( ( l i s p l e t? expr ) ( l e t c o n s t r a i n t s! expr type env ) ) ( ( l i s p defun? expr ) ( defun c o n s t r a i n t s! expr type env ) ) ( ( l i s p l a b e l s? expr ) ( l a b e l s c o n s t r a i n t s! expr type env ) ) 21
28 ( ( l i s p c a l l? expr ) ( c a l l c o n s t r a i n t s! expr type env ) ) ( t ( e r r o r ' unknown e x p r e s s i o n ) ) ) ) Det är viktigt att anropa lisp call? sist då den även fångar upp special forms. Detta är vår motsvarighet till tabellen i teoridelen, reglerna är funktionerna som anropas om testet lyckas. Vi anropar den funktion som hanterar reglerna för uttrycket. Om denna regel behöver typhärleda något deluttryck anropas generate constraints! igen rekursivt. Vi kommer då på ett enkelt sätt stega igenom programmet likt en interpretator. Ingen kö likt Wands algoritm i teoridelen behövs. Om uttrycket är en variabel kommer vi att slå upp typuttrycket i variabelomgivningen och skapa en ekvation med det typuttryck vi ck. För exempelvis en if -sats plockar vi istället ut villkoret och grenarnas uttryck. För det villkorliga uttrycket förväntar vi oss ett booleskt typuttryck så vi skapar ett nytt typuttryck och skickar in det. För grenarna förväntas samma typuttryck som if -uttrycket så vi använder det typuttryck vi ck. Vi anropar sedan generate constraints! med de uttrycken. Vi gör ingen test om den falska grenen nns eller inte, för om den inte nns returneras nil som vi inte vet hur vi ska tolka. ( defun v a r i a b l e c o n s t r a i n t s! ( expr type env ) ( add c o n s t r a i n t! ( make c o n s t r a i n t type ( get v a r i a b l e v a l u e expr env ) ) env ) ' ok ) ( defun i f c o n s t r a i n t s! ( expr type env ) ( l e t ( ( c o n d i t i o n a l ( second expr ) ) ( then ( t h i r d expr ) ) ( e l s e ( f o u r t h expr ) ) ) ( generate c o n s t r a i n t s! c o n d i t i o n a l ( boolean type ) env ) ( generate c o n s t r a i n t s! then type env ) ( generate c o n s t r a i n t s! e l s e type env ) ' ok ) ) Funktionen add constraint! lägger till ekvationen i ekvationsomgivningen. boolean type skapar ett booleskt-typuttryck. För att om det är en konstant behöver vi endast använda de inbyggda Lisp-typkontrollerna. Vi kan dock inte granska om någonting är en lista med dessa, då de esta uttryck är listor och vi behöver granska om uttrycket är en quote'ad lista. Till en början kommer vi inte att stödja listor då vi endast vill ha homogena listor och att få ut typen av en lista kräver extra arbete. Kom ihåg att en quote'ad konstant är samma sak som en icke-quote'ad konstant (förutom listor). 22
29 ( defun l i s p c o n s t a n t? ( expr ) ( or ( quoted? expr ) ( numberp expr ) ( c h a r a c t e r p expr ) ( s t r i n g p expr ) ( booleanp expr ) ) ) ( defun get constant type ( expr ) ( l a b e l s ( ( aux ( expr ) ( cond ( ( booleanp expr ) ( boolean type ) ) ( ( symbolp expr ) ( symbol type ) ) ( ( s t r i n g p expr ) ( s t r i n g type ) ) ( ( c h a r a c t e r p expr ) ( c h a r a c t e r type ) ) ( ( i n t e g e r p expr ) ( i n t e g e r type ) ) ( ( r a t i o n a l p expr ) ( r a t i o n a l type ) ) ( ( r e a l p expr ) ( r e a l type ) ) ( ( complexp expr ) ( complex type ) ) ( ( numberp expr ) ( number type ) ) ( t ( e r r o r ' not a c o n s t a n t ) ) ) ) ) ( i f ( quoted? expr ) ( aux ( unquote expr ) ) ( aux expr ) ) ) ) Funktionen unquote hämtar ut det quote'ade uttrycket (andra elementet). Nu när vi kan granska om någonting är en konstant och få ut typuttryck för konstanten kan vi enkelt skapa en regel som skapar en ekvation. ( defun constant c o n s t r a i n t s! ( expr type env ) ( add c o n s t r a i n t! ( make c o n s t r a i n t type ( get constant type expr ) ) env ) ' ok ) Hittills har vi endast gått igenom konstruktioner som inte utökar typomgivningen. Vi ska därför undersöka defun som utökar typomgivningen och lägger till en ny bindning i funktionsomgivningen. Uttrycket defun har ett namn, en formell parameterlista och en kropp. Vi plockar ut respektive del. Kom ihåg att uttrycket i sig returnerar en symbol med funktionens namn och inte vad funktionen returnerar. Vi skapar ett object-typuttryck för varje variabel i parameterlistan, skapar ett object-typuttryck för kroppen samt en för funktionen där funktionen går från de typuttryck vi skapade för parameterlistan till typuttrycket vi skapade för kroppen. Vi måste lägga till en ny bindning i den globala funktionsomgivningen med namnet och funktionstyputtrycket. Sedan utökas typomgivningen där variabelnamnen binds till deras typuttryck. Vi har också en implicit progn i kroppen, det räcker med att lägga till symbolen progn i kroppen och vid anropet till generate constraints! kommer rätt regel ta hand om kroppen. Vi tar inte upp progn i rapporten men denitionen har inga överraskningar. 23
Tentamen i. TDDC67 Funktionell programmering och Lisp
1 Linköpings tekniska högskola Institutionen för datavetenskap Anders Haraldsson Tentamen i TDDC67 Funktionell programmering och Lisp och äldre kurser TDDC57 Programmering, Lisp och funktionell programmering
Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler
21-1-2 1 Dagens föreläsning Hur fungerar ett Lisp system intern struktur av symbolen, tal, listan pekare - delade strukturer - eq minneshantering fri lista - sophämtning/garbage collection stack Diverse
Dagens föreläsning Programmering i Lisp. - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning
1 Dagens föreläsning Programmering i Lisp - Block, räckvidd - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning - Felhantering (kap 17) icke-normala återhopp catch
Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson
1 2 - Block, räckvidd Dagens föreläsning Programmering i Lisp - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning - Felhantering (kap 17) icke-normala återhopp catch
Tentamen i. TDDA 69 Data och programstrukturer
1 Linköpings tekniska högskola Institutionen för datavetenskap Anders Haraldsson Tentamen i TDDA 69 Data och programstrukturer Torsdag den 14 januari 2009, kl 14-18 Hjälpmedel: Inga. Poänggränser: Maximalt
Dagens föreläsning Programmering i Lisp Fö 5
Anders Haraldsson 1 Dagens föreläsning Programmering i Lisp Fö 5 - Funktioner - lambda-uttryck (avs 7.1) - funcall och function (avs 7.2) - Högre ordningens funktioner (avs 7.3) - Iteratorer - Egenskaper
Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2
Anders Haraldsson 1 Anders Haraldsson 2 Dagens föreläsning Programmering i Lisp Fö 5 - Funktioner - lambda-uttryck (avs 7.1) - funcall och function (avs 7.2) - Högre ordningens funktioner (avs 7.) - Iteratorer
Typsystem. Typsystem... Typsystem... Typsystem... 2 *
Typsystem Typsystem finns i alla programmeringsspråk. Avsikten med typsystem är att kontrollera att uttryck är säkra i den bemärkelsen att innebörden i operanderna är klar och inte är motsägelsefull och
Typsystem. DA2001 (Föreläsning 23) Datalogi 1 Hösten / 19
Typsystem Typsystem finns i alla programmeringsspråk. Avsikten med typsystem är att kontrollera att uttryck är säkra i den bemärkelsen att innebörden i operanderna är klar och inte är motsägelsefull och
TDDC74 Programmering, abstraktion och modellering. Tentamen
AID-nummer: Datum: 2012-01-10 1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering Tentamen Tisdag 10 januari
TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014
TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014 Läs alla frågorna först, och bestäm dig för i vilken ordning du vill lösa uppgifterna. Skriv tydligt och läsligt. Använd
TDDC74 Programmering, abstraktion och modellering. Tentamen
AID-nummer: Datum: 2011-06-10 1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering Tentamen Fredag 10 juni
TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18
TDDC74 Programmering: Abstraktion och modellering Datortenta - 017-10-7, kl 14-18 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis
Omgivningar. Omgivningar är viktiga eftersom de avgör vilka namn som är synliga och därmed dessas innebörd och de värden som är förknippade med dem.
Omgivningar Omgivningar är viktiga eftersom de avgör vilka namn som är synliga och därmed dessas innebörd och de värden som är förknippade med dem. (define (sqrroot c) (define (fixpoint guess c eps) (define
DD1361 Programmeringsparadigm. Carina Edlund
DD1361 Programmeringsparadigm Carina Edlund carina@nada.kth.se Funktionell programmering Grundidéen med funktionell programmering är att härma matematiken och dess funktionsbegrepp. Matematiskt funktionsbegrepp
TDDC74 Lab 04 Muterbara strukturer, omgivningar
TDDC74 Lab 04 Muterbara strukturer, omgivningar 1 Översikt I den här laborationen kommer ni att lära er mer om: Tillstånd, och skillnader mellan ren funktionell programmering och imperativ. Skillnaden
Programmering II (ID1019) :00-11:00
ID1019 Johan Montelius Programmering II (ID1019) 2015-06-11 08:00-11:00 Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten. Svaren
Uppgift 4A - Definition av enkla funktioner
Uppgift 4A - Definition av enkla funktioner (defun start-klockslag (tidsperiod) "tidsperiod -> klockslag" (typkontroll tidsperiod #'tidsperiod?) (first (packa-upp tidsperiod))) (defun slut-klockslag (tidsperiod)
Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad
1 Datatyper Tobias Wrigstad Det finns flera olika typer av (slags) data Olika datatyper har olika egenskaper. T.ex. är ett personnummer inte ett tal. (Den sista siffran skall stämma enligt den s.k. Luhnalgoritmen
Föreläsning 6: Introduktion av listor
Föreläsning 6: Introduktion av listor Med hjälp av pekare kan man bygga upp datastrukturer på olika sätt. Bland annat kan man bygga upp listor bestående av någon typ av data. Begreppet lista bör förklaras.
Funktionell programmering DD1361
Funktionell programmering DD1361 Tupler Två eller fler (men ändligt) antal element. Elementen kan vara av olika typer. Ex: (1,2) :: (Integer, Integer) (( 2, hejsan ), True) ::? Tupel med två element ->
TDDC74 Programmering, abstraktion och modellering. Tentamen
AID-nummer: Datum: 2011-08-17 1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering Tentamen Onsdag 17 augusti
Dataabstraktion. TDDD73 Funktionell och impterativ programmering i Python Föreläsning 12. Peter Dalenius Institutionen för datavetenskap
Dataabstraktion TDDD73 Funktionell och impterativ programmering i Python Föreläsning 12 Peter Dalenius Institutionen för datavetenskap 2013-11-12 Översikt Vad är abstraktion? Vad är en abstrakt datatyp?
Introduktion till programmering D0009E. Föreläsning 5: Fruktbara funktioner
Introduktion till programmering D0009E Föreläsning 5: Fruktbara funktioner 1 Retur-värden Funktioner kan både orsaka en effekt och returnera ett resultat. Hittills har vi ej definierat några egna funktioner
TDDC74 Programmering, abstraktion och modellering. Tentamen
AID-nummer: Datum: 2011-01-11 1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering Tentamen Tisdag 11 januari
Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.
Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E Föreläsning 4: Villkor och rekursion Konverterar mellan de grundläggande typerna: >>> int("") >>> int(.999) >>> float().0
Programmering II (ID1019) :00-12:00
ID1019 Johan Montelius Programmering II (ID1019) 2015-03-13 09:00-12:00 Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten. Svaren
n Detta för att kunna koncentrera oss på n Tal: number? n Symboler: symbol? n Strängar: string? n Tecken: char? n Boolskt: boolean?
Tidigare TDDC74 Programming: Abstraktion och modellering Föreläsning 4 Symboler, Par, Listor Representation av par, Grafisk notation för par Representation av listor mha par Typiska listhanteringsprocedurer
TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017
FÖRELÄSNING 1 TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017 Introduktion till kursen Schemespråkets grunder Enkla exempel Jalal Maleki Institutionen för datavetenskap Linköpings universitet
Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion
Introduktion till programmering Föreläsning 4: Villkor och rekursion 1 1 Några inbyggda funktioner (med resultat!) Konverterar mellan de grundläggande typerna: >>> int("32") 32 >>> int(3.999) 3 >>> float(32)
Inledande programmering med C# (1DV402) Summera med while"-satsen
Summera med while"-satsen Upphovsrätt för detta verk Inledande programmering med C# (1DV402) Detta verk är framtaget i anslutning till kursen Inledande programmering med C# vid Linnéuniversitetet. Du får
Dagens föreläsning. Modeller för programmeringsspråk. - Olika modeller programspråk Interpretator - kompilator. - Syntax - semantik.
1 Dagens föreläsning Modeller för programmeringsspråk - Olika modeller programspråk Interpretator - kompilator - Olika typer av språk Statiska och dynamiska programspråk - Syntax - semantik. Grammatik
TDDC74 Programmering, abstraktion och modellering DUGGA 2
AID-nummer: Datum: 2011-02-18 1 Tekniska högskolan vid Linköpings universitet Institutionen för datavetenskap Anders Haraldsson TDDC74 Programmering, abstraktion och modellering DUGGA 2 Fredag 18 feb 2011
Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt
Föreläsning 2 Programmeringsteknik och C DD1316 Mikael Djurfeldt Föreläsning 2 Programmeringsteknik och C Python introduktion Utskrift Inläsning Variabler Datatyp Aritmetiska operatorer Omvandling
Classes och Interfaces, Objects och References, Initialization
Classes och Interfaces, Objects och References, Initialization Objekt-orienterad programmering och design (DIT953) Niklas Broberg/Johannes Åman Pohjola, 2018 Abstract class En abstract class är en class
Programmering II (ID1019) :00-12:00
ID1019 Johan Montelius Programmering II (ID1019) 2014-01-16 09:00-12:00 Förnamn: Efternamn: Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten.
Introduktion till programmering SMD180. Föreläsning 5: Fruktbara funktioner
Introduktion till programmering Föreläsning 5: Fruktbara funktioner 1 Retur-värden Funktioner kan både orsaka en effekt och returnera ett resultat. Hittills har vi ej definierat några egna funktioner med
Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)
Programmönster: # Listan som sekvens, Rekursiv process Enkel genomgång av sekvens (element på toppnivån i en lista)) TDDC60 Programmering: abstraktion och modellering Föreläsning 5 Rekursiva och iterativa
Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson
1 2 Dagens föreläsning Modeller för programmeringsspråk Interpretator - att interpretera ett program - att beräkna ett program - Olika modeller programspråk Interpretator - kompilator program i S interpretator
Programmering II (ID1019)
ID1019 Johan Montelius Instruktioner Betyg Programmering II (ID1019) 2019-03-08 Svaren skall lämnas på dessa sidor, använd det utrymme som nns under varje uppgift för att skriva ner ditt svar (inte på
TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12
TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12 Läs alla frågorna först, och bestäm dig för i vilken ordning du vill lösa uppgifterna. Skriv tydligt och läsligt.
Imperativ programmering. Imperativ programmering konstruktioner i Lisp. Datastrukturer (kap ) arraystruktur poststruktur
Imperativ programmering konstruktioner i Lisp Imperativ programmering I den imperativa programmeringen skriver vi program satsvist. Datastrukturer (kap.-.) aystruktur poststruktur Iterativa uttryck (avs.)
TDDC74 Lab 02 Listor, sammansatta strukturer
TDDC74 Lab 02 Listor, sammansatta strukturer 1 Översikt I denna laboration kommer ni att lära er mer om: Mer komplexa rekursiva mönster, procedurer och processer. Hur man kan hantera listor och andra enklare
Imperativ programmering. Föreläsning 2
Imperativ programmering 1DL126 3p Föreläsning 2 Imperativ programmering Kännetecken för imperativa språk: Programmet består av en serie instruktioner. Olika språk har olika uppsättningar av instruktioner.
Bakgrund och motivation. Definition av algoritmer Beskrivningssätt Algoritmanalys. Algoritmer. Lars Larsson VT 2007. Lars Larsson Algoritmer 1
Algoritmer Lars Larsson VT 2007 Lars Larsson Algoritmer 1 1 2 3 4 5 Lars Larsson Algoritmer 2 Ni som går denna kurs är framtidens projektledare inom mjukvaruutveckling. Som ledare måste ni göra svåra beslut
Tentamen Grundläggande programmering
Akademin för Innovation Design och Teknik Tentamen Grundläggande programmering Kurskod: DVA103 Datum 2012-06-11 Tid 14.10 16.30 Examinator: Lars Asplund Maxpoäng: 48 Betygsgränser: Betyg 3: 20 Betyg 4:
Objektorienterad Programmering (TDDC77)
Objektorienterad Programmering (TDDC77) Föreläsning II: utmatning, variabler, typer Ahmed Rezine IDA, Linköpings Universitet Hösttermin 2017 Outline Java Språket Utmatning av Sträng litteraler Variabler
Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }
En klassdefinition class A extends B {... Arv definierar en klass A som ärver av B. Klassen A ärver alla fält och metoder som är definierade för B. A är en subklass till B. B är en superklass till A. class
12. Relationer och funktioner
Objektorienterad modellering och diskreta strukturer 12. Relationer och funktioner Sven Gestegård Robertz Institutionen för datavetenskap, LTH 2013 Laboration 4 Syntaxanalys Grammatik för (vår delmängd
Variabler, värden och typer
Variabler, värden och typer Viktigt att förstå på djupet: För programmering i många språk, t.ex. Java För kommande objektorientering! TDDD78, TDDE30, 729A85 jonas.kvarnstrom@liu.se 2018 Fråga kommentera
Användarhandledning Version 1.2
Användarhandledning Version 1.2 Innehåll Bakgrund... 2 Börja programmera i Xtat... 3 Allmänna tips... 3 Grunderna... 3 Kommentarer i språket... 4 Variabler... 4 Matematik... 5 Arrayer... 5 på skärmen...
TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 2015, kl 8 12
TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 215, kl 8 12 Läs alla frågorna först, och bestäm dig för i vilken ordning du vill lösa uppgifterna. Skriv tydligt och läsligt.
Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek
De åtta primitiva typerna Java, datatyper, kontrollstrukturer Skansholm: Kapitel 2) Uppsala Universitet 11 mars 2005 Typ Innehåll Defaultvärde Storlek boolean true, false false 1 bit char Tecken \u000
Tentamen i kurserna Beräkningsmodeller (TDA181/INN110) och Grundläggande Datalogi (TDA180)
Göteborgs Universitet och Chalmers Tekniska Högskola 25 oktober 2005 Datavetenskap TDA180/TDA181/INN110 Tentamen i kurserna Beräkningsmodeller (TDA181/INN110) och Grundläggande Datalogi (TDA180) Onsdagen
allt.cl Page 1 of 17 Date: torsdag 7 december 2006
allt.cl Page 1 of 17 Slumpspelaren Väljer slumpvis en flytt ur möjliga flyttar. (defun skapa-slump-spelare (namn bricktyp) "lisp-sträng x bricka -> spelare" (skapa-spelare #'slump-gör-flytt namn bricktyp))
Sista delen av kursen
Sista delen av kursen handlar om hur program, delprogram och datatyper deklareras och vad det man åstadkommit egentligen betyder. Innehåll Syntaktisk (hur ser det ut) och semantisk (vad betyder det) beskrivning
Programspråkslingvistik. Sista delen av kursen. Ett programspråk
Sista delen av kursen Programspråkslingvistik handlar om hur program, delprogram och datatyper deklareras och vad det man åstadkommit egentligen betyder. Innehåll Syntaktisk (hur ser det ut) och semantisk
Rekursiva algoritmer sortering sökning mönstermatchning
Anders Haraldsson 1 Anders Haraldsson 2 Dagens föreläsning Programmering i Lisp Fö 6-7 Rekursiva strukturer rekursiva definitioner rekursiva funktioner rekursiva bevis: induktion - rekursion strukturell
Deklarationer/definitioner/specifikationer
Deklarationer/definitioner/specifikationer Konstantdefinitioner innebär att ett namn binds och sätts att referera till ett värde som beräknas vid kompileringen/interpreteringen och som under programmets
Inledande programmering med C# (1DV402) 27+15=42 1 (22)
27+15=42 1 (22) Variabler Upphovsrätt för detta verk Detta verk är framtaget i anslutning till kursen Inledande programmering med C# vid Linnéuniversitetet. Du får använda detta verk så här: Allt innehåll
Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.
Idag Javas datatyper, arrayer, referenssemantik Klasser Arv, polymorfi, typregler, typkonvertering Strängar Tänker inte säga nåt om det som är likadant som i C. Objectorienterad programmering Sida 1 Ett
Dataabstraktion. TDDD73 Funktionell och imperativ programmering i Python Föreläsning 12. Peter Dalenius Institutionen för datavetenskap
Dataabstraktion TDDD73 Funktionell och imperativ programmering i Python Föreläsning 12 Peter Dalenius Institutionen för datavetenskap 2014-11-19 Översikt Vad är abstraktion? Vad är en abstrakt datatyp?
TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15
TENTAMEN I PROGRAMSPRÅK -- DVG C01 140605 kl. 08:15-13:15 Ansvarig Lärare: Donald F. Ross Hjälpmedel: Bilaga A: BNF-definition Betygsgräns: Kurs: Max 60p, Med beröm godkänd 50p, Icke utan beröm godkänd
Sista delen av kursen
Sista delen av kursen handlar om hur program, delprogram och datatyper deklareras och vad det man åstadkommit egentligen betyder. Innehåll Syntaktisk (hur ser det ut) och semantisk (vad betyder det) beskrivning
TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 17-19
TDDC74 Programmering: Abstraktion och modellering Dugga 2, 2017-04-06, kl 17-19 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis i
Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018
Static vs Dynamic binding Polymorfism Objekt-orienterad programmering och design (DIT95) Niklas Broberg, 2018 Diagnostiskt prov Shape + overlaps(shape): int return 1; Shape shape = new Shape(); Polygon
Datalogi, grundkurs 1. Lösningsförslag till tentamen
Datalogi, grundkurs 1 Lösningsförslag till tentamen 10 december 2008 1. a. Man testar med typiska värden, gränsvärden och värden utanför specificerad indatavärdemängd. Helst med alla permutationer av
Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6
Laboration 2 Objektorienterad programmering i Java I Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6 Syfte: Att kunna använda sig av olika villkors- och kontrollflödeskonstruktioner
BEGREPP HITTILLS FÖRELÄSNING 2 SAMMANSATTA UTTRYCK - SCHEME DATORSPRÅK
FÖRELÄSNING 2 Viss repetition av Fö1 Rekursivt fallanalys Rekursiva beskrivningar BEGREPP HITTILLS Konstant, Namn, Procedur/Funktion, LAMBDA, Parameter, Argument, Kropp, Villkor/Rekursion, Funktionsanrop,
Klassdeklaration. Metoddeklaration. Parameteröverföring
Syntax: Class Declaration Modifier Class Body Basic Class Member Klassdeklaration class Class Member Field Declaration Constructor Declaration Method Declaration Identifier Class Associations Motsvarar
TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18
TDDC74 Programmering: Abstraktion och modellering Datortenta - 2018-06-07, kl 14-18 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis
Objektorienterad Programmering (TDDC77)
Objektorienterad Programmering (TDDC77) Föreläsning II: utmatning, variabler, typer Ahmed Rezine IDA, Linköpings Universitet Hösttermin 2016 Kompilera och köra programmet under terminal 2: I Skapa Hej.java
OMTENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13: 15
OMTENTAMEN I PROGRAMSPRÅK -- DVG C01 130823 kl. 08:15-13: 15 Ansvarig Lärare: Donald F. Ross Hjälpmedel: Bilaga A: BNF-definition Betygsgräns: Kurs: Max 60p, Med beröm godkänd 50p, Icke utan beröm godkänd
TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 14-16
TDDC74 Programmering: Abstraktion och modellering Dugga 2, 207-04-06, kl 4-6 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis i svårighetsordning.
Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet
Procedurer och villkor Rekursiva procedurer (define lessorequal (lambda (x y) (or (< x y) (= x y)))) (define between (lambda (x y z) (and (lessorequal x y) (lessorequal y z)))) > (between 3 4 5) #t > (between
Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p
Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p Skriven av Michael Andersson Introduktion Programmering I högnivåspråk fokuserar på själv problemet (algoritmen) istället
I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program
Kompilera och köra programmet Objektorienterad Programmering (TDDC77) Föreläsning II: utmatning, variabler, typer Ahmed Rezine IDA, Linköpings Universitet Hösttermin 2016 under terminal 2: I Skapa Hej.java
Uppsala Universitet Matematiska Institutionen Thomas Erlandsson
Uppsala Universitet Matematiska Institutionen Thomas Erlandsson LÄSANVISNINGAR VECKA 36 VERSION 1. ARITMETIK FÖR RATIONELLA OCH REELLA TAL, OLIKHETER, ABSOLUTBELOPP ADAMS P.1 Real Numbers and the Real
Procedurer och villkor
Procedurer och villkor (define lessorequal (lambda (x y) (or (< x y) (= x y)))) (define between (lambda (x y z) (and (lessorequal x y) (lessorequal y z)))) > (between 3 4 5) #t > (between 3 2 5) #f DA2001
TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 08-12
TDDC74 Programmering: Abstraktion och modellering Datortenta - 2019-05-27, kl 08-12 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis
Inlämningsuppgift MiniPlotter
LUNDS TEKNISKA HÖGSKOLA Institutionen för datavetenskap EDAA01 Programmeringsteknik fördjupningskurs Inlämningsuppgift MiniPlotter I den här uppgiften ska ett program som ritar grafer av matematiska funktioner
TDDC74 Programmering: Abstraktion och modellering Datordugga 2 - exempel
TDDC74 Programmering: Abstraktion och modellering Datordugga 2 - exempel Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis i svårighetsordning.
Variabler, värden och typer
Variabler, värden och typer Viktigt att förstå på djupet: För programmering i många språk, t.ex. Java För kommande objektorientering! jonas.kvarnstrom@liu.se 2017 Fråga kommentera avbryt! Intro till variabler
Repetition av OOP- och Javabegrepp
ArrayList Repetition av OOP- och Javabegrepp En lista i vilken man kan lagra objekt Implementerar List-interfacet Skiljer sig från ett vanligt endimensionellt fält: Dynamisk expanderar när den blir
Parameteröverföring. Exempel. Exempel. Metodkropp
Exempel atriangle.changesize (100, 50); // OK atriangle.changesize (100); // fel antal atriangle.changesize ( 1, 50); // fel datatyp char c = atriangle.getarea (); // fel datatyp Parameteröverföring I
Svar till vissa uppgifter från första veckan.
Svar till vissa uppgifter från första veckan. Svar till kortuppgifter F:. Ja! Förhoppningsvis så ser man direkt att g fx) är ett polynom. Vidare så gäller det att g fα) = gfα)) = gβ) = 0. Använd faktorsatsen!
DAT043 - föreläsning 8
DAT043 - föreläsning 8 Paket, generics, Java collections framework 2017-02-07 Paket och tillgänglighet Ovanför klasser finns en hierarkisk namespace med paket. Filer som inte deklareras i något paket finns
Föreläsning 5: Introduktion av pekare
Föreläsning 5: Introduktion av pekare Det bör påpekas att det som tas upp i introduktionen inte är reella exempel på kod. Man anväder inte pekare till att peka på enstaka heltal som i exemplen nedan, men
Pascal... Pascal. Pascal... Pascal...
... Programspråk uppkallat efter Blaise. Skapat av Nicolaus Wirt. Avsett för undervisning för att lära ut typbegreppet och styrstrukturer. Har fått stor spridning p.g.a. enkelhet och att kompilatorn varken
Att förstå hur man konstruerar modulära program Att kunna skapa nya funktioner Att förstå hur data skickas mellan funktioner
Lektion 4, del 1, kapitel 10 Funktioner i JavaScript Inlärningsmål Att förstå hur man konstruerar modulära program Att kunna skapa nya funktioner Att förstå hur data skickas mellan funktioner Introduktion
Repetition av OOP- och Javabegrepp
ArrayList Repetition av OOP- och Javabegrepp En lista i vilken man kan lagra objekt Implementerar List-interfacet Skiljer sig från ett vanligt endimensionellt fält: Dynamisk expanderar när den blir
TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18
TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18 Läs alla frågorna först, och bestäm dig för i vilken ordning du vill lösa uppgifterna. Skriv tydligt och läsligt.
Signalflödesmodellen. Två (gamla) exempel: Kvadratera alla jämna löv.
Strömmar (streams) De sista dagarna objekt med tillstånd modellerades som beräkningsobjekt med tillstånd. Isådana modeller är tiden modelerad (implicit) som en sekvens av tillstånd. För att kunna modellera
Introduktion till formella metoder Programmeringsmetodik 1. Inledning
Introduktion till formella metoder Programmeringsmetodik 1. Inledning Fokus på imperativa program (ex. C, Java) program betyder härefter ett imperativt program Program bestäms i en abstrakt mening av hur
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal?? C är ett språk på relativt låg nivå vilket gör det möjligt att konstruera effektiva kompilatorer, samt att komma nära
Pascal. reserverade ord fördefinierade funktioner och procedurer egendefinierade funktioner, procedurer och objekt
Programspråk uppkallat efter Blaise. Skapat av Nicolaus Wirt. Avsett för undervisning för att lära ut typbegreppet och styrstrukturer. Har fått stor spridning p.g.a. enkelhet och att kompilatorn varken
Digitalitet. Kontinuerlig. Direkt proportionerlig mot källan. Ex. sprittermometer. Elektrisk signal som representerar ljud.
Analog Digitalitet Kontinuerlig Direkt proportionerlig mot källan Ex. sprittermometer Elektrisk signal som representerar ljud Diskret Digital Representation som siffror/symboler Ex. CD-skiva Varje siffra
Symbolisk data. quote. (define a 1) (define b 2) (jacek johan david) (list a b)
Symbolisk data (1 2 3 4) (a b c d) (jacek johan david) ((jacek "jacek@cs.lth.se") (johan "johang@cs.lth.se") (david "dat99dpe@ludat.lth.se")) ((anna 13) (per 11) (klas 9) (eva 4)) (+ (* 23 4) (/ y x))
TDDC74 Programmering: Abstraktion och modellering Datortenta
TDDC74 Programmering: Abstraktion och modellering Datortenta - 2017-08-26 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis i svårighetsordning.
Tillämpad Programmering (ID1218) :00-13:00
ID1218 Johan Montelius Tillämpad Programmering (ID1218) 2014-03-13 09:00-13:00 Förnamn: Efternamn: Regler Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten.