Plan: Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) Funksjonelle språk (Ghezzi&Jazayeri kap.7 frem til 7.4) Innføring i ML (Ghezzi&Jazayeri kap. 7.4.3 + ML-komp.) typer enkle funksjoner (Fortsetter med ML i to uker til) Ark 1 av 21 Forelesning 18.10.1999
Typer En (data-)type består av: en verdimengde tilhørende operasjoner for å lage, se på og endre slike verdier Eksempel: Type: boolean Verdimengde: {true, false} Operatorer: NOT, AND, OR... Programmeringsspråk har vanligvis en del predefinerte typer, samt mekanismer for å lage mer komplekse datatyper fra disse. Forelesning 18.10.1999 Ark 2 av 21
Spesielle TYPE-mekanismer predefinerte typer, ofte integer, real, character, string oppramstyper, eks. {mandag, tirsdag, onsdag,...} intervall-typer, f.eks. tallene fra 1 til 100 lister, sekvenser predefinert i LISP, ML tabeller, arrayer gjerne predefinert i imperative språk Forelesning 18.10.1999 Ark 3 av 21
Generelle TYPE-mekanismer produkt-typer med flere komponenter Pascal/Ada: record C/C++: structure Java/Simula: klasser union-typer gir flere alternativer Eksempel (i ML-syntaks): datatype boolean = true false; Pascal/Ada: variant record C/C++: union Java/Simula: super-/subklasser rekursive typer inneholder noe av sin egen type Eksempel: liste av heltall class Node { int verdi; Node neste; } Node liste; parametriserte typer muliggjør datastrukturer over vilkårlige element -typer Eksempel: en generell liste Forelesning 18.10.1999 Ark 4 av 21
Abstrakte datatyper Innkapsling: Kan definere verdimengden og de tilhørende funksjonene i én modul. Beskyttelse: Skjule visse funksjoner og variable i en modul slik at de ikke kan brukes utenfor modulen. Eksempel: Rasjonale tall som data-type: Type RAT = modulebegin # Verdimengde/datastruktur: t, n : Int # Tilhørende funksjoner: FUNC mult(a,b:rat):rat == RETURN((a.t*b.t),(a.n*b.n))... endmodule RAT Forelesning 18.10.1999 Ark 5 av 21
Noen fordeler ved typede språk Statisk sjekking av variabelbruk INT BOOL X + Y Statisk binding av overlastede funksjoner og prosedyrer. Skjuling av representasjon (abstrakte data typer) Programmeringsstil (lesbarhet) Modifiserbarhet Forelesning 18.10.1999 Ark 6 av 21
Funksjonelle (applikative) språk Motivasjon: Matematisk tilnærming til problemene uten tanke på maskinens oppbygning. Abstraksjonsnivå tilpasset programmereren, ikke hardware. Eksempel: Euclids algoritme for å finne største felles divisor Algoritmen: gcd(0, n) = n gcd(m, n) = gcd(n mod m, m) for m > 0 IJava: int gcd(int m, int n) { int prev; while(m!=0){prev=m;m=n%m;n=prev;} return n; } IML: fun gcd(m, n) = ifm=0thenn else gcd(n mod m, m); Forelesning 18.10.1999 Ark 7 av 21
Rent funksjonelle språk Rent funksjonelle språk har ikke tilordning! Variable kan ikke oppdateres. Kan definere: konstanter, funksjoner, typer (hvis typet språk) og kan skrive uttrykk! ML har typer, men ikke ren Lisp og Prolog. Forelesning 18.10.1999 Ark 8 av 21
imperativt applikativt valg if-setning if-uttrykk gjentakelse løkke rekursjon sekv. sammensetning ; funksjons-sammensetning Eksempel: den imperative koden x := f (x, y); x := g(x, y); blir funksjonelt seende ut som: g( f (x, y), y) Forelesning 18.10.1999 Ark 9 av 21
Rent funksjonelle språk Typiske fordeler enkel, elegant kode (se foil 7) ingen side-effekter aliasing ikke problem kan lett interpreteres Typiske ulemper effektivitet mister kontroll med tid og rom input/output (ML gjør dette imperativt) Forelesning 18.10.1999 Ark 10 av 21
Introduksjon til standard ML Pensum: Bjørn Kristoffersen: Funksjonell Programmering i Standard ML, Kompendium 61 Standard ML er et interpreterende språk. Ml-interpreteren startes fra Unix ved kommandoen sml: > sml Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled] - - angir at systemet er klart til å ta imot kommandoer. Husk: Alle uttrykk og deklarasjoner skal avsluttes med ; Kommentarer skrives ved (*... *) CTRL-D avslutter systemet. Forelesning 18.10.1999 Ark 11 av 21
Enkle beregninger -2+2; val it = 4 : int - val verdi = 2+3*4; val verdi = 14 : int Svaret legges altså i it hvis ikke annet spesifiseres. Deklarasjon av funksjoner fun <navn> (<parameterliste>) = <uttrykk>; - fun fak(n:int) = if n < 2 then 1 else n * fak(n-1); valfak=fn:int->int Konstanter - val pi = 3.14159; val pi = 3.14159 : real - fun areal (r:real) = pi * r * r; val areal = fn : real -> real - areal(3.0); val it = 28.27431 : real Hva hvis vi redeklarerer pi? - val pi = 1.0; valpi=1.0:real - areal(3.0); val it = 28.27431 : real (* NB! *) Forelesning 18.10.1999 Ark 12 av 21
Enkel ML Predefinert: int med:= <*+-div mod (unær minus) realmed:=<*+-/ bool med: = true, false, andalso, orelse, not string med: = < Hei ˆ (konkatenering) lister med: = :: @ (konkatenering) [] [1,2,3] Eksempler: "ole" ˆ "mann" = "olemann" (konkatenering av strenger) [1,2]@[3] = [1,2,3] (konkatenering av lister) 1:: [2,3] = [1,2,3] (hekt på først i liste) [] = nil (tom liste) [3] = 3::nil (liste med ett element) 1::2::3::nil = [1,2,3] [true,false] (liste av boolske) ["ole","jens"] (liste av strenger) [[1,2,3],[2,3]] (liste av lister) Forelesning 18.10.1999 Ark 13 av 21
Ingen overlasting Merk: Ingen overlasting, dvs. ny deklarasjon med samme navn medfører at siste deklarasjon gjelder. NB! Denne nye deklarasjonen gjelder kun for etterfølgende bruk (på samme måte som pi i eksempelet foil 12). Eksempel: - fun beregn(x:int) = 2 * x; val beregn = fn : int -> int - fun dobbel (x:int) = beregn(x); val dobbel = fn : int -> int - beregn(5); val it = 10 : int - dobbel(5); val it = 10 : int - fun beregn(x:int) = 3 * x; (* redeklarasjon *) val beregn = fn : int -> int - beregn(5); val it = 15 : int - dobbel(5); val it = 10 : int (* NB! *) Forelesning 18.10.1999 Ark 14 av 21
Smart type-analyse Følgende deklarasjoner forstås likt av ML: fun dobbel(x:int):int = x+x; fun dobbel(x:int) = x+x; fun dobbel(x):int = x+x; I alle tilfellene kvitterer ML med val dobbel = fn : int -> int ML kan dedusere typen av funksjonsverdien og/eller (utypede) parametre, så sant en éntydig løsning finnes. -funid(x)=x; valid=fn: a-> a Her står a for en vilkårlig type. Dvs. funksjonen er polymorf, den kan brukes for alle typer. Forelesning 18.10.1999 Ark 15 av 21
Type-deklarasjoner Deklarasjon av en type med navn T uten parametre: type/datatype T = <type-uttrykk>; Deklarasjon av en type med navn T og med parametre: type/datatype <type-parametre> T = <type-uttrykk>; Eksempel: type tall = int; type talliste = tall list; Merk: Navnet på en type-parameter må starte med en apostrof. Forelesning 18.10.1999 Ark 16 av 21
Produkt-typer med navn-gitte komponenter - type Person = {navn:string, alder:int}; type Person = {alder:int, navn:string} - val Ole = {navn= Ole, alder= 25}; val Ole = {alder=25,navn="ole"} : {alder:int, navn:string} - #navn Ole; val it = "Ole" : string - #alder Ole; val it = 25 : int med navn-løse komponenter - type Person = string * int; type Person = string * int - val Ole = ( Ole, 25); val Ole = ( Ole, 25); -#1Ole; val it = "Ole" : string -#2Ole; val it = 25 : int; Tomt produkt: unit minste produkt: type unit = {} Denne typen er predefinert, og har bare én mulig verdi, nemlig () Kan også skrive denne verdien som {} Forelesning 18.10.1999 Ark 17 av 21
Union-typer i ML: datatyper - datatype PData = navn of string alder of int; datatype PData = alder of int navn of string - val n = navn( Ole ); val n = navn "Ole" : PData - val a = alder(25); val a = alder 25 : PData Både n og a er lovlige, men ulike, verdier av typen PData. Ved case-uttrykk kan man analysere PData-verdier: case x of navn(s) =>...s... alder(i) =>...i... der x er et uttrykk av type PData. Forelesning 18.10.1999 Ark 18 av 21
Konstanter som alternativer Et alternativ kan være en konstant. Eksempel: datatype Dag = mandag tirsdag onsdag torsdag fredag lordag sondag; fun ukedag(d:dag):bool= case d of lordag => false sondag => false _ => true; Eksempel: datatype Data = tall of int no; tall(5); no; fun dobbel(x:data):data = case x of tall(i) => tall(i+i) no => no; Forelesning 18.10.1999 Ark 19 av 21
Flere eksempler type HogV = {hoyde: int, vekt: int}; datatype HelV = hoyde of int vekt of int; fun storhogv(x:hogv) = #hoyde x > 180 orelse #vekt x > 80; fun storhelv(x:helv) = case x of hoyde(i) => i > 180 vekt(i) => i > 80; storhelv(vekt(90)); (gir true) storhelv(hoyde(90)); (gir false) storhogv({vekt=90,hoyde=90}); (gir true) Forelesning 18.10.1999 Ark 20 av 21
Rekursive Typer datatype T ==...... T... Eksempel: liste av tall datatype TallListe = tom ikketom of { forste:int * rest:tallliste}; ikketom({forste=1,rest=ikketom({forste=2,rest=ikketom ({forste=3,rest=tom}) }) }); det samme, uten komponent-navn datatype TallListe = tom ikketom of int * TallListe; ikketom(1,ikketom(2,ikketom(3,tom))) Men lister er også predefinert i ML: Kan da skrive listen av 1, 2, 3 som [1, 2, 3] Forelesning 18.10.1999 Ark 21 av 21