Uploaded on

A slightly-modified version of my IPRUG talk, this time for the BT DevCon5 developer conference at Adastral Park on 25 May 2012. …

A slightly-modified version of my IPRUG talk, this time for the BT DevCon5 developer conference at Adastral Park on 25 May 2012.

The main changes are the addition of the Ruby section and the increased number of HHGTTG references in honour of towel day.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
660
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
2
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. What I learned fromSeven Languagesin Seven WeeksKerry Buckley (@kerryb) – DevCon5 25/5/12
  • 2. Twenty-
  • 3. RubyIoPrologScalaErlangClojureHaskell
  • 4. What is the typing model?What is the programming model?How will you interact with it?What are the decision constructsand core data structures?What are the core features thatmake the language unique?
  • 5. Java was like having a rich lawyer as a brother. He wasfun when he was younger, but now he’s a black holethat sucks away all the joy in a 100-mile radius.
  • 6. RubyIoPrologScalaErlangClojureHaskell
  • 7. Meet Ruby, one of my favorites. She’s sometimes quirky,always beautiful, a little mysterious, and absolutely magical.
  • 8. The irb console>> puts "Hello world"Hello world=> nil>> name = "Kerry"=> "Kerry">> puts "Hello #{name}"Hello Kerry=> nil
  • 9. Everything’s an object>> 42.class=> Fixnum>> nil.class=> NilClass>> String.class=> Class> 42.methods=> [:to_s, :+, :-, :*, :/, :abs, ...
  • 10. Duck typingdef double(x) x * 2end>> double(2)=> 4>> double(2.5)=> 5.0>> double("foo")=> "foofoo">> double(false)NoMethodError: undefined method `* for false:FalseClass from (irb):2:in `double
  • 11. Arrays, ranges & hashes>> array = [1, 2.0, "three"]>> array[0]=> 1>> array.reverse=> ["three", 2.0, 1]>> range = (1..10)>> range.include? 5=> true>> hash = {:foo => 123, "bar" => "", 456 => [1, 2]}>> hash[456]=> [1, 2]
  • 12. Blocks & yield>> 3.times { puts "hello" }hellohellohello>> File.open "some-file", "w" do |f|?> f.write "some-data">> end>> def delayed_by seconds>> sleep seconds>> yield>> end>> delayed_by 5 do?> puts "At last!">> endAt last!
  • 13. Open classesclass NilClass def blank? true endendclass String def blank? empty? endend>> [nil, "", "foo"].map &:blank?=> [true, true, false]
  • 14. Modules & mixinsmodule Debug def info "#{self.class}[#{object_id}]: #{to_s}" endendclass Object include Debugend>> 2.info=> "Fixnum[5]: 2">> "foo".info=> "String[70107061928320]: foo"
  • 15. Collections & Enumerable class MyCollection include Enumerable def each ... end end >> MyCollection.instance_methods.sort => [:all?, :any?, :chunk, :collect, :collect_concat, :count, :cycle, :detect, :drop, :drop_while, :each, :each_cons, :each_entry, :each_slice, :each_with_index, :each_with_object, :entries, :find, :find_all, :find_index, :first, :flat_map, :grep, :group_by, :include?, :inject, :map, :max, :max_by, :member?, :min, :min_by, :minmax, :minmax_by, :none?, :one?, :partition, :reduce, :reject, :reverse_each, :select, :slice_before, :sort, :sort_by, :take, :take_while, :to_a, :zip]
  • 16. method_missing magicclass MyStruct def initialize values @values = values end def method_missing name, *args @values[name] endend>> struct = MyStruct.new foo: 123, bar: 456=> #<MyStruct:0x007fc2c21433b8 @values={:foo=>123, :bar=>456}>>> struct.foo=> 123>> struct.bar=> 456
  • 17. Dynamic definitionclass MyStruct def initialize values @values = values end def method_missing name, *args puts "Defining method #{name}" self.class.class_eval do define_method(name) { @values[name] } end send(name, *args) endend>> struct.fooDefining method foo=> 123>> struct.foo=> 123
  • 18. ProsPower and flexibilityDeveloper productivity and funRaw execution speedLimited concurrency supportType-aware tool support Cons
  • 19. RubyIoPrologScalaErlangClojureHaskell
  • 20. Io is a rule bender. He’s young, wicked smart, and easy tounderstand but hard to predict. He might give you the ride ofyour life, wreck your dad’s car, or both.
  • 21. Message passingIo> "oI olleH" reverse==> Hello IoIo> list("iH", "oI") map(reverse)==> list(Hi, Io)Io> list(1, 2, 3) map(** 2) sum==> 14
  • 22. Objects & SlotsIo> Person := Object clone==> Person_0x7f922c06ad00: type = "Person"Io> Person firstName := "John"==> JohnIo> Person lastName := "Doe"==> DoeIo> Person firstName==> John
  • 23. Defining methodsIo> Person name := method ( firstName .. " " .. lastName)Io> Person name==> John Doe
  • 24. Prototypal inheritanceIo> Arthur := Person clone==> Arthur_0x7fd5406cd860: type = "Arthur"Io> Arthur name==> John DoeIo> Arthur firstName = "Arthur"Io> Arthur lastName = "Dent"Io> Arthur name==> Arthur DentIo> Arthur proto==> Person_0x7fd540693ed0: firstName = "John" lastName = "Doe" name = method(...) type = "Person"
  • 25. Control structuresIo> for(i, 1, 3, i println)123==> 3Io> if(true, "Yes" println, "No" println)Yes==> Yes
  • 26. ReflectionIo> foo := method( call sender println call message arguments println)Io> foo("bar", 42) Object_0x7fcf78418920: Lobby = Object_0x7fcf78418920 Protos = Object_0x7fcf78417c00 ...list("bar", 42)
  • 27. CoroutinesIo> Ping := Object cloneIo> Pong := Object cloneIo> Ping ping := method ( 2 repeat("Ping!" println; yield))Io> Pong pong := method ( 2 repeat(yield; "Pong!" println))Io> Ping @@ping; Pong @@pongIo> Coroutine currentCoroutine pausePing!Pong!Ping!Pong!
  • 28. ActorsIo> Slow := Object cloneIo> Fast := Object cloneIo> Slow go := method( wait(1) "Slow" println)Io> Fast go := method( "Fast" println)Io> Slow @@go; Fast @@go; wait(2)FastSlow
  • 29. FuturesIo> page := URL with( "http://google.co.uk/") @fetchIo> "Im in the foreground" printlnIm in the foregroundIo> page size println16906
  • 30. ProsTiny – ideal for embedded systemsPrototypes and duck typing are very flexibleConcurrency supportSimple, consistent syntaxRaw execution speedSmall user community Cons
  • 31. RubyIoPrologScalaErlangClojureHaskell
  • 32. Sometimes spectacularly smart, other times just as frustrating. You’llget astounding answers only if you know how to ask the question.
  • 33. Simple factslikes(wallace, cheese).likes(gromit, cheese).likes(wendolene, sheep).?- likes(wallace, sheep).false.?- likes(gromit, cheese).true.?- likes(Who, cheese).Who = wallace ;Who = grommit.
  • 34. Evaluating rulesfriend(X, Y) :- +(X = Y), likes(X, Z), likes(Y, Z).?- friend(wallace, wallace).false.?- friend(wendolene, gromit).false.?- friend(wallace, gromit).true.
  • 35. Recursive rulesfather(grandpa, homer).father(homer, bart).ancestor(X, Y) :- father(X, Y).ancestor(X, Y) :- father(X, Z), ancestor(Z, Y).?- ancestor(Who, bart).Who = homer ;Who = grandpa ;false.
  • 36. Tuples?- (X, Y, Z) = (1, 2, "foo").X = 1,Y = 2,Z = [102, 111, 111].?- (X, _, Z) = (1, 2, "foo").X = 1,Z = [102, 111, 111].
  • 37. Calculation with listssum(0, []).sum(Total, [Head|Tail]) :- sum(Sum, Tail), Total is Head + Sum.?- sum(What, [1, 2, 3]).What = 6.
  • 38. Solving (4×4) sudoku?- sudoku([_, _, 2, 3, _, _, _, _, _, _, _, _, 3, 4, _, _], Solution).Solution = [4,1,2,3,2,3,4,1,1,2,3,4,3,4,1,2].
  • 39. Solving (4×4) sudokusudoku(Puzzle, Solution) :- Solution = Puzzle, Puzzle = [S11, S12, S13, S14, S21, S22, S23, S24, S31, S32, S33, S34, S41, S42, S43, S44], Solution ins 1..4, Row1 = [S11, S12, S13, S14], Row2 = [S21, S22, S23, S24], Row3 = [S31, S32, S33, S34], Row4 = [S41, S42, S43, S44], Col1 = [S11, S21, S31, S41], Col2 = [S12, S22, S32, S42], Col3 = [S13, S23, S33, S43], Col4 = [S14, S24, S34, S44], Square1 = [S11, S12, S21, S22], Square2 = [S13, S14, S23, S24], Square3 = [S31, S32, S41, S42], Square4 = [S33, S34, S43, S44], valid([Row1, Row2, Row3, Row4, Col1, Col2, Col3, Col4, Square1, Square2, Square3, Square4]).valid([]).valid([Head|Tail]) :- all_different(Head), valid(Tail).
  • 40. ProsSolving logical and scheduling problemsNatural language processingArtificial intelligenceScaling requires deep understandingNot a general-purpose languageSimple procedural tasks are difficult Cons
  • 41. RubyIoPrologScalaErlangClojureHaskell
  • 42. He was often awkward, was sometimes amazing, but always had aunique expression. Sometimes, his scissors let him do incredible things.Other times, he was awkward and humiliated.
  • 43. Type inference & coercion scala> "foo" res0: java.lang.String = foo scala> 123 res1: Int = 123 scala> 45.6 res2: Double = 45.6 scala> 1 + 2.3 res3: Double = 3.3 scala> "The answer is " + 42 res4: java.lang.String = The answer is 42
  • 44. var & valscala> var a = 42a: Int = 42scala> a = a + 1a: Int = 43scala> val earth = "Harmless"earth: java.lang.String = Harmlessscala> earth = "Mostly Harmless"<console>:8: error: reassignment to val earth = "Mostly Harmless" ^
  • 45. Ranges & tuplesscala> val range = 0 to 3range: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)scala> val range = 0 to 5 by 2range: scala.collection.immutable.Range = Range(0, 2, 4)scala> val tuple = ("Kerry", 42)tuple: (java.lang.String, Int) = (Kerry,42)scala> val (name, age) = tuplename: java.lang.String = Kerryage: Int = 42
  • 46. Lists, sets & mapsscala> val list = List(1, 2, 3)list: List[Int] = List(1, 2, 3)scala> list(1)res0: Int = 2scala> "zero"::listres1: List[Any] = List(zero, 1, 2, 3)scala> Set(1, 2, 3) ++ Set(2, 3, 4)res2: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)scala> val map = Map(1 -> "One", 2 -> "Two")map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> One, 2 -> Two)scala> map(1)res3: java.lang.String = One
  • 47. Defining classesclass Person(firstName: String, lastName: String) { def greet(name: String) { println("Hello " + name + ", Im " + firstName + ".") }}scala> val kerry = new Person("Kerry", "Buckley")kerry: Person = Person@276bab54scala> kerry.greet("DevCon")Hello DevCon, Im Kerry.
  • 48. Companion objectsclass Person(firstName: String, lastName: String) { ...}object Person { def find(id: Int) { val (first, last) = DB.people.find(id) new Person(first, last }}
  • 49. Extending & traitsclass Person(val name:String)trait Nice { def greet() = println("Howdily doodily.")}class Character(override val name:String) extends Person(name) with Nicescala> val flanders = new Character("Ned")scala> flanders.greetHowdily doodily.
  • 50. List processingscala> val jedi = List("Yoda", "Obiwan", "Luke")jedi: List[java.lang.String] = List(Yoda, Obiwan, Luke)scala> jedi.filter(name => name.size < 5)res0: List[java.lang.String] = List(Yoda, Luke)scala> jedi.map(name => name.size)res1: List[Int] = List(4, 6, 4)scala> val numbers = List(1, 2, 3)numbers: List[Int] = List(1, 2, 3)scala> numbers.foldLeft(0)((a, n) => a + n)res2: Int = 6
  • 51. Class hierarchy Any AnyVal AnyRefFloat Int … ScalaObject … List Map Nothing Null
  • 52. First-class XMLscala> val pets = <pets> <chicken>Babs</chicken> <chicken>Bunty</chicken> <chicken>Lily</chicken> <cat>Pebbles</cat> <chicken>Pepper</chicken> <cat>Twiglet</cat> <cat>Willow</cat> <cat>Zorro</cat></pets>scala> pets "cat"res0: scala.xml.NodeSeq = NodeSeq(<cat>Twiglet</cat>, <cat>Pebbles</cat>, <cat>Willow</cat>, <cat>Zorro</cat>)
  • 53. Pattern matchingscala> (pets "_").foreach {pet => pet match { case <cat>{name}</cat> => println(name + " says meow.") case <chicken>{name}</chicken> = println(name + " says cluck.") }}Babs says cluck.Bunty says cluck.Lily says cluck.Pebbles says meow.Pepper says cluck.Twiglet says meow.Willow says meow.Zorro says meow.
  • 54. Concurrency with actorscase object Strokecase object Feedclass Cat() extends Actor { def act() { loop { react { case Stroke => { println("Purr!") } case Feed => { println("Om nom nom") } } } }}scala> val cat = new Cat().startscala> cat ! Stroke; cat ! Feed; println("Done.")Done.Purr!Om nom nom
  • 55. ProsA modern version of JavaMixins, pattern matching, blocks, XMLConcurrency with actors & immutabilityStatic typingCompromises with mutable state Cons
  • 56. RubyIoPrologScalaErlangClojureHaskell
  • 57. Agent Smith was an artificial intelligence program in the matrix thathad an amazing ability to take any form and bend the rules ofreality to be in many places at once. He was unavoidable.
  • 58. The usual types (mostly)1> 2 + 2.42> "Hello"."Hello"3> atom.atom4> {foo, 123, "bar"}.{foo,123,"bar"}5> [1, "one", two].[1,"one", two]6> [87, 84, 70, 63]."WTF?"
  • 59. Variables don’t change1> Foo = 42.422> Foo = Foo + 1.** exception error: no match of right hand side value 433> Values = [1, 2, 3].[1,2,3]4> lists:append(Values, [4]).[1,2,3,4]5> Values.[1,2,3]
  • 60. Pattern matching1> Pet = {{name, "Zorro"}, {type, "Cat"}}.{{name,"Zorro"},{type,"Cat"}}2> {{name, Name}, {type, Type}} = Pet.{{name,"Zorro"},{type,"Cat"}}3> Name."Zorro"4> Type."Cat"5> [Head|Tail] = [foo, bar, baz].[foo,bar,baz]6> {Head, Tail}.{foo,[bar,baz]}
  • 61. Bit matching1> [A, B, C, D] = [1, 0, 50, 200].[1,0,50,200]2> Packed = <<A:1, B:1, C:6, D:8>>.<<"²È">>3> <<P:1, Q:1, R:6, S:8>> = Packed.<<"²È">>4> {P, Q, R, S}.{1,0,50,200}
  • 62. Basic functions-module(demo).-export([echo/1]).echo(Value) -> Value.1> c(demo).{ok,demo}5> demo:echo("Hello")."Hello"6> demo:echo(42).42
  • 63. Patterns in functions-module(fact).-export([fact/1]).fact(0) -> 1;fact(N) -> N * fact(N-1).1> c(fact).{ok,fact}3> fact:fact(6).7204> fact:fact("foo").** exception error: bad argument in an arithmeticexpression in function fact:fact/1 (fact.erl, line 5)6> fact:fact(10000).
  • 64. Patterns in functions28462596809170545189064132121198688901480514017027992307941799942744113400037644437729907867577847758158840621423175288300423399401535187390524211613827161748198241998275924182892597878981242531205946599625986706560161572036032397926328736717055741975962099479720346153698119897092611277500484198845410475544642442136573303076703628825803548967461117097369578603670191071512730587281041158640561281165385325968425825995584688146430425589836649317059251717204276597407446133400054194052462303436869154059404066227828248371512038322178644627183822923899638992827221879702459387693803094627332292570555459690027875282242544348021127559019169425429028916907219097083690539873747452483372899521802363282741217040268086769210451555840567172555372015852132829034279989818449313610640381489304499621599999359670892980190336998484404665419236258424947163178961192041233108268651071354516845540936033009607210346944377982349430780626069422302681885227592057029230843126188497606560742586279448827155956831533440534425446648416894580425709461673613187605234982286326452921529423479870603344290737158688499178932580691483168854251956006172372636323974420786924642956012306288720122652952964091508301336630982733806353972901506581822574295475894399765113865541208125788683704239208764484761569001264889271590706306409661628038784044485191643790807186112370622133415415065991843875961023926713276546986163657706626438638029848051952769536195259240930908614471907390768585755934786981720734372093104825475628567777694081564074962275254993384112809289637516990219870492405617531786346939798024619737079041868329931016554150742308393176878366923
  • 65. Patterns in functions284625968091705451890641321211986889014805140170279923079417999427441134000376444377299078675778477581588406214231752883004233994015351873905242116138271617481982419982759241828925978789812425312059465996259867065601615720360323979263287367170557419759620994797203461536981198970926112775004841988454104755446424421365733030767036288258035489674611170973695786036701910715127305872810411586405612811653853259684258259955846881464304255898366493170592517172042765974074461334000541940524623034368691540594040662278282483715120383221786446271838229238996389928272218797024593876938030946273322925705554596900278752822425443480211275590191694254290289169072190970836905398737474524833728995218023632827412170402680867692104515558405671725553720158521328290342799898184493136106403814893044996215999993596708929801903369984844046654192362584249471631789611920412331082686510713545168455409360330096072103469443779823494307806260694223026818852275920570292308431261884976065607425862794488271559568315334405344254466484168945804257094616736131876052349822863264529215294234798706033442907371586884991789325806914831688542519560061723726363239744207869246429560123062887201226529529640915083013366309827338063539729015065818225742954758943997651138655412081257886837042392087644847615690012648892715907063064096616280387840444851916437908071861123706221334154150659918438759610239267132765469861636577066264386380298480519527695361952592409309086144719073907685857559347869817207343720931048254756285677776940815640749622752549933841128092896375169902198704924056175317863469397980246197370790418683299310165541507423083931768783669236948490259996077296842939774275362631198254166815318917632348391908210001471789321842278051351817349219011462468757698353734414560131226152213911787596883673640872079370029920382791980387023720780391403123689976081528403060511167094847222248703891999934420713958369830639622320791156240442508089199143198371204455983440475567594892121014981524545435942854143908435644199842248554785321636240300984428553318292531542065512370797058163934602962476970103887422064415366267337154287007891227493406843364428898471008406416000936239352612480379752933439287643983163903127764507224792678517008266695983895261507590073492151975926591927088732025940663821188019888547482660483422564577057439731222597006719360617635135795298217942907977053272832675014880244435286816450261656628375465190061718734422604389192985060715153900311066847273601358167064378617567574391843764796581361005996386895523346487817461432435732248643267984819814584327030358955084205347884933645824825920332880890257823882332657702052489709370472102142484133424652682068067323142144838540741821396218468701083595829469652356327648704757183516168792350683662717437119157233611430701211207676086978515597218464859859186436417168508996255168209107935702311185181747750108046225855213147648974906607528770828976675149510096823296897320006223928880566580361403112854659290840780339749006649532058731649480938838161986588508273824680348978647571166798904235680183035041338757319726308979094357106877973016339180878684749436335338933735869064058484178280651962758264344292580584222129476494029486226707618329882290040723904037331682074174132516566884430793394470192089056207883875853425128209573593070181977083401638176382785625395168254266446149410447115795332623728154687940804237185874230262002642218226941886262121072977766574010183761822801368575864421858630115398437122991070100940619294132232027731939594670067136953770978977781182882424429208648161341795620174718316096876610431404979581982364458073682094040222111815300514333870766070631496161077711174480595527643483333857440402127570318515272983774359218785585527955910286644579173620072218581433099772947789237207179428577562713009239823979219575811972647426428782666823539156878572716201461922442662667084007656656258071094743987401107728116699188062687266265655833456650078903090506560746330780271585308176912237728135105845273265916262196476205714348802156308152590053437211410003030392428664572073284734817120341681863289688650482873679333984439712367350845273401963094276976526841701749907569479827578258352299943156333221074391315501244590053247026803129123922979790304175878233986223735350546426469135025039510092392865851086820880706627347332003549957203970864880660409298546070063394098858363498654661367278807487647007024587901180465182961112770906090161520221114615431583176699570609746180853593904000678928785488278509386373537039040494126846189912728715626550012708330399502578799317054318827526592258149489507466399760073169273108317358830566126147829976631880700630446324291122606919312788815662215915232704576958675128219909389426866019639044897189185974729253103224802105438410443258284728305842978041624051081103269140019005687843963415026965210489202721402321602348985888273714286953396817551062874709074737181880142234872484985581984390946517083643689943061896502432883532796671901845276205510857076262042445096233232047447078311904344993514426255017017710173795511247461594717318627015655712662958551250777117383382084197058933673237244532804565371785149603088025802840678478094146418386592266528068679788432506605379430462502871051049293472674712674998926346273581671469350604951103407554046581703934810467584856259677679597682994093340263872693783653209122877180774511526226425487718354611088863608432728062277766430972838790567286180360486334648933714394152502594596525015209595361579771355957949657297756509026944280884797612766648470036196489060437619346942704440702153179435838310514049154626087284866787505416741467316489993563813128669314276168635373056345866269578945682750658102359508148887789550739393653419373657008483185044756822154440675992031380770735399780363392673345495492966687599225308938980864306065329617931640296124926730806380318739125961511318903593512664808185683667702865377423907465823909109555171797705807977892897524902307378017531426803639142447202577288917849500781178893366297504368042146681978242729806975793917422294566831858156768162887978706245312466517276227582954934214836588689192995874020956960002435603052898298663868920769928340305497102665143223061252319151318438769038237062053992069339437168804664297114767435644863750268476981488531053540633288450620121733026306764813229315610435519417610507124490248732772731120919458651374931909651624976916575538121985664322079786663003989386602386073578581143947158728008933741650337929658326184360731333275260236051155242272284472514638632693697637625101967143801256912277844284269994408291522159046944372824986580852051865762929927755088331286726384187132777808744466438753526447335624411394476287809746506839529821081749679588364522733446948737934717907100649782364660166805720342979292074468223228486658395222114468595728584038633772780302275915304978658739195136502462741958990883743873315942873720297706202071202130385721759332111624133304227737424163535535879770653096476858860773014327782903288947958184043788585677729320944767786693575374600481423767411941826716368704810569111562156143575162905273512243500806046536689174581965494826086122607502930627614788132689552807361490225258196828150510333181321296596649581590304212387756459909732967280666838491662579497479229053618455637410347914307715611686504842924902811029925296787352987678292690407887784802624792227507359484058174390862518779468900459420601686051427722444862724699111462001498806627235388378093806285443847630532350
  • 66. Patterns in functions284625968091705451890641321211986889014805140170279923079417999427441134000376444377299078675778477581588406214231752883004233994015351873905242116138271617481982419982759241828925978789812425312059465996259867065601615720360323979263287367170557419759620994797203461536981198970926112775004841988454104755446424421365733030767036288258035489674611170973695786036701910715127305872810411586405612811653853259684258259955846881464304255898366493170592517172042765974074461334000541940524623034368691540594040662278282483715120383221786446271838229238996389928272218797024593876938030946273322925705554596900278752822425443480211275590191694254290289169072190970836905398737474524833728995218023632827412170402680867692104515558405671725553720158521328290342799898184493136106403814893044996215999993596708929801903369984844046654192362584249471631789611920412331082686510713545168455409360330096072103469443779823494307806260694223026818852275920570292308431261884976065607425862794488271559568315334405344254466484168945804257094616736131876052349822863264529215294234798706033442907371586884991789325806914831688542519560061723726363239744207869246429560123062887201226529529640915083013366309827338063539729015065818225742954758943997651138655412081257886837042392087644847615690012648892715907063064096616280387840444851916437908071861123706221334154150659918438759610239267132765469861636577066264386380298480519527695361952592409309086144719073907685857559347869817207343720931048254756285677776940815640749622752549933841128092896375169902198704924056175317863469397980246197370790418683299310165541507423083931768783669236948490259996077296842939774275362631198254166815318917632348391908210001471789321842278051351817349219011462468757698353734414560131226152213911787596883673640872079370029920382791980387023720780391403123689976081528403060511167094847222248703891999934420713958369830639622320791156240442508089199143198371204455983440475567594892121014981524545435942854143908435644199842248554785321636240300984428553318292531542065512370797058163934602962476970103887422064415366267337154287007891227493406843364428898471008406416000936239352612480379752933439287643983163903127764507224792678517008266695983895261507590073492151975926591927088732025940663821188019888547482660483422564577057439731222597006719360617635135795298217942907977053272832675014880244435286816450261656628375465190061718734422604389192985060715153900311066847273601358167064378617567574391843764796581361005996386895523346487817461432435732248643267984819814584327030358955084205347884933645824825920332880890257823882332657702052489709370472102142484133424652682068067323142144838540741821396218468701083595829469652356327648704757183516168792350683662717437119157233611430701211207676086978515597218464859859186436417168508996255168209107935702311185181747750108046225855213147648974906607528770828976675149510096823296897320006223928880566580361403112854659290840780339749006649532058731649480938838161986588508273824680348978647571166798904235680183035041338757319726308979094357106877973016339180878684749436335338933735869064058484178280651962758264344292580584222129476494029486226707618329882290040723904037331682074174132516566884430793394470192089056207883875853425128209573593070181977083401638176382785625395168254266446149410447115795332623728154687940804237185874230262002642218226941886262121072977766574010183761822801368575864421858630115398437122991070100940619294132232027731939594670067136953770978977781182882424429208648161341795620174718316096876610431404979581982364458073682094040222111815300514333870766070631496161077711174480595527643483333857440402127570318515272983774359218785585527955910286644579173620072218581433099772947789237207179428577562713009239823979219575811972647426428782666823539156878572716201461922442662667084007656656258071094743987401107728116699188062687266265655833456650078903090506560746330780271585308176912237728135105845273265916262196476205714348802156308152590053437211410003030392428664572073284734817120341681863289688650482873679333984439712367350845273401963094276976526841701749907569479827578258352299943156333221074391315501244590053247026803129123922979790304175878233986223735350546426469135025039510092392865851086820880706627347332003549957203970864880660409298546070063394098858363498654661367278807487647007024587901180465182961112770906090161520221114615431583176699570609746180853593904000678928785488278509386373537039040494126846189912728715626550012708330399502578799317054318827526592258149489507466399760073169273108317358830566126147829976631880700630446324291122606919312788815662215915232704576958675128219909389426866019639044897189185974729253103224802105438410443258284728305842978041624051081103269140019005687843963415026965210489202721402321602348985888273714286953396817551062874709074737181880142234872484985581984390946517083643689943061896502432883532796671901845276205510857076262042445096233232047447078311904344993514426255017017710173795511247461594717318627015655712662958551250777117383382084197058933673237244532804565371785149603088025802840678478094146418386592266528068679788432506605379430462502871051049293472674712674998926346273581671469350604951103407554046581703934810467584856259677679597682994093340263872693783653209122877180774511526226425487718354611088863608432728062277766430972838790567286180360486334648933714394152502594596525015209595361579771355957949657297756509026944280884797612766648470036196489060437619346942704440702153179435838310514049154626087284866787505416741467316489993563813128669314276168635373056345866269578945682750658102359508148887789550739393653419373657008483185044756822154440675992031380770735399780363392673345495492966687599225308938980864306065329617931640296124926730806380318739125961511318903593512664808185683667702865377423907465823909109555171797705807977892897524902307378017531426803639142447202577288917849500781178893366297504368042146681978242729806975793917422294566831858156768162887978706245312466517276227582954934214836588689192995874020956960002435603052898298663868920769928340305497102665143223061252319151318438769038237062053992069339437168804664297114767435644863750268476981488531053540633288450620121733026306764813229315610435519417610507124490248732772731120919458651374931909651624976916575538121985664322079786663003989386602386073578581143947158728008933741650337929658326184360731333275260236051155242272284472514638632693697637625101967143801256912277844284269994408291522159046944372824986580852051865762929927755088331286726384187132777808744466438753526447335624411394476287809746506839529821081749679588364522733446948737934717907100649782364660166805720342979292074468223228486658395222114468595728584038633772780302275915304978658739195136502462741958990883743873315942873720297706202071202130385721759332111624133304227737424163535535879770653096476858860773014327782903288947958184043788585677729320944767786693575374600481423767411941826716368704810569111562156143575162905273512243500806046536689174581965494826086122607502930627614788132689552807361490225258196828150510333181321296596649581590304212387756459909732967280666838491662579497479229053618455637410347914307715611686504842924902811029925296787352987678292690407887784802624792227507359484058174390862518779468900459420601686051427722444862724699111462001498806627235388378093806285443847630532350701320280294883920081321354464500561349870178342711061581772898192906564986880810455622337030672542512772773302834984335957725759562247037077933871465930330886296994403183326657975146765027173462988837773978482187007180267412659971587280354404784324786749071279216728985235884869435466922551013376063779151645972542571169684773399511589983490818882812639844005055462100669887926145582145653196969098272539345157604086134762587781658672944107753588241623157790825380547469335405824697176743245234514984830271703965438877376373581917365824542733474904242629460112998819165637138471118491569150547681404117498014542657123942044254410280758060013881986506137592885390389226443229479902864828400995986759635809991126953676015271730868527565721475835071222982965295649178350717508357413622825450556202709694174767992592297748886274113145876761475314568953280931170526964864101874076732969866492364373825654750228164719268155598831966298483077766668406223143158843849105190582818167407644630333001197102930364558665946518690744752508378419876229904159117936827997606541860887216266548864923443910309232569106337759697390517811227646684867917360494043937033393519006093872683972992464784837272747709774666935997848571201567890002419472692209749841273231474015499809203814598214164811763571478015542315996678385348544864069364105569135313352311840535813489409381918218986948253839609899428220275993396352062177053435720733962505742167694651016084956014393032443042715760995273086846092044222261031542299844448021100981613338248273752189987382053151649271344981059501599748005715919122021544877487501034732461906339413030308923994119850062259021841644099881732143244221085542486208962502606043981801890263177811466174549997714406652328638463638470016556181538610981881111817341913055050248603458567555856375117297742993290749442365796683327009183673389773479017592488856603799527715405690830173117238941403261596122929122251910959487438056733812785386164918427869384175568980471008598683720336151751580970225662752001609561922299254017598785220385459137717839763898111984858032910487516669211951045148966777615982494687274206634375932078526189226872855276713248832677941529128391654079683441902390948036766887078380113670427539713962014247849351967353014444040378235266744375567408830252257452738062099804512331881027290120429979890054231262179681352377580411625114591759932791341765072928267622368972919605282896752235214252342172478418693173974604118776346046256371353098015906177367587153368039585590548273618761121513846734328843250900456453581866819051087317913462157303395405809871720138443770992795327976755310993813658404035567957318941419765114363255262706397431465263481200327200967556677019262425850577706178937982310969867884485466595273270616703089182772064325519193936735913460377570831931808459295651588752445976017294557205055950859291755065101156650755216351423181535481768841960320850508714962704940176841839805825940381825939864612602759542474333762262562871539160690250989850707986606217322001635939386114753945614066356757185266170314714535167530074992138652077685238248846006237358966080549516524064805472958699186943588111978336801414880783212134571523601240659222085089129569078353705767346716678637809088112834503957848122121011172507183833590838861875746612013172982171310729447376562651723106948844254983695141473838924777423209402078312008072353262880539062660181860504249387886778724955032554242842265962710506926460717674675023378056718934501107373770341193461133740338653646751367336613947315502114571046711614452533248501979010834316419899984140450449011301637595206757155675094852435802691040776372109986716242547953853128528899309565707292186735232166660978749896353626105298214725694827999962208257758409884584842503911894476087296851849839763679182422665711671665801579145008116571922002337597653174959223978849828147055061906892756252104621856613058002556079746097267150333270323100252746404287555565468837658388025432274035074316842786206376970547917264843781744463615205709332285872843156907562555693055588188226035900067393399525043798874709350792761811162763097712579839759965266121203174958820594357548838622825084014088857205839924009712192125480740977529742787759125660264434827136472318491251808662787086261166999896348124058036847945873648201246536632288890116365722708877577361520034501022688901891016735720586614100117236647626578353963642978190116470561702796319223322942287393092333307482589376261989975965300841353832411258996396294451290828020232254989366275064995308389256322467946959606690469066862926450062197401217828998729797048590217750600928933289572723920195899944719451473608507704007257174393181484619094062695452850305263410005650222261523093648828871220464542677005771489943351471625042523651737102660686472534581201866832739536825474565365535975466857887000569883602866864507402569930874834410940860863037079082952405767316849418558104824753047589233928015713028241062349999459323905214098565595656613460033961505151647588527422147325179995489779928495227460298556667008118712008561550164574004841702103030389963392533374665568178244107374093369192941046323077319947598263073834996007703724104462854146487041162738956498345551621656851145513838220470054839966717062464675661012913820489091211172293862442531589130669874620455872448060528293781483026221645422804217577607623654598282230708155034694049383177550533050946989994761194192312807218072169643784333136067606769651871383943387724854936890618457005720436966664650807344958144959663062466986798328725863000642152202101718139173252751736722626214549454685060063346927138383117158497530926432524869602200590998026637653862254632651684149633063695480865511012567577178906166947583440434862184853695916021720304561834975241620399264413316518847686068306420048585579244733402901425888764037125186422290163336915850632737271995963629127833447862188878710095337535510546889802363782637149269132895643394408994701214521345721177156575914517348951950168006213539271754198438761635434798069208866662270995123717062419249142825764531257699397353416730468645851819796682320156937926849269999839924135719414968822737040228208051718080034004806152617920139789451862952905584407037383005335524211539033851858293667791906101163062336731444192028938572018555695963308336154502904248223092970871247880020173830720604826801566753975937899317935157999589295621563073384162945999002767308328277165950642179665231904392505432267537318117553154767807394703389311851072977243183789726749574557781833454959423173535582910469673153912759756872818616911610831563372326399688814905439432611971822749967911766285534018601983158096299817911072088049922920160620590672712735994618716349457749958053379471871054564525793960242102591364155283983952017730127125148920510617082280083399856657866469207371142696823017704163248294794095586946990893791651910063051853521023451897981276191430618643627030819771249927510567329094812020577471006877033797089342292071839037441675034938188363422292849467906602856742932516425690443634730876567970565956772852910812427331544065801998027115791262541727974528625748659219332938059152395247355188871198603913196542875762901905039640835602462775343144091556421817294599415960619796226332427158634259779473486820748020215387347297079997533329877855310538201621697918803807530063343507661477371359393626519052222425281410847470452956886477579135021609220403484491499507787431071896557254926512826934895157950754861723413946103651766167503299486422440396595118822649813159250801851263866353086222234910946290593178294081956404847024565383054320565069244226718632553076407618720867803917113563635012695250912910204960428232326289965027589510528443681774157309418748944280654275614309758281276981249369933130289466705604140843089422311409127222381484703643410196304136307367710600381595908297464101144213583210425743583502207371732197450890355731873504458272387707282714061629979196293572241044771550516525358675441093950792183690152611384403826800541509243465117114364778994445539936536677275895657139875055429908245856095100369346631006737147080299276569334355009271898540501099174749799915543920319089619676154446860481754006956894714639282453838070104441810455061713051605843558175210323384658292010710300611242834074586070060601948305513648670210203647084708074227043718937069656887956179287130452245168420274020219664156052803350612935587390793935244040925842483806071774446099640352218910229619090325690423813744924949068923143308842243996313963915458540652863264688075811487483714082841764552263863135202648940162624948023885682315991029526203371264492799019382111345184463875445163912393779741905766499117642376377222828023184657380501212778096803156914772649102575035087587922481102235445244108724485657007551871321465920935485045528291707495967754044507794948363717560623269257574128131102419103733380804343253108846948315557294022653949729138175813386194570577995618087559514136449076131096171559283765858400364893740768222575239359887310816896676882874038371928276904315141069976783038190856907130919313408460195111474827663507246765349220400586266776329355166319396224989799127080044659822648991252268131243005281049950585956765271235914944426125544376186450292028813585828717895772241163808151618316031297287969874801398286216456291961530963583373136197247733323530254665711969026112373806290302429042757945490300226608474465131617416919168517464649454596960053308852527920834724952354731106741090992235410555062996876421539512493559863113466617251168907856333289355691504494851891134883018763651006385025659164330219285655962639143828950683248387271656165601115315170552229557659449724547888155323164174532671679788611411653555975883319796380709629988807673036169403177364481404278677842512324499746934213482171795951906982046029971720011748573038897192055974147424530111358697662566077709702256332617011084637847955552585045780588794407560649741279745309184184052075585264622088214836467546522376092107875391904546848523497599860449433228280731206799224024775075141058907746273343190912554513522253292759138420473846030561631542365529353122783897594465157873373434631722800010313804254814040220905804050560038609374034350688630814346838489007089385650500275690596780694046984351845351341410316151336830437147866429253897171659786290107284007589397003883177426481637251132773699268277094653425835961118819550924620621539781211972447626237715344520480698190825249439639622511138311774289785358255908324904804975160471042575697534425515157798156003708472306034847539775136883904043160174862488713393118185230294254256762024856883939708367487884537891725741451559179190353985350772009005949793529394596312134455033682606900598287177235333752219419155473037420623432628929683970150588921911120492498647920534108723491154309871821600557622090757323046261065977449476583463130255986363150299596723524769439754625302067881933043722848002093053541556406648385693781446031386975634592002334626069959555134847541478911808303298164215874529229526789379256477520290526753493566737442931826733745716424654077482679010467787590854081305314471764558698941696689404364899524652474439883495838712062964854133575538134195004987438133690627039738745866042968715958207157665998266073170056244655417630245013491595672889426197461444969086716558597827292287027237748350973629010191304178127357730377818040815891360052073158069410343050031843493423602692447330600138611197817744726696089283210525431164960334201020326038636725328896483334058622048436165753620014684054766496664735669795729533948091382637033242209308393669549806882404916220631479114946420425000224504134255585619374429052572524363200544874415243073052150704910204340765724768650957511741254137295316445217655772353486018215668333525205328300001083440087622668438170232356056451582569541773591978136499755596019125677449427179863600458474052092900893973152760243049516538644313881478769775414787574326101598797097588556258067661979730984724607694848211279484279765366070550516391044150225544203297212920330093533566872945959123279658863764868941884336405484940095749657916576872139273301535550978651147679473996906231848783775154626138236516659563372093457082083018404827970057280714329257275774362295870473616416097318172415942042703660664040897402455215307252273886372418596464552236732604111645984640200102169208233151553888210715271912678765317950719082045251004478212913185440548144941518671142071036938911291250127508534663377177493760165434546963900427111298292550968304206657253642794722000208353138837087816499571897176293387948542712768826520037663259245616148687448974715193662192756658524621144574070106753804275641844408348052038382650526016985840600847884224218878569278977518104428054744272294551674203356864606099779731249504333214252050536757904995207835976504153790011325795360406551726548790221735954441511394292316489506631778130390574620824491719213118641296337046614064569001789423567387755231309527859127745332418554424844844936642107313488191806401892223173021566458134731864499979057816620914698707180393888857812807402263636022941143548698714021435720559477308928086536789202019351026053615679244832767494761178583160718657103108422005602595451151913913091195444478443610327418761023388433916875892334237908598419682665256106287512375723184914749519459857288979349817917618226524804082371281097907726388642860679170822885758527034708397145616199262478447946927949968459456323827022973641735034307831941156982478200132908512028784748058601889600459017459740556307327144876790852888679788099706952406810066256114400149834135808897372468440649488570741676879164132242053736540673301863924979109154747859591638655975070905811759248995022147992509456355825143158144640601342834904227983579396592589852007638456466816407326819283460077672858762849000688745646392749644159040340336723378144915970329417872941550610541295154001593938516639293256774295575494800466582735796539909402335436446493768272725418736275475329768081903253361410864330842377717389952215367630953020459024386946327028952939944830135775890812148845584938198745059209140672095224690962630769417533409836988593637003149737289779963600186265001749292900879311899978229637123066422979961635825726001122889836476514180459757700421208339493646596473364642890444993253962270919073737057720513228159578632275919127860542978629531886155598047281607108641328035854001600555756868557917859778991979026565926212830072253514015259735693007290153922111168685047404021721744420517380002513610004945341193243316683442431259630988123969622023588583955878316851948331266535773532443799356832152691770422490345745348589138125826813669089294768090526355606381196613060639369384118177135459298843172329122362624588683942028899816935611698654298847765131182276625267399788088160104706515423350156713537448170862343146625311902910401522629271040992850724188433290072777947541116375521765635893163266360493812184018375128188847711689754794837676640848427536230740195421832179854962606665903479258163423926709478399070629231665350372850197513248138038370708946389254708870390857235810061306286466647100061043521157789266134322146553114118825969429262845221090266884149757633415549211355812546165580782734701158140060083457621331303899878432706537199567095708473857860926491888583787392391655542635773012922436416040625517368923356365688543658516462078218757417243645258141434876327613417527073767549222762877822647651543153415857137735227303354033763642042580342572647496862178236669513534106773784211313711319873732228918052750628122777164124944124012071259543199917465747458925826137128255555350804041439445572959945546356084872513394629363589408320989648016195831304297209647941285393889962653689282638076771687595885022164645824309401650096887973661577335603168367103868952282709415095452227440027354992536702147159940565448138421863801287999008209335763207363694059914242637182940006137419005795130962985453307481978025683010896728738022348204888629731303696898826406579047815623897784853650256910642317957360253309087632717849111897484322468680863403839641761276057886465744722848249326874430625512205069551684646694771836819114328735448158363505481464110999601433905957997662906468812950250391509236330110760706328633173933781496933802475800350527897827557509286040394205063429393270646361610318228792481526793068627492372756318522256542660085568494977202859091509304954259674736483314372363495554489015986684083621769135596560395196704253688634823695871294625247590317768131849775882765767404825581365021036495855057032592199576753342642237837235860585094035839771034766706447886408311096503025652156074640196527169997323734652371734565955145594930981666440062115993491331801351505286518421788280263433259347558507611686977091255800561856837105408560812495194031480646187194025776632852670196983875675615246967590281068648968692933159543520976875271372016161609311742501997092896849400346962423256884106651133043774122561762586589412367281711455264238945126317178347902769211714528873529550193367592189080060486337377867281806102547825704367884495035189257874998366947859086129755430841226770609543476121337174331567837901620123372370233383164147064285921859776101582327219979150628718681867509816655377450130208803339043536397702633638090985264945326281465580655465048234864294953906132574004969128883405182229336444766838550379679758096199835758070277595359687882261946596122230445492756002749551685835425822953360428344263184780688253954507466918778977654060384325128438128113168562046086172894082296586261744207669202974279300881295198546787135486232366104132165812792671515459615943525934567574459923078892055195400823164097195912500254552375031067356397488355424804496813830306718519314913357892021236053081999520205845034234999321509626349778124566583046805818245635248146258493319261954068848184464452484294860630161694766632426252314763223711096953694838244823164103962245076754056142874682678357237048956069906527926884558445120466548533785340266466450423396384882577198749536113004942155937355452119261867214782654168856040949282900566168838076376566905107408925105491652229688786769686316525149177014999000666373445461202627807019256987062255409289451947187780043061300218282874258670487484808269485734447782440787341027108248702695238308049109604820139012940246312448001593366702126583176778797529659634725768943265404358892672939506878608306262662632873920873273025479100999321133889778078143367287914487683736864677485287777374035474728716442177678207129645062708809786379281440711925051411480049070556080972292997924414710628522470298706998692276763417735132586029089038757074543680778764223853337006920896163510092335873039865439060718809525575533803647258950073067721225280781794710564811713785574510576910443229254290241494335883960936793213616969542512997310310328044369545019298438208423831212658257405945094269427773071248021769157818357200871705387732560179871330055059113778238417916402808414096238208476373930139307784285545452223675598246662506087542848761041456613622276424059143044555808563181809352304077938916149021162924005150749140684432032303656099548786209991943065644553325471355573653185160117003215506907877167520628815278858971494103209869840830489665243510305024446799317791476591034289491290541203616016956712221408063694059403045521862128799330928562310224184463652890974446401519866231838819624448225907835859140436861930190414589626938789070349821698686969344480862139905345917928266543047982072196341347556465254831437711566784590777971965107724680002935815462676463102242790073136313525220670629511259358744731341864924972827847966445854489629329052620580652485887070208793891344760833446531709392424082493280089157313195413483118209277524868805487339433158675626661221793550511906099929113794456349956273918984590290217131557060962678816733029401984642373904450980280309489759812592520558509735374365568257803136819020071516756938272818188245875417107211808065564480391225045370894226953583821925350756928340956398592655997403913167092900439962759768303752175033608790282956730688622630777297335338536826687345190357097096873223237383004940901232392743187590465263270951784062672648288936468965932191695211063617297570743761480616013311049116922713186094041450148428664236347169828924181804843652305388645598098392738364906854808230142678031439374404318078226787794940062064891512489525165430056344483750467517542070433133724868706332375616452323604819320243775968909147833721795536769926032357151855133910984027390637532807023133017557542693962026294239109453235379101259489649418125636729929670842506675998034562734555985596285122814145825560248417833056452405084500659887559875186013358606249327844877720068422965919455165395629829605916100465789072148420548618304181756045598151680880317830802614459944446779180124321464009836106786834129748725967292587868062230801158220262890143644590023016458236667092655712645599257906223047452356255751117707915120027893809757754685461210173075227992414070263081377929719094614131458020810877381216245398587696973714258818361526050693809269177120873219150058319771133227935723850719406127612918725720994049302502777481566140213274347438819664133300526342290829064009279449248085561311834401618048013570325078363239389215676431596204426128097009441077761306389090712944563940566015592460254542047711861404201552333712705013771210345700095780093892653293857204785765087771496634030035623805957571916093821713122228104658583889435071764319399730126615914238371702844001203994858809962318594724748587765843550770069340992203403787721927283703013808381443941149849717307661629613420591050148142839497006959516769390415579028563569110555473126845714974496353205546779407751840566676372229690903461287068298871042787610900909991604438217945117636208353797161618331243644312678554355508005079861246643977241355021282380267267199149897272485129812872836974892764207928686669701772597944078581559093325085541312999465811185276916524647908191193842332758976995730120981030091710016957187916169422700795289151919125210538918385389593151674005057238174010306210043802430111879777042523280732365751296093724560536800375165961642361477093303912244097528717320679761281204280267392565573056759315126457500478757565318548258214115740304731474925119108356157657320025461096867018903076485313738329126824817411813590328266250825493132114314789533523170439890539285349466428860742683718249024980924794872266336868237995808756370408086556493219054896377855495311673979352707994704523991532975343586905141058640965345141828964744393671828527118435607992858959781765439501130888484191635166732136928608309567445028018003737164580091680829727087156091850386540534366600455049856246873760225570415958002501740953618392876434580036708649540579417200851363571271637683234931342307038212744845014405295416953743819454594565331651409909937227228010196546527262278315121034676861668261314718436100255178632479501500229536954663177395893441314814858346943745239811599546660712059977943634401850783608991089480734196339392593189739409431100421167291201997226266098719270140241058055153151001098049960441472910394510303126641147267368399733150350367427415469926331652704329406752374490750567395089296747791158008643999925648172088474292508215462798560791277686119460862103494055358501344721902445438245210892844094981327170106739664711149318967899776615954881861931769001750279017838246243878738314832795008790264339925770265880058497789846242956603212769458108243481296908409725506710547324713172549971919010395533058470407280816931586260938860191476899441376736214320836073751315743763167546664791867538965715551008506268100051198274868077805926677656541008347785710242501332533915873847610241297947367510011634989778037459300254576098706710921535971151782520142812166475430340751286002402970384286159842898166021434298490889173596821922844691230359043298772318433099141872646746075583187257131388323560158090095941825302077993976484625979018833417938309209658414635744119858782964758509430530081483418217478266037737622529977034687529035173107920832200380808092121643465868179898105042743753857867891863505177175016065318264069288832501359195171785376878658817523664215340109612957630747626480703127573657877623528590571539324845765039443904966680877118991924989338965248523955367958275306141671317579157563866060048399941795487058682092011951549520312945624513154225065748586291616065237966430101726939502822946674896817468211639967949502942840130992359012782504374281925576345332175761622927511105983682715672297786200537229323140828870587494440601162365216277175585030134514714527658418642770717699684354996202575474318119948833858067596923595806221658324640920953506483579358177429030183153512900143214955181774569083887193206977696956577717544991499114313689508361606925396064698933748709429332191856012991085644702562571635055086206892402975896847142836786847354555335834776525361565781899969830686546717364459963431364681954274204904724330646750014426975083223690130838954926370667784065313286648860801295137717208475811577194910123451417749414827735800414326673323796177169656985827858323005052658835022478680506482014445705931973433829238600726016965109032589809099128376522753814935298450994149669338628155680313069810645251927038185158726486917625632394414252161184277691450677184117357143966810056154839524431549448642383842989003998261133224689633465221046925451379692760097196453389553
  • 67. Higher order functions1> Double = fun(X) -> X * 2 end.#Fun<erl_eval.6.111823515>2> Double(2).43> List = [1, 2, 3].[1,2,3]4> lists:map(Double, List).[2,4,6]5> lists:map(fun(X) -> X + 1 end, List).[2,3,4]6> lists:foldl(fun(X, Sum) -> X + Sum end, 0, List).6
  • 68. List comprehensions1> Numbers = [1, 2, 3, 4].[1,2,3,4]2> Double = fun(X) -> X * 2 end.#Fun<erl_eval.6.111823515>3> lists:map(Double, Numbers).[2,4,6,8]4> [Double(X) || X <- Numbers].[2,4,6,8]5> [X || X <- Numbers, X > 1, X < 4].[2,3]6> Basket = [{pencil, 4, 0.25}, {pen, 1, 1.20}, {paper, 2, 1.00}].[{pencil,4,0.25},{pen,1,1.2},{paper,2,1.0}]7> Totals = [{Item, Qty * Price} || {Item, Qty, Price} <- Basket].[{pencil,1.0},{pen,1.2},{paper,2.0}]
  • 69. Message loops-module(doubler).-export([loop/0]).loop() -> receive N -> io:format("~b~n", [N * 2]), loop()end.18> Doubler = spawn(fun doubler:loop/0).<0.87.0>19> Doubler ! 2.4
  • 70. Synchronous messages-module(doubler).-export([loop/0, double/2]).loop() -> receive {Pid, N} -> Pid ! (N * 2), loop()end.double(To, N) -> To ! {self(), N}, receive Result -> Result end.27> Doubler = spawn(fun doubler:loop/0).<0.118.0>28> doubler:double(Doubler, 3).6
  • 71. Monitor & restart-module(monitor).-export([loop/0, start/0]).loop() -> process_flag(trap_exit, true), receive new -> register(doubler, spawn_link(fun doubler:loop/0)), loop(); {EXIT, From, Reason} -> io:format("~p exited: ~p.", [From, Reason]), monitor ! new, loop()end.start() -> register(monitor, spawn(fun monitor:loop/0)), monitor ! new.
  • 72. ProsDesigned for concurrency & fault toleranceFlexibility of dynamic typingLightweight processes with message passing & monitoringBuild scalable applications with the OTP librarySyntax sometimes a little clumsyIntegration with other languages Cons
  • 73. RubyIoPrologScalaErlangClojureHaskell
  • 74. His communication style is often inverted and hard to understand.He seems too small to make a difference, but it quickly becomesapparent that there is more to Yoda than meets the eye.
  • 75. Prefix notationuser=> (+ 2 2)4user=> (- 10 4 1)5user=> (/ 2.0 3)0.6666666666666666user=> (/ 2 3)2/3user=> (count "hello")5user=> (+ (count "hello") (count "clojure"))12
  • 76. Java hiding underneathuser=> (class 1)java.lang.Integeruser=> (class "foo")java.lang.Stringuser=> (class (= 2 2))java.lang.Booleanuser=> (class (/ 1 2))clojure.lang.Ratio
  • 77. Data or code?user=> (1 2 3)java.lang.ClassCastException: java.lang.Integer cannot becast to clojure.lang.IFn (NO_SOURCE_FILE:0)user=> (list 1 2 3)(1 2 3)user=> (class (list 1 2 3))clojure.lang.PersistentListuser=> (1 2 3)(1 2 3)user=> (class (+ 2 2))clojure.lang.PersistentListuser=> (eval (+ 2 2))4
  • 78. Vectors, sets & mapsuser=> (def numbers [1 2 3])(1 2 3)user=> (conj numbers "forty-two")[1 2 3 "forty-two"]user=> (def crew #{:zaphod :trillian :marvin})#user/crewuser=> (clojure.set/union crew #{:ford :zaphod :arthur})#{:arthur :trillian :ford :zaphod :marvin}user=> (def home {:arthur :earth, :ford :betelgeuse, :marvin :sirius})#user/homeuser=> (home :arthur):earthuser=> (:arthur home):earth
  • 79. Defining functionsuser=> (defn answer [] 42)#user/answeruser=> (answer)42user=> (defn treble [a] (* 3 a))#user/trebleuser=> (treble 20)60
  • 80. Destructuring paramsuser=> (def board [[:x :o :x] [:o :x :o] [:o :x :o]])#user/boarduser=> (defn centre [[_ [_ c _] _]] c)#user/centreuser=> (centre board):x
  • 81. Anonymous functionsuser=> (defn treble [a] (* 3 a))#user/trebleuser=> (def numbers [1 2 3])#user/numbersuser=> (map treble numbers)(3 6 9)user=> (map (fn [n] (* 3 n)) numbers)(3 6 9)user=> (map #(* 3 %) numbers)(3 6 9)
  • 82. Recursion: loop & recuruser=> (defn size [v] (if (empty? v) 0 (inc (size (rest v)))))#user/sizeuser=> (size [1 2 3])3user=> (defn size [v] (loop [l v, c 0] (if (empty? l) c (recur (rest l) (inc c)))))
  • 83. Working with sequencesuser=> (def numbers [1 2 3 4])#user/numbersuser=> (every? odd? numbers)falseuser=> (filter odd? numbers)(1 3)user=> (for [x numbers] (* 2 x))(2 4 6 8)user=> (for [x numbers, y numbers] (* x y))(1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16)user=> (for [x numbers, y numbers, :when (odd? x)] (* x y))(1 2 3 4 3 6 9 12)
  • 84. Lazy evaluationuser=> (take 5 (cycle ["I" "am" "what"]))("I" "am" "what" "I" "am")user=> (take 5 (drop 2 (cycle [1 2 3])))(3 1 2 3 1)user=> (->> [1 2 3] (cycle) (drop 2) (take 5))(3 1 2 3 1)user=> (take 5 (iterate inc 1))(1 2 3 4 5)user=> (defn factorial [n] (apply * (take n (iterate inc 1))))#user/factorialuser=> (factorial 5)120
  • 85. Records & protocolsuser=> (defprotocol Shape (area [this]))Shapeuser=> (defrecord Square [width height] Shape (area [this] (* width height)))user.Squareuser=> (defrecord Circle [radius] Shape (area [this] (* (. Math PI) (* radius radius))))user.Circleuser=> (area (Square. 2 3))6user=> (area (Circle. 4))50.26548245743669
  • 86. Macro expansionuser=> (defn unless [test body] (if (not test) body))#user/unlessuser=> (unless true (println "Its a lie!"))Its a lie!niluser=> (defmacro unless [test body] (list if (list not test) body))#user/unlessuser=> (macroexpand (unless condition body))(if (not condition) body)user=> (unless true (println "Its a lie!"))niluser=> (unless false (println "Its true!"))Its true!nil
  • 87. Transactional memoryuser=> (def ford (ref {:name "Ford Prefect", :from "Guildford"}))#user/forduser=> (deref ford){:name "Ford Prefect", :from "Guildford"}user=> @ford{:name "Ford Prefect", :from "Guildford"}user=> (alter ford assoc :from "Betelgeuse")java.lang.IllegalStateException: No transaction running(NO_SOURCE_FILE:0)user=> (dosync (alter ford assoc :from "Betelgeuse")){:name "Ford Prefect", :from "Betelgeuse"}user=> @ford{:name "Ford Prefect", :from "Betelgeuse"}
  • 88. Encapsulation with atoms user=> (def numbers (atom [1 2 3])) #user/numbers user=> numbers #<Atom@7d98d9cf: [1 2 3]> user=> @numbers [1 2 3] user=> (reset! numbers [4 5 6]) [4 5 6] user=> (swap! numbers conj 7) [4 5 6 7]
  • 89. Agents in the background user=> (defn slow-twice [x] (do (Thread/sleep 5000) (* 2 x))) #user/slow-twice user=> (def number (agent 2)) #user/number user=> number #<Agent@4c825cf3: 2> user=> @number 2 user=> (send number slow-twice) #<Agent@4c825cf3: 2> user=> @number 2 user=> @number 4
  • 90. Back to the futuresuser=> (def ultimate-answer (future (do (Thread/sleep 2.4e17) 42)))#user/ultimate-answeruser=> @ultimate-answer42
  • 91. ProsA good lisp implementationAccess to Java ecosystemConcurrency provided by STMPrefix notation can be confusing(((((and all those parens don’t help)))))Some limitations compared to other lisps Cons
  • 92. RubyIoPrologScalaErlangClojureHaskell
  • 93. Haskell represents purity and freedom, but the power comes at aprice. Think Spock from Star Trek. His character has a single-mindedpurity that has endeared him to generations.
  • 94. Type inferencePrelude> :set +tPrelude> 4242it :: IntegerPrelude> "Mostly harmless""Mostly harmless"it :: [Char]Prelude> "black" == "white"Falseit :: BoolPrelude> 1/20.5it :: Double
  • 95. Defining functionsPrelude> let double x = x * 2double :: Num a => a -> aPrelude> double 48Prelude> double 2.55.0Prelude> let times x y = x * ytimes :: Num a => a -> a -> aPrelude> times 5 630
  • 96. Specifying function types module Main where double :: Integer -> Integer double x = 2 * x Prelude> :load main [1 of 1] Compiling Main ( main.hs, interpreted ) Ok, modules loaded: Main. *Main> double 2 4 *Main> double 2.5 <interactive>:1:8: No instance for (Fractional Integer) arising from the literal `2.5
  • 97. Pattern matching & guards module Main where factorial :: Integer -> Integer factorial 0 = 1 factorial x = x * factorial (x - 1) factorial2 :: Integer -> Integer factorial2 x | x > 1 = x * factorial2 (x - 1) | otherwise = 1
  • 98. Tuples & listsPrelude> let zaphod = ("Zaphod", "Beeblebrox", "Betelgeuse", 2)Prelude> let (_, _, _, numberOfHeads) = zaphodPrelude> let numbers = [1, 2, 3, 4]Prelude> let (head:tail) = numbersPrelude> head1Prelude> tail[2,3,4]Prelude> 1:[2, 3][1,2,3]Prelude> [1, "two"]<interactive>:1:2: No instance for (Num [Char]) arising from the literal `1 Possible fix: add an instance declaration for (Num [Char]) In the expression: 1 In the expression: [1, "two"] In an equation for `it: it = [1, "two"]
  • 99. Ranges & sequencesPrelude> [1..5][1,2,3,4,5]Prelude> [2, 4 .. 10][2,4,6,8,10]Prelude> [0, 0.5 .. 2][0.0,0.5,1.0,1.5,2.0]Prelude> take 5 [1 ..][1,2,3,4,5]
  • 100. List comprehensionsPrelude> let numbers = [1,2,3]Prelude> [x * 2 | x <- [1, 2, 3]][2,4,6]Prelude> [[x, y] | x <- numbers, y <- numbers][[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]Prelude> [[x, y] | x <- numbers, y <- numbers, x < y][[1,2],[1,3],[2,3]]Prelude> let more_numbers = [4,5]Prelude> [(x, y, x * y) | x <- numbers, y <- more_numbers, x < y][(1,4,4),(1,5,5),(2,4,8),(2,5,10),(3,4,12),(3,5,15)]
  • 101. Function curryingPrelude> 4 * 520Prelude> (*) 4 520Prelude> :t (*)(*) :: Num a => a -> a -> aPrelude> let double = (* 2)Prelude> :t doubledouble :: Integer -> IntegerPrelude> double 36
  • 102. Higher order functionsPrelude> (x -> 2 * x) 510Prelude> map (x -> 2 * x) [1, 2, 3][2,4,6]Prelude> map (* 2) [1, 2, 3][2,4,6]Prelude> filter odd [1, 2, 3, 4][1,3]Prelude> foldl (+) 0 [1, 2, 3, 4]10
  • 103. Type classesclass Eq a where (==), (/=) :: a -> a -> Bool -- Minimal complete definition: -- x/=y x==y (==) or (/=) = not(x==y) = not(x/=y)*Main> :info Integerdata Integer = integer-gmp:GHC.Integer.Type.S# GHC.Prim.Int# | integer-gmp:GHC.Integer.Type.J# GHC.Prim.Int#GHC.Prim.ByteArray# -- Defined in integer-gmp:GHC.Integer.Typeinstance Enum Integer -- Defined in GHC.Numinstance Eq Integer -- Defined in GHC.Classesinstance Integral Integer -- Defined in GHC.Realinstance Num Integer -- Defined in GHC.Numinstance Ord Integer -- Defined in GHC.Classesinstance Read Integer -- Defined in GHC.Readinstance Real Integer -- Defined in GHC.Realinstance Show Integer -- Defined in GHC.Num
  • 104. User-defined typesmodule Main where data Shape = Circle Float | Rectangle Float Float deriving show area :: Shape -> Float area (Circle r) = pi * r ^ 2 area (Rectangle x y) = x * y*Main> let circle = Circle 10*Main> let rect = Rectangle 6 7*Main> area circle314.15927*Main> area rect42.0*Main> [circle, rect][Circle 10.0,Rectangle 6.0 7.0]
  • 105. Record syntaxmodule Main where data Shape = Circle {radius :: Float} | Rectangle {width :: Float, height :: Float} deriving Show area :: Shape -> Float area (Circle r) = pi * r ^ 2 area (Rectangle x y) = x * y*Main> let circle = Circle 10*Main> let rect = Rectangle 6 7*Main> [circle, rect][Circle {radius = 10.0},Rectangle {width = 6.0, height = 7.0}]
  • 106. MonadsA monad is a construction that, given an underlying typesystem, embeds a corresponding type system (calledthe monadic type system) into it (that is, each monadictype acts as the underlying type). This monadic typesystem preserves all significant aspects of theunderlying type system, while adding features particularto the monad.Monads must obey the following rules:• (return x) >>= f ≡ f x• m >>= return ≡ m• (m >>= f) >>= g ≡ m >>= ( x -> (f x >>= g) )
  • 107. MonadsA monad is a construction that, given an underlying typesystem, embeds a corresponding type system (calledthe monadic type system) into it (that is, each monadictype acts as the underlying type). This monadic typesystem preserves all significant aspects of theunderlying type system, while adding features particularto the monad.Monads must obey the following rules:• (return x) >>= f ≡ f x• m >>= return ≡ m• (m >>= f) >>= g ≡ m >>= ( x -> (f x >>= g) )
  • 108. The maybe monaddata Maybe a = Nothing | Just aPrelude> case (html doc) of Nothing -> Nothing Just x -> case body x of Nothing -> Nothing Just y -> paragraph 2 yinstance Monad Maybe where return = Just Nothing >>= f = Nothing (Just x) >>= f = f xPrelude> Just someWebPage >>= html >>= body >>= paragraph >>= return
  • 109. ProsPure functional language with no side effectsStrong typing with powerful type inferenceLaziness reduces need for recursionIdeal for learning the functional paradigm Inflexibility and lack of compromiseSmall community outside academiaSteep learning curve (especially monads!) Cons
  • 110. What I learned fromSeven Languagesin Seven Weeks
  • 111. Functional styledef total_price(widgets) total = 0 widgets.each do |widget| if widget.red? total += widget.price end end totalenddef total_price(widgets) widgets.select{|w| w.red?}.map{|w| w.price}.reduce(&:+)end
  • 112. JVM or standalone?• Access to Java libraries• Deployment environments• Escape route for Java developers• Limitations (eg tail recursion)
  • 113. Know what’s out there• Languages• Features • First-class functions • List comprehensions • Pattern matching • Lazy evaluation
  • 114. Dealing with concurrency • Immutability • Coroutines • Actors • Futures • Software Transactional Memory
  • 115. Creditshttp://pragprog.com/book/btlang/seven-languages-in-seven-weekshttp://www.flickr.com/photos/oskay/472097903/http://www.flickr.com/photos/clairedancer/273214248