Clojure workshop

675 views

Published on

Slides used to present Clojure for students in Trondheim. Tasks can be found here:

https://github.com/andreaja/clojure-workshop

Published in: Technology, Economy & Finance
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
675
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
15
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Hvem kan FP?\nHvem kan Lisp?\nHvem kan Java?\n
  • accountNo -> final. Det er helt uproblematisk at dette er et public felt, i hvert fall fra et concurrency perspektiv.\n\n+= og -= er syntaktisk sukker for 3 operasjoner, read-write-store.\n
  • += og -= er syntaktisk sukker for 3 operasjoner, read-write-store.\n
  • += og -= er syntaktisk sukker for 3 operasjoner, read-write-store.\n
  • += og -= er syntaktisk sukker for 3 operasjoner, read-write-store.\n
  • \n
  • Forhindre samtidig oppdatering ved å låse på objektene.\n\nDette ser vel og bra ut, men med litt uheldig timing vil \n
  • Innføre deterministisk låserekkefølge\n
  • Har vi klart å unngå alle mulige feil fra denne koden?\n* Slik kode er svært vanskelig å resonnere rundt, og selv eksperter har problemer. Jeg kan helt ærlig si at jeg ikke vet om denne koden er korrekt.\n* Et felt som kan endre seg -> Gir seg selv at i en ekte applikasjon vil sitausjonen være mye værre.\n* Det som værre er, er at slik kode er nesten umulig å teste. Feilsituasjoner med tråder oppstår kun som følge av uheldig timing.\n* Hva er så problemet her, hvorfor er dette så vanskelig. Jo, vi programmerer med eksplisitte låser, noe som i praksis viser seg å være en svært dårlig abstraksjon.\n\nDet må finnes bedre alternativer\n
  • \n
  • \n
  • \n
  • Korrekthet og ytelse\nPresisere at det vi skal snakke om er Concurrency.\n
  • Startet mars i 2006.\nFørste versjon 4 May 2009\nFikk veldig mye oppmerksomhet.\n
  • Alle problemer har en inherent complexity. Dette er det som uansett må til for å løse problemet.\n
  • Først lisp i 1958 John McCarthy\nIkke objektorientert\nYtelse nesten som Java\n
  • \n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • Cambridge polish notation\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Med låsemodell, vil programmet gå tregere jo flere som oppfatter/perceives meg?\n
  • \n
  • \n
  • \n
  • Epokisk tidsmodell\n
  • \n
  • Gjenta egenskaper! Når brukes dette!\n
  • Gjenta egenskaper! Når brukes dette!\n
  • Gjenta egenskaper! Når brukes dette!\n
  • Gjenta egenskaper. Når brukes dette!\nActors vs agents:\nAc -> Sende tilstand til oppførsel\nAg -> Sende oppførsel til tilstand\nSynkron perception\n
  • Gjenta egenskaper. Når brukes dette!\nActors vs agents:\nAc -> Sende tilstand til oppførsel\nAg -> Sende oppførsel til tilstand\nSynkron perception\n
  • Gjenta egenskaper. Når brukes dette!\nActors vs agents:\nAc -> Sende tilstand til oppførsel\nAg -> Sende oppførsel til tilstand\nSynkron perception\n
  • Gjenta egenskaper, når brukes dette\n
  • Gjenta egenskaper, når brukes dette\n
  • Gjenta egenskaper, når brukes dette\n
  • \n
  • \n
  • STM var en av hovedårsakene til at Clojure ble såpass fort kjent.\nAnalogi\n
  • Snakke om .Net prosjektet\n
  • Atomic - rollback ved transactions ellers vil det committe\nConsistent - constraints i database, set-validator\nIsolated - Snapshot MVCC\nMen... kan gi rollback.\nEget eksempel 10 000 retries.\nEksempel tungt oppdaterer en ref som få konkurrerer om. Så gjør den en lett jobb som oppdaterer en ref som mange konkurrerer om.\n
  • Atomic - rollback ved transactions ellers vil det committe\nConsistent - constraints i database, set-validator\nIsolated - Snapshot MVCC\nMen... kan gi rollback.\nEget eksempel 10 000 retries.\nEksempel tungt oppdaterer en ref som få konkurrerer om. Så gjør den en lett jobb som oppdaterer en ref som mange konkurrerer om.\n
  • Atomic - rollback ved transactions ellers vil det committe\nConsistent - constraints i database, set-validator\nIsolated - Snapshot MVCC\nMen... kan gi rollback.\nEget eksempel 10 000 retries.\nEksempel tungt oppdaterer en ref som få konkurrerer om. Så gjør den en lett jobb som oppdaterer en ref som mange konkurrerer om.\n
  • \n
  • Når man tenker seg om -> fornuftig måte å modellere tilstand på. Bonusen er jo da at dette fungerer veldig bra i en concurrent setting.\n
  • Når man tenker seg om -> fornuftig måte å modellere tilstand på. Bonusen er jo da at dette fungerer veldig bra i en concurrent setting.\n
  • \n
  • \n
  • Repl, dere kan følge med på eksemplene. Read. Eval. Print. Loop.\n
  • +Enten clj, eller IDE, eller+ lein repl\n
  • Grunnenheten i språket. Angir et uttrykk. \n
  • Reader? \n
  • Parantesene betyr at dette er uttryk som returnerer noe. \n
  • Første symbolet blir kallt som en funksjon\n
  • Dette er parametere\n
  • Merket foran betyr at det skal leses som en liste og ikke eksekveres\n
  • \n
  • \n
  • Funksjon som parameter. \n
  • fn lager en funksjon,\narg er et argument, kunne brukt hva som helst som navn\narg + 5 = resultat\n
  • Mange paranteser. Første parantes betyr: nå skal vi kalle noe. Skal kalle det som kommer fra andre parantes. Det er en funksjon. \n
  • Symbolet “five” har en verdi, men kun innenfor parentesene til let\n
  • \n
  • Organisert med tester, hver test har en eller flere ting som skal fylles inn. Trenger bare endre på ting innenfor en “deftest”.\n
  • Første kjører alle testene (oppgavene), andre kjører bare de første oppgavene. Disse skal resultere i masse feilmeldinger.\n
  • \n
  • \n
  • Eksempel på test, tester likhet mellom 1 og 1, true og true. \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Clojure workshop

    1. 1. Clojure workshop Alf Kristian Støyle Andreas Jacobsen  
    2. 2. Agenda• Introduksjon - hvorfor er Clojure viktig• Basic syntax • Oppgaver • Gjennomgang av oppgaver• JSON over HTTP • Oppgaver • Gjennomgang• Oppsummering
    3. 3. Kontoeksempelet
    4. 4. public class Account { private long balance; public final int accountNo; public Account(long balance, int accountNo){ this.balance = balance; this.accountNo = accountNo; } public void debit(long debitAmount) { this.balance -= debitAmount; } public void credit(long creditAmount) { this.balance += creditAmount; } public long getBalance() { return this.balance; }}
    5. 5. public class Account { private long balance; public final int accountNo; public Account(long balance, int accountNo){ this.balance = balance; this.accountNo = accountNo; } public synchronized void debit(long debitAmount) { this.balance -= debitAmount; } public synchronized void credit(long creditAmount) { this.balance += creditAmount; } public long getBalance() { return this.balance; }}
    6. 6. public class Account { private long balance; public final int accountNo; public Account(long balance, int accountNo){ this.balance = balance; this.accountNo = accountNo; } public synchronized void debit(long debitAmount) { this.balance -= debitAmount; } public synchronized void credit(long creditAmount) { this.balance += creditAmount; } public synchronized long getBalance() { return this.balance; }}
    7. 7. public class Account { private volatile long balance; public final int accountNo; public Account(long balance, int accountNo){ this.balance = balance; this.accountNo = accountNo; } public synchronized void debit(long debitAmount) { this.balance -= debitAmount; } public synchronized void credit(long creditAmount) { this.balance += creditAmount; } public synchronized long getBalance() { return this.balance; }}
    8. 8. public void transfer(Account fromAccount, Account toAccount, long amount) throws Exception { if (fromAccount.getBalance() < amount) { throw new Exception("Not enough money!"); } fromAccount.debit(amount); toAccount.credit(amount);}
    9. 9. public void transfer(Account fromAccount, Account toAccount, long amount) throws Exception { synchronized (fromAccount) { synchronized (toAccount) { if (fromAccount.getBalance() < amount) { throw new Exception("Not enough money!"); } fromAccount.debit(amount); toAccount.credit(amount); } }}
    10. 10. public void transfer(Account fromAccount, Account toAccount, long amount) throws Exception { Object mutex1 = toAccount; Object mutex2 = fromAccount; if (fromAccount.accountNo < toAccount.accountNo) { mutex1 = fromAccount; mutex2 = toAccount; } synchronized (mutex1) { synchronized (mutex2) { if (fromAccount.getBalance() < amount) { throw new Exception("Not enough money!"); } fromAccount.debit(amount); toAccount.credit(amount); } }}
    11. 11. public void transfer(Account fromAccount, Account toAccount, long amount) throws Exception { Object mutex1 = toAccount; Object mutex2 = fromAccount; if (fromAccount.accountNo < toAccount.accountNo) { mutex1 = fromAccount; mutex2 = toAccount; ? } synchronized (mutex1) { synchronized (mutex2) { if (fromAccount.getBalance() < amount) { throw new Exception("Not enough money!"); } fromAccount.debit(amount); toAccount.credit(amount); } }} public class Account { private volatile long balance; public final int accountNo; public Account(long balance, int accountNo){ this.balance = balance; this.accountNo = accountNo; } public synchronized void debit(long debitAmount) { this.balance -= debitAmount; } public synchronized void credit(long creditAmount) { this.balance += creditAmount; } public synchronized long getBalance() { return this.balance; } }
    12. 12. (defn transfer [from-account to-account amount] (dosync (if (> amount @from-account) (throw (new Exception "Not enough money!"))) (alter from-account - amount) (alter to-account + amount)))
    13. 13. (defn transfer [from-account to-account amount] (dosync (if (> amount @from-account) (throw (new Exception "Not enough money!"))) (alter from-account - amount) (alter to-account + amount)))(def account-a (ref 1000))(def account-b (ref 800))
    14. 14. (defn transfer [from-account to-account amount] (dosync (if (> amount @from-account) (throw (new Exception "Not enough money!"))) (alter from-account - amount) (alter to-account + amount)))(def account-a (ref 1000))(def account-b (ref 800))(transfer account-a account-b 300)@account-a; => 700
    15. 15. http://www.dehne.carleton.ca/research/multi-core
    16. 16. Concurrency dreier som om å gjøre flere oppgaver omtrent samtidigParallelism dreier seg om å dele en oppgave i mange deloppgaver som kan gjøres concurrent
    17. 17. Clojure
    18. 18. Accidental complexity
    19. 19. Clojure• General purpose• Lisp (List Processing)• Funksjonelt• Kompilert• Dynamisk typet• Tett knyttet til JVM’en
    20. 20. 1; => 1"Hello World"; => "Hello World"
    21. 21. 1; => 1"Hello World"; => "Hello World"(class 1); => java.lang.Integer(class "Hello world"); => java.lang.String
    22. 22. (println "Hello " "world"); “Hello world”; => nil
    23. 23. Funksjonsnavn(println "Hello " "world"); “Hello world”; => nil
    24. 24. Funksjonsnavn Parametere(println "Hello " "world"); “Hello world”; => nil
    25. 25. Funksjonsnavn Parametere(println "Hello " "world") ,; “Hello world”; => nil
    26. 26. Prefiks notasjon Funksjonsnavn Parametere(println "Hello " "world") ,; “Hello world”; => nil
    27. 27. Methods.callStatic();methods.callInstance();callStatic();callInstance();this.callInstance();methods.callStatic();Methods.this.callInstance();Methods.this.callStatic();
    28. 28. (println "Hello world"); Hello world; => nil
    29. 29. (println "Hello world"); Hello world; => nil(sum 1 2 3); => 6
    30. 30. (println "Hello world"); Hello world; => nil(sum 1 2 3); => 6(+ 1 2); => 3
    31. 31. (println "Hello world"); Hello world; => nil(sum 1 2 3); => 6(+ 1 2); => 3(+ 1 2 3); => 6
    32. 32. (println "Hello world"); Hello world; => nil(sum 1 2 3); => 6(+ 1 2); => 3(+ 1 2 3); => 6(+); => 0
    33. 33. 1 + 2 * 3
    34. 34. 1 + 2 * 31 + (2 * 3)
    35. 35. 1 + 2 * 31 + (2 * 3)(+ 1 (* 2 3))
    36. 36. Funksjoner(fn [& nums] (apply + nums))
    37. 37. Funksjoner(def sum (fn [& nums] (apply + nums)))
    38. 38. Funksjoner(def sum )
    39. 39. Funksjoner(def sum (fn [& nums] (apply + nums)))
    40. 40. Funksjoner(def sum (fn [& nums] (apply + nums)))(defn sum [& nums] (apply + nums))
    41. 41. Lister!(3 2 1); => (3 2 1)(+ 3 2 1); => 6
    42. 42. Lister!(3 2 1); => (3 2 1)(+ 3 2 1); => 6(defn iterate [f x] (cons x (lazy-seq (iterate f (f x)))))
    43. 43. Immutable collections; List(3 2 1); Vector[1 2 3]; Set#{1 2 3}; Map{1 "one", 2 "two"‚ 3 "three"}
    44. 44. Persistent data structures(def my-list (3 2 1)); => (3 2 1)
    45. 45. Persistent data structures(def my-list (3 2 1)); => (3 2 1)
    46. 46. Persistent data structures(def my-list (3 2 1)); => (3 2 1)(def my-other-list (cons 4 my-list)); => (4 3 2 1)
    47. 47. Persistent data structures(def my-list (3 2 1)); => (3 2 1)(def my-other-list (cons 4 my-list)); => (4 3 2 1)
    48. 48. Immutable records(defrecord Person [fname lname]); => user.Person(Person. "Alf" "Støyle"); => #:user.Person{:fname "Alf", :lname "Støyle"}
    49. 49. Immutable objects are always thread-safe.
    50. 50. Ren funksjonellprogrammering f(x) = x + 1
    51. 51. Clojures filosofiVerdier Immutable/uforanderlig, primitiv eller sammensatt
    52. 52. Clojures filosofiVerdier Immutable/uforanderlig, primitiv eller sammensattIdentitet En observert entitet som vi assosierer med en serie relaterte tilstander (verdier) over tid
    53. 53. Clojures filosofiVerdier Immutable/uforanderlig, primitiv eller sammensattIdentitet En observert entitet som vi assosierer med en serie relaterte tilstander (verdier) over tidTilstand Verdien til en identitet i på et gitt tidspunkt
    54. 54. Clojures filosofiVerdier Immutable/uforanderlig, primitiv eller sammensattIdentitet En observert entitet som vi assosierer med en serie relaterte tilstander (verdier) over tidTilstand Verdien til en identitet i på et gitt tidspunktTid Relativ før/etter endring av identitet
    55. 55. Perception
    56. 56. Perception
    57. 57. Perception
    58. 58. Perception
    59. 59. Perception
    60. 60. Perception
    61. 61. Fra Rich Hickeys“Are we there yet”
    62. 62. Reference types• Atoms - synkron og ukoordinert oppdatering• Agents - asynkron og ukoordinert oppdatering• Refs - synkron og koordinert oppdatering
    63. 63. Reference types• Atoms - synkron og ukoordinert oppdatering• Agents - asynkron og ukoordinert oppdatering• Refs - synkron og koordinert oppdatering• Synkron perception
    64. 64. Atoms(def an-atom (atom 0)); => #user/an-atom
    65. 65. Atoms(def an-atom (atom 0)); => #user/an-atom(swap! an-atom inc); => 1
    66. 66. Atoms(def an-atom (atom 0)); => #user/an-atom(swap! an-atom inc); => 1(deref an-atom); => 1
    67. 67. Atoms(def an-atom (atom 0)); => #user/an-atom(swap! an-atom inc); => 1(deref an-atom); => 1@an-atom; => 1
    68. 68. Agents(def an-agent (agent 0)); => #user/an-atom
    69. 69. Agents(def an-agent (agent 0)); => #user/an-atom(send an-agent inc); => #<Agent@9b7c63f: 0>
    70. 70. Agents(def an-agent (agent 0)); => #user/an-atom(send an-agent inc); => #<Agent@9b7c63f: 0>@an-agent; => ; 0 eller 1 ??
    71. 71. Agents(def an-agent (agent 0)); => #user/an-atom(send an-agent inc); => #<Agent@9b7c63f: 0>@an-agent (await an-agent); => ; 0 eller 1 ?? ; => nil @an-agent ; => 1
    72. 72. Refs(def ref-1 (ref 0)); => #user/ref-1(def ref-2 (ref 0)); => #user/ref-2
    73. 73. Refs(def ref-1 (ref 0)); => #user/ref-1(def ref-2 (ref 0)); => #user/ref-2(alter ref-1 inc)
    74. 74. Refs(def ref-1 (ref 0)); => #user/ref-1(def ref-2 (ref 0)); => #user/ref-2(alter ref-1 inc); java.lang.IllegalStateException:; No transaction running
    75. 75. Refs(def ref-1 (ref 0)); => #user/ref-1(def ref-2 (ref 0)); => #user/ref-2(alter ref-1 inc); java.lang.IllegalStateException:; No transaction running(dosync (alter ref-1 inc)); => 1
    76. 76. Refs(dosync (alter ref-1 inc) (alter ref-2 dec)); => -1
    77. 77. Refs(dosync (alter ref-1 inc) (alter ref-2 dec)); => -1@ref-1; => 2@ref-2; => -1
    78. 78. Refs(dosync (alter ref-1 inc) (dosync (alter ref-2 dec))); => -2@ref-1; => 3@ref-2; => -2
    79. 79. Software transactional memory
    80. 80. Software transactional memory
    81. 81. Software transactional memory Transactional memory is to shared-memory concurrency as garbage collection is to memory management
    82. 82. Software transactional memory
    83. 83. Software transactional memory Atomic Consistent Isolated Durable
    84. 84. (defn transfer [from-account to-account amount] (dosync (if (> amount @from-account) (throw (new Exception "Not enough money!"))) (alter from-account - amount) (alter to-account + amount)))(def account-a (ref 1000))(def account-b (ref 800))(transfer account-a account-b 300)@account-a; => 700
    85. 85. Oppsummering• Skiller tilstand og identitet• Ingen mutable tilstand• Ingenting blokkerer• Clojure hjelper langt på vei med concurrency
    86. 86. Oppsummering• Skiller tilstand og identitet• Ingen mutable tilstand• Ingenting blokkerer• Clojure hjelper langt på vei med concurrency• Mindre “accidental complexity”
    87. 87. Clojure syntaks(Masse paranteser)
    88. 88. • REPL• Syntaks• Data strukturer• Funksjoner• Hvordan fylle ut oppgavene• Hvordan finne hjelp
    89. 89. clojure-workshop/$ lein repl
    90. 90. Dette er en form
    91. 91. Dette er også en liste
    92. 92. Et uttrykk (expression)
    93. 93. Dette er en liste
    94. 94. Akkurat samme, skrevet litt lenger
    95. 95. Noen som klarer å gjette hva dette blir?
    96. 96. En funksjon er også bare data
    97. 97. Dette er en funksjon (uten navn)
    98. 98. Lost in Stupid Parentheses?
    99. 99. let lar deg binde lokale variable
    100. 100. Oppgaver! Disse ligger underclojure-workshop/test/clojure-workshop/test/ (Dere ser ikke dobbelt)
    101. 101. Start med core.clj
    102. 102. c-w/$ lein testc-w/$ lein test clojure-workshop.test.core
    103. 103. To streker: __ => En funksjonTre streker: ___ => En verdi
    104. 104. Alle testene er kommentert ut, flytt (commentnedover for å kommentere inn tester
    105. 105. • http://clojuredocs.org• http://clojure.org/cheatsheet• Repl har innebygget hjelp• (doc first)• (find-doc “Returns the first item”)• (apropos ‘first)• (source first)
    106. 106. JSON over HTTP
    107. 107. JSON• JavaScript Object Notation• http://www.json.org/ • It is easy for humans to read and write. • It is easy for machines to parse and generate
    108. 108. { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } http://en.wikipedia.org/wiki/JSON
    109. 109. { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY",map }, "postalCode": "10021" "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } http://en.wikipedia.org/wiki/JSON
    110. 110. { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", map }, "postalCode": "10021" "phoneNumber": [ { "type": "home", "number": "212 555-1234" },vector { "type": "fax", "number": "646 555-4567" } ] } http://en.wikipedia.org/wiki/JSON
    111. 111. (clojure.data.json/read-json "...")
    112. 112. { :firstName John, :lastName Smith, :age 25, :address { :streetAddress 21 2nd Street, :city New York, :state NY, :postalCode 10021 }, :phoneNumber [ { :type home, :number 212 555-1234 } { :type fax, :number 646 555-4567 } ]}
    113. 113. { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] }
    114. 114. (get {:one 1 :two 2 :three 3} :one);=> 1
    115. 115. (get {:one 1 :two 2 :three 3} :one);=> 1(:one {:one 1 :two 2 :three 3});=> 1
    116. 116. (get {:one 1 :two 2 :three 3} :one);=> 1(:one {:one 1 :two 2 :three 3});=> 1({:one 1 :two 2 :three 3} :one);=> 1
    117. 117. clj-http(client/get "http://google.com")=> {:status 200 :headers {"date" "Sun, 01 Aug 2010 07:03:49 GMT" "cache-control" "private, max-age=0" "content-type" "text/html; charset=ISO-8859-1" ...} :body "<!doctype html>..."} https://github.com/dakrone/clj-http
    118. 118. Oppgave• Eksempel på twitter json i “twitter-java-search-json.txt”• Skrive ut “tweet-text” fra live twitter søk• Skriv ut encodings benyttet i resultat av live twitter søk• twitter-java-search-json.txt • Finn antall unike encodings • Skriv ut tweets fra “world_finance” • Skriv ut tweets som er replies• API’er • https://github.com/dakrone/clj-http • http://clojure.github.com/clojure-contrib/json-api.html
    119. 119. Lyst til å lære mer?• clojure.org• 4clojure.com• github.com/functional-koans/clojure-koans
    120. 120. Takk for oss :)• Spørsmål: • aks@knowit.no • aja@knowit.no• Oppgaver: github.com/andreaja/clojure-workshop• Løsninger: github.com/andreaja/clojure-workshop/tree/solutions

    ×