INF2810: Funksjonell programmering INF2810: Funksjonell

INF2810: Funksjonell programmering
INF2810: Funksjonell Programmering
Introduksjon
Erik Velldal
Universitetet i Oslo
22. januar 2015
Tema for i dag
I
Introduksjon
I
Praktiske detaljer
I
I
I
Grupper
Obliger
Lærebok
I
Hva skal vi lære?
I
Scheme på noen minutter
2
Screencasting
I
Tar opp screencast for hver forelesning (lyd + foiler).
I
Vi lenker til egen YouTube-kanal fra forelesningsplanen etterhvert.
3
Hei
I
Foreleser: Erik Velldal (erikve), fra språkteknologigruppa (LTG).
Gruppelærere
I
Marie Katrine Ekeberg (mariuek)
I
I
Lars Tveito (larstvei)
I
I
I
Gruppe 2 (on. 14:15–16:00)
Hovedansvarlig for opplegg til gruppetimene, se under.
Håkon Salomonsen Møller (haakomol)
I
I
I
Gruppe 1 (ma. 10:15–12:00)
Gruppe 103 (fr. 10:15–12:00)
Hovedansvarlig for YouTube-kanalen og posting av screencasts.
Aksel L. Wester (aksellw)
I
Gruppe 4 (ma. 12:15-14:00)
4
Opplegg for gruppetimene
Genererelt
- Første halvdel av timen: felles tavleundervisning. Andre halvdel:
selvstendig arbeid der man kan få hjelp med kodingen.
- I uker rett før en innelevering brukes mer av tiden på selvstendig arbeid.
- Lars kommer til å poste (frivillige) ukesoppgaver her:
http://folk.uio.no/larstvei/inf2810/v15/
- Timeplan vil oppdateres på semestersiden.
Første time
I
Gjennomgang av programmeringsomgivelsen.
I
I
I
Gruppe 1, 103, 4: Scheme i DrRacket.
Gruppe 2: Scheme i Emacs.
Arbeid med oblig 1a.
5
Obliger
I
3 obliger, hver i to deler (a + b), dvs. 6 innleveringer tilsammen.
I
Man kan oppnå opptil 10 poeng per innlevering
I
Kreves minst 12 poeng (av 20 mulige) per oblig (a + b) for å bestå.
I
Alle 3 obligene må vurderes som bestått for å kunne ta eksamen.
I
I
I
I
NB: Innleveringsfrister utsettes bare ved egenmelding eller
legeerklæring; ingen omlevering.
Oblig 1 må løses individuelt, mens 2 og 3 kan løses i grupper av to eller
tre studenter sammen.
Konkurranse: den/de som får flest poeng tilsammen på obligene
gjennom semesteret får en premie (overraskelse)!
1a legges ut i morgen med frist om to uker.
6
Spørsmål og hjelp
I
I
Gruppetimene: Gruppelærerene er der for å hjelpe og veilede.
Diskusjonsforum (Piazza):
https://piazza.com/uio.no/spring2015/inf2810/home
I
I
Invitasjoner til registrering vil bli sendt ut snart!
?
Felles adresse til fag- og-gruppelærere:
inf2810-hjelp [at] ifi.uio.no
7
Beskjeder
I
Husk å sjekke UiO-eposten din eller beskjedlisten på semestersiden.
I
Abonnér gjerne på RSS-feed’en på semestersiden;
!
www.uio.no/studier/emner/matnat/ifi/INF2810/v15/beskjeder/?vrtx=feed
8
Læreboka
I
Structure and Interpretation of Computer
Programs, 2. utg., Abelson & Sussman.
I
Aka SICP eller the Wizard book
I
Gratis tilgjengelig på nett
I
HTML-versjon: mitpress.mit.edu/sicp/
I
I
Pdf-versjon (ulike versjoner tilpasset
lesebrett, tablets, mobil, etc):
sicpebook.wordpress.com/ebook/
Selges også på Akademika.
9
Læreboka (forts.)
I
SICP er en klassiker innen informatikk.
I
1. utgave 1984, 2. utg. 1996
I
Brukes fortsatt på en rekke universiteter.
I
Gammel men ikke støvete.
I
Hvordan kan den fortsatt være relevant?
I
Som med klassikere flest er den tidløs.
I
I
(Sussman)
Basert på Scheme, men ikke fokus på
lavnivå-detaljer ved språk og syntaks.
Generelle teknikker for å kontrollere
kompleksiteten i programmer.
(Abelson)
10
Noe av det vi skal se på i kurset
I
Rekursjon
I
I
Prosedyrer som førsteklasses objekter
I
I
I
innkapsulering av data i prosedyrer for å skjule tilstandsvariabler
Strømmer og utsatt evaluering
I
I
prosedyrer som tar andre prosedyrer som input-argument og/eller
prosedyrer som returnerer andre prosedyrer som output-verdi
Objektorientering via prosedyrer
I
I
prosedyrer er en datatype på linje med tall, symboler, strenger, lister, etc.
Høyere-ordens prosedyrer
I
I
prosedyrer som kaller på seg selv
definering av uendelige sekvenser og realisering de enkelte elementene i
disse ved utsatt evaluering etter behov
Programmer som opererer på programmer
I
I
program = data
enkelt å gjøre i Lisp siden programkoden er basert på en språkets
innebygde datastrukturer; lister
11
Programmeringsparadigmer
Funksjonell programmering
I Uten tilstandsendringer
I En prosedyres returverdi er alltid den samme hvis argumentene er de samme.
I Beregninger utføres som funksjonelle transformasjoner av data.
Imperativ programmering
I Med tilstandsendringer
I Prosedyrers returverdi kan variere fra kall til kall, selv om argumentene er de samme.
I Beregninger utføres som sekvensielle endringer av tilstandsvariabler.
12
Viktige egenskaper ved funksjonell programmering
I
Prosedyrer påvirker ikke ekstern tilstand.
I
I
Prosedyrer er uavhengige av ekstern tilstand.
I
I
I
I
I
I
I
Semantikken til et uttrykk er uavhengig av hvor og når det brukes.
Funksjonskall kan erstattes med returverdi uten at programmets
semantikk endres.
Enklere
I
I
Kallet på en prosedyre gir alltid samme resultat med samme argument.
Gjennomsiktig semantikk (referential transparency)
I
I
Prosedyrer kalles for deres returverdi; uten bieffekter (side-effects).
å lese og vedlikeholde
å teste og debugge; enkeltfunksjoner kan testes i isolasjon.
å parallelisere.
Ofte ansett for å gi økt sikkerhet (pga alt over).
Funksjoner danner byggeklosser. Kan være sammensatte / kan settes
sammen. Legger til rette for nedenfra-og-opp design og modularitet.
Prosedyrer er data.
13
Ikke fokus på ren funksjonell programmering
I
I
I
I
Hverken INF2810 eller SICP prediker rendyrket funksjonell
programmering.
Scheme er ikke et rent funksjonelt språk; inneholder også støtte for
“destruktive operasjoner” og muterbare data.
Poenget er ikke at det ene eller andre paradigmet alltid er bedre enn
det andre. . .
men at du blir en bedre programmerer ved å kjenne til flere ulike
teknikker og tenkemåter.
14
Lisp
I
Kraftig høynivå-språk med lange tradisjoner.
I
Som SICP er også Lisp i seg selv en klassiker.
I
“Oppdaget” av John McCarthy allerede i 1958.
I
I
I
Først bare ment som en matematisk formalisme
(for rekursjonsteori og symbolsk algebra).
En av studentene hans, Steve Russell, implementerte så en interpreter for
formalismen og dermed var programmeringsspråket Lisp født.
Snarere enn at Lisp har blir utdatert har tendensen vært at andre språk
stadig beveger seg nærmere Lisp.
15
Lisp og AI
I
Har hatt en tett kobling til forskningen på kunstig intelligens.
I
Ofte beskrevet som “AI-språket”.
I
Bare delvis sant, men det er flere grunner til koblingen;
I
AI: introdusert av McCarthy på midten av 50-tallet.
I
Lisp: introdusert av McCarthy på midten av 50-tallet.
16
Koding i INF2810
I
Programmeringspråk: Scheme
I
Minimalistisk dialekt av Lisp.
I
I
I
I
Andre dialekter: Common Lisp, Clojure,
Emacs Lisp, Racket (dialekt av Scheme), etc.
Lisp har en enkel semantikk, og en ekstremt enkel syntaks.
Vi skal lære Scheme på noen minutter; og så bruke resten av kurset på
å mestre noen av de avanserte teknikkene det støtter.
Programmeringsomgivelse: DrRacket
17
DrRacket
I
I
I
I
Se racket-lang.org
Innstalert på alle
IFI-maskiner.
Viktig: DrRacket
støtter flere
standarder; sett
språk til R5 RS.
Se kurssidene for en
innføring i bruk.
I
I det nederste tekstområdet kan du teste og utvikle kode interaktivt:
I
Skriv et uttrykk og trykk enter; uttrykket evalueres; resultatet printes:
I
Såkalt read-eval-print loop eller REPL.
18
Nå skal vi bruke noen minutter på å lære Scheme
I
Vi tester noen uttrykk mot REPL’en.
I
(= den interaktive Scheme-omgivelsen)
I
I
I
Vi bruker ? for representere
REPL-promptet og → for hva et
uttrykk evalueres til.
Datatyper som tall, strenger og boolske
konstanter er eksempler på primitive /
atomære uttrykk.
Slike uttrykk evaluerer til seg selv.
Eksempler
? "dette er en streng"
→ "dette er en streng"
? 42
→ 42
? 3.14159
→ 3.14159
? 1/3
→ 1/3
? #t
→ #t
? #f
→ #f
19
Prosedyrer og navngitte variabler
I
“Parentesbasert prefiksnotasjon”.
I
Scheme-kode består av lister.
I
I
I
I
Første element (prefikset) er
operatoren (prosedyre).
Resten av lista består av operandene
(argumentene / parameterene).
Lett å anvende en prosedyre på
vilkårlig mange argumenter med
prefiksnotasjon.
define: er en såkalt special form,
ikke en vanlig prosedyre. Brukes for
å introdusere en leksikalsk variabel;
symbol som bindes til en verdi.
Eksempler
? (+ 1 2)
→3
? (+ 1 2 10 7 5)
→ 25
? (define foo 42)
? foo
→ 42
? (+ foo 58)
→ 100
? (+ foo bar)
; error; bar undefined
20
Sammensatte uttrykk
? (* 10 (+ foo 58))
→ 1000
? (/ (+ 10 20) 2)
→ 15
? (* (+ foo 58) (- (/ 8 2) 2))
→ 200
? (* (+ foo 58)
(- (/ 8 2)
2))
→ 200
I
I
I
Lister kan omslutte hverande
for å bygge opp sammensatte
uttrykk.
Parentesene gir strukturen;
ingen tvetydighet mht.
presedens.
Ved lange uttrykk bruker vi
indentering for å gjøre koden
mer lesbar. (Bruk TAB i
DrRacket / Emacs.)
21
Når Scheme leser sammensatte utrykk
Schemes evalueringsregel:
Eksempel
1) Evaluér enkelt-uttrykkene i sammensetningen
? (* (+ foo 58)
(- (/ 8 2)
2))
a) Atomære uttrykk: evalueres til seg selv.
b) Leksikalske variabler og prosedyrenavn:
evalueres til verdiene de refererer til.
c) Sammensatte utrykk: anvend 1) igjen.
2) Anvend operatoren (det første uttrykket i
lista) på verdiene til de andre uttrykkene.
I
I
I
⇒ (* (+ 42 58)
(- (/ 8 2)
2))
Vi har beskrevet evalueringen rekursivt;
regelen kaller på seg selv (1c).
⇒ (* 100
(- (/ 8 2)
2))
Scheme og Lisp har en ekstremt enkel syntax;
alt oppsummeres med regelen over.
⇒ (* 100 (- 4 2))
Unntaket er special forms (som define),
som har sine egne evalueringsregler.
⇒ (* 100 2)
→ 200
22
Oppsummering om datatypene vi har sett til nå
I
Tall, “booleans”, og strenger er selv-evaluerende.
? 3.1415 → 3.1415
? "foo" → "foo"
? #t → #t
I
Symboler evalueres til verdien de navngir (om noen):
? foo → 42
? + → #<procedure:+>
I
Lister er prosedyrekall. Det første elementet er en operator som kalles
med verdiene til de resterende elementene som argumenter.
? (* 10 (+ 2 3)) → 50
I
Men lister kan også være data:
? (list 1 2 3) → (1 2 3)
? (list foo 2 "bar") → (42 2 "bar")
23
Program = data
Kommentar / frampek
I
I
I de første to forelesningen skal vi jobbe med enkle matematiske
eksempler, men senere i kurset kommer vi til å jobbe masse med lister
og symbolske data.
Lister har en spesiell rolle i Lisp og Scheme: kan brukes til å
representere både data og program.
I
LISP = LISt Processing
I
Lister = data = program.
24
Å opprette egne prosedyrer med define
I
I
Vi har sett at define kan brukes for å binde leksikalske variabler til en
verdi. Men verdien kan også være en prosedyre.
Prosedyrer lages ved såkalte lambda-uttrykk.
Eksempel
? (define snitt
(lambda (x y)
(/ (+ x y) 2)))
Generell form
(define hnavni
(lambda (hargumenter i)
hkropp i))
I
? (snitt 10 20) → 15
Det finnes også en kortform
som sløyfer lambda:
? (snitt (snitt 10 20)
(snitt 10 30))
→ 17.5
(define (hnavni hargumenter i)
hkropp i)
? (define (snitt x y)
(/ (+ x y) 2))
25
Predikater og kondisjonale uttrykk
Eksempler
? (define foo 42)
? (even?
? (zero?
I
foo) → #t
foo) → #f
? (not (>= foo 42)) → #f
? (and (< 3 4)
foo)
→ 42
I
I
I
→ 42
? (or foo
(negative?
I
foo))
Predikater er prosedyrer eller
uttrykk som returnerer sant /
usant (#t / #f).
F.eks even?, not, >, =, etc.
Husk at alt unntatt #f teller
som sant.
De logiske konnektivene and
og or er såkalte special forms.
Sammen med kondisjonale
uttrykk som f.eks if og cond
kan vi bruke predikater og
konnektiver til å kontrollere
flyten i et program.
26
Predikater og kondisjonale uttrykk (forst.)
Eksempler
Generell form
? (if (number? 42)
"number"
"something else")
(if htesti
hutfall-hvis-sant i
hutfall-hvis-usant i)
→ "number"
? (cond ((< 42 3) "less")
((> 42 3) "greater")
(else "equal"))
(cond (htest1 i hutfall1 i)
(htest2 i hutfall2 i)
(htestn i hutfalln i)
(else hutfall i))
→ "greater"
27
xkcd on Lisp
http://xkcd.com/297/
28