Programming Paradigms & Constructs Nicolas Demengel 2011, July 7th www.xebia.fr / blog.xebia.fr 1
Inspiration  Ruby, Io, Prolog, Scala, Erlang, Clojure, Haskell  Presentation of those languages' main features  Exercises  Good start... but not enough! www.xebia.fr / blog.xebia.fr 2
Agenda  Talk ▶ Definitions and Examples ▶ Laptops allowed! (and encouraged)  Hands On! ▶ Choose one or several exercises to solve  Retrospective ▶ Comparison of solutions to some exercises ▶ Feelings about this or that feature/language www.xebia.fr / blog.xebia.fr 3
Material  Image for VirtualBox  Under your home: ▶ A folder for each language ▶ Simple examples of the language features ▶ HOWTO: instructions for compiling or interpreting the examples ▶ Solved exercises ▶ Unresolved problems www.xebia.fr / blog.xebia.fr 4
Describing A Language  Paradigm ▶ Style, concepts, abstractions, computation  Typing ▶ Constraints applied to values ▶ Operations provided for kinds of values  Constructs ▶ Decision constructs, data structures, advanced features  Syntax ▶ Rules, expressiveness  Ecosystem, … ▶ Out of scope www.xebia.fr / blog.xebia.fr 5
The Four Main Paradigms (1/4)  Imperative (Procedural) ▶ “First do this, next do that” => recipe ▶ Control structures and procedures ▶ Hard to organize ▶ Sensitive to small changes  Functional ▶ Theory of functions ▶ Given the same input, a function will produce the same output ▶ Immutable values, no side effect ▶ Higher-order functions ▶ Computation-oriented, suitable for data transformation ▶ Sometimes allows for proof of correctness www.xebia.fr / blog.xebia.fr 6
The Four Main Paradigms (2/4)  Logic ▶ Build a knowledge base with facts and rules ▶ Query the program and let it infer solutions ▶ Adapted to knowledge extraction => IA  Object-Oriented ▶ Grouping of data and behavior ▶ Message passing between objects ▶ Inheritance and polymorphism ▶ Domain-oriented, adapted to large and evolutive programs www.xebia.fr / blog.xebia.fr 7
The Four Main Paradigms (3/4)  A word about Prototype-based Programming ▶ A flavor of OO ▶ No classes, but still allows for inheritance via prototypes ▶ Naively put: a given object may be: › an “instance” of another object (having it as prototype) › a “class” of another object (being one of its prototypes) ▶ Very powerful! Example: › a publication › a newspaper › Le Monde › the July 7th edition of Le Monde › my copy of the July 7th edition of Le Monde › ... www.xebia.fr / blog.xebia.fr 8
The Four Main Paradigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C www.xebia.fr / blog.xebia.fr 9
The Four Main Paradigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C Source: Pulp Fiction. Dir. Quentin Tarentino. Miramax Films. 1994. Film www.xebia.fr / blog.xebia.fr 10
The Four Main Paradigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C Source: Pulp Fiction. Dir. Quentin Tarentino. Miramax Films. 1994. Film ▶ You can write OO programs with a Functional language and vice-versa ▶ Some languages mixes paradigms (C++, Scala, ...)  There are many other paradigms ▶ Most of them are flavors of the four main ones www.xebia.fr / blog.xebia.fr 11
The Main Languages That We Will See (1/2)  Erlang ▶ 1986, functional, dynamic, concurrent, fault-tolerant ▶ “Ericsson Language”  Haskell ▶ 1990, purely functional, static, lazy, “standard”  Ruby ▶ 1995, object-oriented and functional, dynamic www.xebia.fr / blog.xebia.fr 12
The Main Languages That We Will See (2/2)  Scala ▶ 2003, object-oriented and functional, static, concurrent, on the JVM  Clojure ▶ 2007, functional, dynamic (code as data), concurrent, on the JVM ▶ Lisp dialect www.xebia.fr / blog.xebia.fr 13
A Word About Prolog (1/3)  What we are used to: assignment ▶ X = 10 assign 10 to variable X  Prolog: Unification ▶ X = 10 given an unknown X, make 10 and X match (binding) ▶ X = 10 given a yet known X, does it match 10? (matching) www.xebia.fr / blog.xebia.fr 14
A Word About Prolog (1/3)  What we are used to: assignment ▶ X = 10 assign 10 to variable X  Prolog: Unification ▶ X = 10 given an unknown X, make 10 and X match (binding) ▶ X = 10 given a yet known X, does it match 10? (matching) ▶ Basics of logic programming: author(what_mad_universe, frederic_brown). author(the_eyre_affair, jasper_fforde). genre(what_mad_universe, science_fiction). genre(the_eyre_affair, science_fiction). genre(the_eyre_affair, comic_novel). writes_genre(Author, Genre) :- author(Book, Author), genre(Book, Genre). www.xebia.fr / blog.xebia.fr 15
A Word About Prolog (2/3) |?- writes_genre(Who, science_fiction). Who = frederic_brown ? Who = jasper_fforde yes |?- writes_genre(frederic_brown, What). What = science_fiction yes |?- writes_genre(jasper_fforde, comic_novel). true yes |?- writes_genre(frederic_brown, comic_novel). no www.xebia.fr / blog.xebia.fr 16
A Word About Prolog (3/3)  Pattern matching smallest([LonelyNumber], LonelyNumber). smallest([Head|Tail], SmallestSoFar) :- smallest(Tail, TailSmallest), SmallestSoFar is min(Head, TailSmallest). smallest([3, 1, 7], S). % S = 1 % more matching smallest([], -1). % empty list smallest(_, -1). % anything smallest([_|[SecondItem|_]], -1) :- SecondItem > 5, % guard % ... www.xebia.fr / blog.xebia.fr 17
Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell www.xebia.fr / blog.xebia.fr 18
Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell  Dynamic ▶ Type-checking at run-time ▶ JavaScript, Ruby, Python, Clojure www.xebia.fr / blog.xebia.fr 19
Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell  Dynamic ▶ Type-checking at run-time ▶ JavaScript, Ruby, Python, Clojure  “Strong” / “Weak” ▶ What happens when types collide? › 5 + 'a string' ▶ Can you subvert the type system? › int an_int = (int) some_bytes; ▶ Few languages are totally “strongly” or “weakly” typed www.xebia.fr / blog.xebia.fr 20
Typing (2/6)  Type Inference ▶ Deduction of the type of an expression at compile time ▶ Less boiler-plate code: eases writing and reading ▶ Haskell: double x = x * 2 -- (Num a) => a -> a double :: Integer -> Integer double x = x * 2 -- Integer -> Integer ▶ Scala: val ints = List(1, 2, 3) // List[Int] def addNumbers(first: Int, second: Int) = first + second // equivalent to def addNumbers(first: Int, second: Int): Int = first + second www.xebia.fr / blog.xebia.fr 21
Typing (2/6)  Type Inference ▶ Deduction of the type of an expression at compile time ▶ Less boiler-plate code: eases writing and reading ▶ Java: List<Integer> ints = new ArrayList<Integer>(); ints.add(1); ints.add(2); ints.add(3); // Java 7 List<Integer> ints = new ArrayList<>(); // java.util.Arrays, unmodifiable List<Integer> ints = asList(1, 2, 3); // Guava, modifiable List<Integer> ints = newArrayList(1, 2, 3); www.xebia.fr / blog.xebia.fr 22
Typing (3/6)  Duck Typing ▶ Example (JS): var car = { startEngine: function() { /* vroom */ } } var blender = { startEngine: function() { /* ouch my fingers! */ } } var thingsWithEngine = [car, blender]; for (thing in thingsWithEngine) { thing.startEngine(); } ▶ If it walks like a duck and quacks like a duck, it’s a duck. www.xebia.fr / blog.xebia.fr 23
Typing (3/6)  Duck Typing ▶ Example (JS): var car = { startEngine: function() { /* vroom */ } } var blender = { startEngine: function() { /* ouch my fingers! */ } } var thingsWithEngine = [car, blender]; for (thing in thingsWithEngine) { thing.startEngine(); } ▶ If it walks like a duck and quacks like a duck, it’s a duck. And if it weighs the same as a duck... www.xebia.fr / blog.xebia.fr 24
Typing (3/6) A witch! Source: Monthy Python and the Holy Grail. Dir. Terry Gillian, Terry Jones. EMI Films. 1974. Film www.xebia.fr / blog.xebia.fr 25
Typing (4/6)  Structural Typing: Type-safe Duck Typing ▶ Example (Scala): class Car { def startEngine = println("vroom") } class Blender { def startEngine = println("ouch my fingers!") } type T = {def startEngine} val thingsWithEngine = List[T](new Car(), new Blender()) thingsWithEngine.foreach(_.startEngine) www.xebia.fr / blog.xebia.fr 26
Typing (5/6)  Mixins ▶ Interfaces with partial implementations › Ruby: module Printable def print_me print self.my_representation end end class Thing extend OtherThing # only one extension include Printable include Xxx # several inclusions def my_representation # ... end end www.xebia.fr / blog.xebia.fr 27
Typing (5/6)  Mixins ▶ Interfaces with partial implementations › Scala: trait Printable { def printMe() = println(myRepresentation) def myRepresentation(): String } class Thing extends OtherThing with Printable with Xxx { def myRepresentation() = // ... } www.xebia.fr / blog.xebia.fr 28
Typing (6/6)  Out of scope but still interesting: ▶ Haskell's ad-hoc polymorphism › type classes › != subtype polymorphism or parametric polymorhism › somehow equivalent to Java interfaces www.xebia.fr / blog.xebia.fr 29
A Word About Dynamic Languages  Concision, productivity ▶ No need to declare value types  Meta-programming ▶ Ruby, Python, Groovy: message interception (method_missing) ▶ Io, Clojure: Deferred argument evaluation ▶ Perfect for DSL  Downside: safety ▶ Test it! www.xebia.fr / blog.xebia.fr 30
Types we don't have in Java (1/5)  Symbols ▶ Sometimes called atoms or keywords: Prolog, Erlang ▶ Allows for naming things, for conveying meaning ▶ Clearer and more efficient than using strings or ints › Ruby: link_to("View Article", :controller => "articles", :action => "show") › Prolog: friend(laurel, hardy) › Clojure: (def product {:name "laser", :price 15}) › ... www.xebia.fr / blog.xebia.fr 31
Types we don't have in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r www.xebia.fr / blog.xebia.fr 32
Types we don't have in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r val LogEntry(totalTime, viewTime, dbTime, responseCode, uri) = line // result totalTime: String = 100 viewTime: String = 25 dbTime: String = 75 responseCode: String = 200 uri: String = "" www.xebia.fr / blog.xebia.fr 33
Types we don't have in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r val LogEntry(totalTime, viewTime, dbTime, responseCode, uri) = line // result totalTime: String = 100 viewTime: String = 25 dbTime: String = 75 responseCode: String = 200 uri: String = "" Source.fromFile(logFile).getLines.collect { _ match { case LogEntry(tt, vt, dbt, rc, uri) => println(rc) case OtherPattern(var1, var2) => // … case _ => } } www.xebia.fr / blog.xebia.fr 34
Types we don't have in Java (3/5)  XML ▶ Scala: val things = <things> <movie genre="action">Pirates of the Caribbean</movie> <movie genre="fairytale">Edward Scissorhands</movie> <book genre={ genre }>{ title }</book> </things> things "movie" (things "@genre")(1).text things "movie" find { node: Node => (node "@genre").text == "action" } www.xebia.fr / blog.xebia.fr 35
Types we don't have in Java (3/5)  XML ▶ Scala: val things = <things> <movie genre="action">Pirates of the Caribbean</movie> <movie genre="fairytale">Edward Scissorhands</movie> <book genre={ genre }>{ title }</book> </things> things "movie" (things "@genre")(1).text things "movie" find { node: Node => (node "@genre").text == "action" } (things "_").foreach { _ match { case <movie>{ title }</movie> => println(title) case <book>{ _ }</book> => println("book") case _ => } } www.xebia.fr / blog.xebia.fr 36
Types we don't have in Java (4/5)  Ranges ▶ Ruby: myArray[1..3] (1..3).to_a (1..21).each{|n| print n} ▶ Scala: 0 to 10 for (i <- 0 until 10) (0 until 10 by 5).start //.end .step ▶ Haskell: [1..5] [1,1.5..5] -- 1, 1.5, 2, 2.5, ... ▶ Clojure: (range 1 21) ; actually this produces a sequence, more on that later www.xebia.fr / blog.xebia.fr 37
Types we don't have in Java (4/5)  Ranges ▶ Ruby: myArray[1..3] (1..3).to_a (1..21).each{|n| print n} ▶ Scala: 0 to 10 for (i <- 0 until 10) (0 until 10 by 5).start //.end .step ▶ Haskell: [1..5] [1,1.5..5] -- 1, 1.5, 2, 2.5, ... ▶ Clojure: (range 1 21) ; actually this produces a sequence, more on that later  Tuples › (x, y) = (1, 2) {x, y} = {1, 2} www.xebia.fr / blog.xebia.fr 38
Types we don't have in Java (5/5) Functions! www.xebia.fr / blog.xebia.fr 39
Higher-Order Functions  Produces or consumes other functions ▶ Ruby: def do_something(x, y) z = # ... lambda { |w| z + w } end ▶ Haskell: applyToArg f x = f(x)  Partial Application (~Currying) ▶ Erlang: prod x y = x * y double = prod 2 triple = prod 3 www.xebia.fr / blog.xebia.fr 40
Functions and Sequences  Sequence: abstraction for “iterable things” ▶ Scala: persons foreach { p => println(p.name) } persons map { _.name } persons filter { _.female } ▶ Clojure: => (def m1 {:car 2, :doll 5, :table 1}) => (def m2 {:bike 6, :doll 3}) => (def m (merge-with + m1 m2)) {:bike 6, :car 2, :doll 8, :table 1} => (reduce (fn [acc [_ qty]] (+ acc qty)) 0 m) 17 www.xebia.fr / blog.xebia.fr 41
Functional Programming Concepts  Immutability  Nil ▶ Empty list ▶ Nil.size(), count(nil)  Optional result ▶ Scala: Haskell: map.get(aKey) match { case aValue of case Some(x) => println(x) Just x -> ... case None => println("Nope") Nothing -> ... } www.xebia.fr / blog.xebia.fr 42
List Comprehension  Builds a list from other list(s) ▶ Erlang: [ {X, Y} || X <- lists:seq(1, 4), X < 3, Y <- [5, 6] ]. % [{1,5},{1,6},{2,5},{2,6}] ▶ Haskell: [ (x, y) | x <- [1..4], x < 3, y <- [5, 6] ] ▶ Clojure: (for [ x [1,2,3,4], y [5,6], :when (< x 3)] (* x y)) ▶ Scala: for (x <- 1 to 2; y <- List(5, 6); if x < 3) yield (x, y) www.xebia.fr / blog.xebia.fr 43
Lazy evaluation  Delays the evaluation of an expression until its value is required  Increases performance  Allows for infinite sequences ▶ Haskell: take 4 (dropWhile (< 34098) [0, 0.5 ..]) -- [34098.0, 34098.5, 34099.0, 34099.5] zip (take 5 (iterate (2*) 10)) (take 5 (iterate (/2) 10)) -- [(10, 10.0), (20, 5.0), (40, 2.5), (80, 1.25), (160, 0.625)] ▶ Clojure => (take 5 (interpose :and (cycle [:x :k :e]))) (:x :and :k :and :e) www.xebia.fr / blog.xebia.fr 44
Lazy evaluation  An alternative to recursion ▶ Fibonacci: (defn fib-pair [[a b]] [b (+ a b)]) (defn fibonacci [] (map first (iterate fib-pair [1 1]))) (take 10 (fibonacci)) ; (1 1 2 3 5 8 13 21 34 55) www.xebia.fr / blog.xebia.fr 45
Concurrency  The Problem ▶ Shared resources ▶ Interactions between threads/processes ▶ Coordination ▶ Failures www.xebia.fr / blog.xebia.fr 46
Actors  An independent computational entity having a mailbox  It can send/receive messages (a-)synchronously ▶ Erlang (synchronous example): loop() -> receive {From, "voiture"} -> From ! "car", loop(); {From, _} -> From ! "unknown word", loop() end. Service = spawn(fun loop/0). Service ! {self(), "voiture"}, receive Translation -> Translation end. www.xebia.fr / blog.xebia.fr 47
Actors  An independent computational entity having a mailbox  It can send/receive messages (a-)synchronously ▶ Scala (asynchronous example): class Service extends Actor { def act() = { loop { react { case "voiture" => println("car") case _ => println("unknown word") } } } } val service = new Service() service.start service ! "voiture" www.xebia.fr / blog.xebia.fr 48
Software Transactional Memory  STM ▶ Same approach as for databases (ACID) ▶ Wrap code accessing shared resources in a transaction ▶ The transaction sees values as they were when opening it › Clojure: (def i (ref 0)) (def j (ref 0)) (dosync (alter i inc) (alter j dec)) – But also, in a nutshell: Uncoordinated Coordinated Synchronous Atom Reference (ref) Asynchronous Agent www.xebia.fr / blog.xebia.fr 49
Let it Crash!  Erlang philosophy  Cheap processes instead of threads  Monitor your processes  Make them restart on failure  Refer to the “library” example loop() -> process_flag(trap_exit, true), receive new -> register(revolver, spawn_link(fun russian_roulette_loop/0)), loop(); {'EXIT', From, Reason} -> self() ! new, loop() end. www.xebia.fr / blog.xebia.fr 50
Questions? www.xebia.fr / blog.xebia.fr 51
Exercises 1. Shopping Cart  Represent a catalog in the form of a list of tuples (article, quantity, price)  Write a function that returns the price of an article when present in the catalog or nothing/nil (depending on the language) otherwise  Using recursion, write a function that computes the total value of the catalog  Write a function that feeds a cart with items from the catalog until: ▶ either a maximum amount is reached for the cart value ▶ or the catalog is empty Note: It might be simpler to represent the cart as a list of tuples (article, price) at first (with the same article occuring serveral times).  Amends your function so that it also returns the catalog minus the items that are in the cart  Using fold/reduce (depending on the language), writes a function that computes the total value of the cart  Using a list comprehension, write a function that takes a cart and returns it with a given tax applied to its items  Interesting candidates are: Erlang, Haskell, Clojure and Scala www.xebia.fr / blog.xebia.fr 52
Exercises 2. Tic-Tac-Toe  Write a pogram that accepts a tic-tac-toe board and returns whether there is a winner and, if it is the case, which one.  Depending on the language you choose, try to use the most different functional constructs you can think of: ▶ list processing with functions ▶ list comprehensions ▶ pattern matching and data deconstruction ▶ ...  Should you finish the first part early, modify your program so that it tells when there is a tie.  Interesting candidates are: Scala, Clojure, Erlang, Haskell  Alternatively, solve the problem with Prolog www.xebia.fr / blog.xebia.fr 53
Exercises 3. Erlang: Chat  The aim of this exercise is to write a chat application allowing for discussing between two terminals, based on the "translate_service", "russian_roulette" and "library" examples.  You can find template files for a server, a supervisor and a client.  The server will be in charge to log in clients and dispatch their messages. It will be built with Erlang OTP's generic server feature.  The supervisor will be in charge to restart the server should a crash occur.  The client will spawn a process when the user requests a connection to the server, so that this underlying process can handle messages from the server while the user use the console process to give orders to the client. www.xebia.fr / blog.xebia.fr 54
Exercises 4. Reverse Dependency Tree  Using Scala, write a program that can scan a local Maven repository for POM files and build a reverse dependency tree for a given module.  Use actors to load and parse files concurrently, and then send pieces of dependency model to a collecting actor.  Use Scala's XML capabilities to read POM files www.xebia.fr / blog.xebia.fr 55
Exercises 5. The Sleeping Barber  A barber has one barber chair and a waiting room with a number of chairs in it.  When the barber finishes cutting a customer's hair, he dismisses the customer and then goes to the waiting room to see if there are other customers waiting: ▶ if there are, he brings one of them back to the chair and cuts his or her hair, ▶ if there are no other customers waiting, he returns to his chair and sleeps in it.  Each customer, when he arrives, looks to see what the barber is doing: ▶ if the barber is sleeping, then he wakes him up and sits in the chair, ▶ if the barber is cutting hair, then he goes to the waiting room: › if there is a free chair in the waiting room, he sits in it and waits his turn, › if there is no free chair, then the customer leaves.  Write a program that print events occurring in the shop: customer arrival and departure (and why), barber state (cutting hair, sleeping), etc...  Use the following durations: a hair cut last 100 to 500 ms, a customer enters the shop every 1 to 450 ms. Stop sending customers after the 20th one. www.xebia.fr / blog.xebia.fr 56

XKE - Programming Paradigms & Constructs

  • 1.
    Programming Paradigms &Constructs Nicolas Demengel 2011, July 7th www.xebia.fr / blog.xebia.fr 1
  • 2.
    Inspiration  Ruby, Io,Prolog, Scala, Erlang, Clojure, Haskell  Presentation of those languages' main features  Exercises  Good start... but not enough! www.xebia.fr / blog.xebia.fr 2
  • 3.
    Agenda  Talk ▶ Definitions and Examples ▶ Laptops allowed! (and encouraged)  Hands On! ▶ Choose one or several exercises to solve  Retrospective ▶ Comparison of solutions to some exercises ▶ Feelings about this or that feature/language www.xebia.fr / blog.xebia.fr 3
  • 4.
    Material  Image forVirtualBox  Under your home: ▶ A folder for each language ▶ Simple examples of the language features ▶ HOWTO: instructions for compiling or interpreting the examples ▶ Solved exercises ▶ Unresolved problems www.xebia.fr / blog.xebia.fr 4
  • 5.
    Describing A Language Paradigm ▶ Style, concepts, abstractions, computation  Typing ▶ Constraints applied to values ▶ Operations provided for kinds of values  Constructs ▶ Decision constructs, data structures, advanced features  Syntax ▶ Rules, expressiveness  Ecosystem, … ▶ Out of scope www.xebia.fr / blog.xebia.fr 5
  • 6.
    The Four MainParadigms (1/4)  Imperative (Procedural) ▶ “First do this, next do that” => recipe ▶ Control structures and procedures ▶ Hard to organize ▶ Sensitive to small changes  Functional ▶ Theory of functions ▶ Given the same input, a function will produce the same output ▶ Immutable values, no side effect ▶ Higher-order functions ▶ Computation-oriented, suitable for data transformation ▶ Sometimes allows for proof of correctness www.xebia.fr / blog.xebia.fr 6
  • 7.
    The Four MainParadigms (2/4)  Logic ▶ Build a knowledge base with facts and rules ▶ Query the program and let it infer solutions ▶ Adapted to knowledge extraction => IA  Object-Oriented ▶ Grouping of data and behavior ▶ Message passing between objects ▶ Inheritance and polymorphism ▶ Domain-oriented, adapted to large and evolutive programs www.xebia.fr / blog.xebia.fr 7
  • 8.
    The Four MainParadigms (3/4)  A word about Prototype-based Programming ▶ A flavor of OO ▶ No classes, but still allows for inheritance via prototypes ▶ Naively put: a given object may be: › an “instance” of another object (having it as prototype) › a “class” of another object (being one of its prototypes) ▶ Very powerful! Example: › a publication › a newspaper › Le Monde › the July 7th edition of Le Monde › my copy of the July 7th edition of Le Monde › ... www.xebia.fr / blog.xebia.fr 8
  • 9.
    The Four MainParadigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C www.xebia.fr / blog.xebia.fr 9
  • 10.
    The Four MainParadigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C Source: Pulp Fiction. Dir. Quentin Tarentino. Miramax Films. 1994. Film www.xebia.fr / blog.xebia.fr 10
  • 11.
    The Four MainParadigms (4/4)  A language is not always tied to a given paradigm ▶ You can write OO or Functional programs in C Source: Pulp Fiction. Dir. Quentin Tarentino. Miramax Films. 1994. Film ▶ You can write OO programs with a Functional language and vice-versa ▶ Some languages mixes paradigms (C++, Scala, ...)  There are many other paradigms ▶ Most of them are flavors of the four main ones www.xebia.fr / blog.xebia.fr 11
  • 12.
    The Main LanguagesThat We Will See (1/2)  Erlang ▶ 1986, functional, dynamic, concurrent, fault-tolerant ▶ “Ericsson Language”  Haskell ▶ 1990, purely functional, static, lazy, “standard”  Ruby ▶ 1995, object-oriented and functional, dynamic www.xebia.fr / blog.xebia.fr 12
  • 13.
    The Main LanguagesThat We Will See (2/2)  Scala ▶ 2003, object-oriented and functional, static, concurrent, on the JVM  Clojure ▶ 2007, functional, dynamic (code as data), concurrent, on the JVM ▶ Lisp dialect www.xebia.fr / blog.xebia.fr 13
  • 14.
    A Word AboutProlog (1/3)  What we are used to: assignment ▶ X = 10 assign 10 to variable X  Prolog: Unification ▶ X = 10 given an unknown X, make 10 and X match (binding) ▶ X = 10 given a yet known X, does it match 10? (matching) www.xebia.fr / blog.xebia.fr 14
  • 15.
    A Word AboutProlog (1/3)  What we are used to: assignment ▶ X = 10 assign 10 to variable X  Prolog: Unification ▶ X = 10 given an unknown X, make 10 and X match (binding) ▶ X = 10 given a yet known X, does it match 10? (matching) ▶ Basics of logic programming: author(what_mad_universe, frederic_brown). author(the_eyre_affair, jasper_fforde). genre(what_mad_universe, science_fiction). genre(the_eyre_affair, science_fiction). genre(the_eyre_affair, comic_novel). writes_genre(Author, Genre) :- author(Book, Author), genre(Book, Genre). www.xebia.fr / blog.xebia.fr 15
  • 16.
    A Word AboutProlog (2/3) |?- writes_genre(Who, science_fiction). Who = frederic_brown ? Who = jasper_fforde yes |?- writes_genre(frederic_brown, What). What = science_fiction yes |?- writes_genre(jasper_fforde, comic_novel). true yes |?- writes_genre(frederic_brown, comic_novel). no www.xebia.fr / blog.xebia.fr 16
  • 17.
    A Word AboutProlog (3/3)  Pattern matching smallest([LonelyNumber], LonelyNumber). smallest([Head|Tail], SmallestSoFar) :- smallest(Tail, TailSmallest), SmallestSoFar is min(Head, TailSmallest). smallest([3, 1, 7], S). % S = 1 % more matching smallest([], -1). % empty list smallest(_, -1). % anything smallest([_|[SecondItem|_]], -1) :- SecondItem > 5, % guard % ... www.xebia.fr / blog.xebia.fr 17
  • 18.
    Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell www.xebia.fr / blog.xebia.fr 18
  • 19.
    Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell  Dynamic ▶ Type-checking at run-time ▶ JavaScript, Ruby, Python, Clojure www.xebia.fr / blog.xebia.fr 19
  • 20.
    Typing (1/6)  Static ▶ Type-checking at compile-time ▶ C, Java, Scala, Erlang, Haskell  Dynamic ▶ Type-checking at run-time ▶ JavaScript, Ruby, Python, Clojure  “Strong” / “Weak” ▶ What happens when types collide? › 5 + 'a string' ▶ Can you subvert the type system? › int an_int = (int) some_bytes; ▶ Few languages are totally “strongly” or “weakly” typed www.xebia.fr / blog.xebia.fr 20
  • 21.
    Typing (2/6)  TypeInference ▶ Deduction of the type of an expression at compile time ▶ Less boiler-plate code: eases writing and reading ▶ Haskell: double x = x * 2 -- (Num a) => a -> a double :: Integer -> Integer double x = x * 2 -- Integer -> Integer ▶ Scala: val ints = List(1, 2, 3) // List[Int] def addNumbers(first: Int, second: Int) = first + second // equivalent to def addNumbers(first: Int, second: Int): Int = first + second www.xebia.fr / blog.xebia.fr 21
  • 22.
    Typing (2/6)  TypeInference ▶ Deduction of the type of an expression at compile time ▶ Less boiler-plate code: eases writing and reading ▶ Java: List<Integer> ints = new ArrayList<Integer>(); ints.add(1); ints.add(2); ints.add(3); // Java 7 List<Integer> ints = new ArrayList<>(); // java.util.Arrays, unmodifiable List<Integer> ints = asList(1, 2, 3); // Guava, modifiable List<Integer> ints = newArrayList(1, 2, 3); www.xebia.fr / blog.xebia.fr 22
  • 23.
    Typing (3/6)  DuckTyping ▶ Example (JS): var car = { startEngine: function() { /* vroom */ } } var blender = { startEngine: function() { /* ouch my fingers! */ } } var thingsWithEngine = [car, blender]; for (thing in thingsWithEngine) { thing.startEngine(); } ▶ If it walks like a duck and quacks like a duck, it’s a duck. www.xebia.fr / blog.xebia.fr 23
  • 24.
    Typing (3/6)  DuckTyping ▶ Example (JS): var car = { startEngine: function() { /* vroom */ } } var blender = { startEngine: function() { /* ouch my fingers! */ } } var thingsWithEngine = [car, blender]; for (thing in thingsWithEngine) { thing.startEngine(); } ▶ If it walks like a duck and quacks like a duck, it’s a duck. And if it weighs the same as a duck... www.xebia.fr / blog.xebia.fr 24
  • 25.
    Typing (3/6) A witch! Source: Monthy Python and the Holy Grail. Dir. Terry Gillian, Terry Jones. EMI Films. 1974. Film www.xebia.fr / blog.xebia.fr 25
  • 26.
    Typing (4/6)  StructuralTyping: Type-safe Duck Typing ▶ Example (Scala): class Car { def startEngine = println("vroom") } class Blender { def startEngine = println("ouch my fingers!") } type T = {def startEngine} val thingsWithEngine = List[T](new Car(), new Blender()) thingsWithEngine.foreach(_.startEngine) www.xebia.fr / blog.xebia.fr 26
  • 27.
    Typing (5/6)  Mixins ▶ Interfaces with partial implementations › Ruby: module Printable def print_me print self.my_representation end end class Thing extend OtherThing # only one extension include Printable include Xxx # several inclusions def my_representation # ... end end www.xebia.fr / blog.xebia.fr 27
  • 28.
    Typing (5/6)  Mixins ▶ Interfaces with partial implementations › Scala: trait Printable { def printMe() = println(myRepresentation) def myRepresentation(): String } class Thing extends OtherThing with Printable with Xxx { def myRepresentation() = // ... } www.xebia.fr / blog.xebia.fr 28
  • 29.
    Typing (6/6)  Outof scope but still interesting: ▶ Haskell's ad-hoc polymorphism › type classes › != subtype polymorphism or parametric polymorhism › somehow equivalent to Java interfaces www.xebia.fr / blog.xebia.fr 29
  • 30.
    A Word AboutDynamic Languages  Concision, productivity ▶ No need to declare value types  Meta-programming ▶ Ruby, Python, Groovy: message interception (method_missing) ▶ Io, Clojure: Deferred argument evaluation ▶ Perfect for DSL  Downside: safety ▶ Test it! www.xebia.fr / blog.xebia.fr 30
  • 31.
    Types we don'thave in Java (1/5)  Symbols ▶ Sometimes called atoms or keywords: Prolog, Erlang ▶ Allows for naming things, for conveying meaning ▶ Clearer and more efficient than using strings or ints › Ruby: link_to("View Article", :controller => "articles", :action => "show") › Prolog: friend(laurel, hardy) › Clojure: (def product {:name "laser", :price 15}) › ... www.xebia.fr / blog.xebia.fr 31
  • 32.
    Types we don'thave in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r www.xebia.fr / blog.xebia.fr 32
  • 33.
    Types we don'thave in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r val LogEntry(totalTime, viewTime, dbTime, responseCode, uri) = line // result totalTime: String = 100 viewTime: String = 25 dbTime: String = 75 responseCode: String = 200 uri: String = "" www.xebia.fr / blog.xebia.fr 33
  • 34.
    Types we don'thave in Java (2/5)  Regex ▶ Scala: val line = """Completed in 100ms (View: 25, DB: 75) | 200 OK [http://example.com?params=here]""" val LogEntry = """Completed in (d+)ms (View: (d+), DB: (d+)) | (d+) OK [http://example.com(.*)?.*""".r val LogEntry(totalTime, viewTime, dbTime, responseCode, uri) = line // result totalTime: String = 100 viewTime: String = 25 dbTime: String = 75 responseCode: String = 200 uri: String = "" Source.fromFile(logFile).getLines.collect { _ match { case LogEntry(tt, vt, dbt, rc, uri) => println(rc) case OtherPattern(var1, var2) => // … case _ => } } www.xebia.fr / blog.xebia.fr 34
  • 35.
    Types we don'thave in Java (3/5)  XML ▶ Scala: val things = <things> <movie genre="action">Pirates of the Caribbean</movie> <movie genre="fairytale">Edward Scissorhands</movie> <book genre={ genre }>{ title }</book> </things> things "movie" (things "@genre")(1).text things "movie" find { node: Node => (node "@genre").text == "action" } www.xebia.fr / blog.xebia.fr 35
  • 36.
    Types we don'thave in Java (3/5)  XML ▶ Scala: val things = <things> <movie genre="action">Pirates of the Caribbean</movie> <movie genre="fairytale">Edward Scissorhands</movie> <book genre={ genre }>{ title }</book> </things> things "movie" (things "@genre")(1).text things "movie" find { node: Node => (node "@genre").text == "action" } (things "_").foreach { _ match { case <movie>{ title }</movie> => println(title) case <book>{ _ }</book> => println("book") case _ => } } www.xebia.fr / blog.xebia.fr 36
  • 37.
    Types we don'thave in Java (4/5)  Ranges ▶ Ruby: myArray[1..3] (1..3).to_a (1..21).each{|n| print n} ▶ Scala: 0 to 10 for (i <- 0 until 10) (0 until 10 by 5).start //.end .step ▶ Haskell: [1..5] [1,1.5..5] -- 1, 1.5, 2, 2.5, ... ▶ Clojure: (range 1 21) ; actually this produces a sequence, more on that later www.xebia.fr / blog.xebia.fr 37
  • 38.
    Types we don'thave in Java (4/5)  Ranges ▶ Ruby: myArray[1..3] (1..3).to_a (1..21).each{|n| print n} ▶ Scala: 0 to 10 for (i <- 0 until 10) (0 until 10 by 5).start //.end .step ▶ Haskell: [1..5] [1,1.5..5] -- 1, 1.5, 2, 2.5, ... ▶ Clojure: (range 1 21) ; actually this produces a sequence, more on that later  Tuples › (x, y) = (1, 2) {x, y} = {1, 2} www.xebia.fr / blog.xebia.fr 38
  • 39.
    Types we don'thave in Java (5/5) Functions! www.xebia.fr / blog.xebia.fr 39
  • 40.
    Higher-Order Functions  Producesor consumes other functions ▶ Ruby: def do_something(x, y) z = # ... lambda { |w| z + w } end ▶ Haskell: applyToArg f x = f(x)  Partial Application (~Currying) ▶ Erlang: prod x y = x * y double = prod 2 triple = prod 3 www.xebia.fr / blog.xebia.fr 40
  • 41.
    Functions and Sequences Sequence: abstraction for “iterable things” ▶ Scala: persons foreach { p => println(p.name) } persons map { _.name } persons filter { _.female } ▶ Clojure: => (def m1 {:car 2, :doll 5, :table 1}) => (def m2 {:bike 6, :doll 3}) => (def m (merge-with + m1 m2)) {:bike 6, :car 2, :doll 8, :table 1} => (reduce (fn [acc [_ qty]] (+ acc qty)) 0 m) 17 www.xebia.fr / blog.xebia.fr 41
  • 42.
    Functional Programming Concepts Immutability  Nil ▶ Empty list ▶ Nil.size(), count(nil)  Optional result ▶ Scala: Haskell: map.get(aKey) match { case aValue of case Some(x) => println(x) Just x -> ... case None => println("Nope") Nothing -> ... } www.xebia.fr / blog.xebia.fr 42
  • 43.
    List Comprehension  Buildsa list from other list(s) ▶ Erlang: [ {X, Y} || X <- lists:seq(1, 4), X < 3, Y <- [5, 6] ]. % [{1,5},{1,6},{2,5},{2,6}] ▶ Haskell: [ (x, y) | x <- [1..4], x < 3, y <- [5, 6] ] ▶ Clojure: (for [ x [1,2,3,4], y [5,6], :when (< x 3)] (* x y)) ▶ Scala: for (x <- 1 to 2; y <- List(5, 6); if x < 3) yield (x, y) www.xebia.fr / blog.xebia.fr 43
  • 44.
    Lazy evaluation  Delaysthe evaluation of an expression until its value is required  Increases performance  Allows for infinite sequences ▶ Haskell: take 4 (dropWhile (< 34098) [0, 0.5 ..]) -- [34098.0, 34098.5, 34099.0, 34099.5] zip (take 5 (iterate (2*) 10)) (take 5 (iterate (/2) 10)) -- [(10, 10.0), (20, 5.0), (40, 2.5), (80, 1.25), (160, 0.625)] ▶ Clojure => (take 5 (interpose :and (cycle [:x :k :e]))) (:x :and :k :and :e) www.xebia.fr / blog.xebia.fr 44
  • 45.
    Lazy evaluation  Analternative to recursion ▶ Fibonacci: (defn fib-pair [[a b]] [b (+ a b)]) (defn fibonacci [] (map first (iterate fib-pair [1 1]))) (take 10 (fibonacci)) ; (1 1 2 3 5 8 13 21 34 55) www.xebia.fr / blog.xebia.fr 45
  • 46.
    Concurrency  The Problem ▶ Shared resources ▶ Interactions between threads/processes ▶ Coordination ▶ Failures www.xebia.fr / blog.xebia.fr 46
  • 47.
    Actors  An independentcomputational entity having a mailbox  It can send/receive messages (a-)synchronously ▶ Erlang (synchronous example): loop() -> receive {From, "voiture"} -> From ! "car", loop(); {From, _} -> From ! "unknown word", loop() end. Service = spawn(fun loop/0). Service ! {self(), "voiture"}, receive Translation -> Translation end. www.xebia.fr / blog.xebia.fr 47
  • 48.
    Actors  An independentcomputational entity having a mailbox  It can send/receive messages (a-)synchronously ▶ Scala (asynchronous example): class Service extends Actor { def act() = { loop { react { case "voiture" => println("car") case _ => println("unknown word") } } } } val service = new Service() service.start service ! "voiture" www.xebia.fr / blog.xebia.fr 48
  • 49.
    Software Transactional Memory STM ▶ Same approach as for databases (ACID) ▶ Wrap code accessing shared resources in a transaction ▶ The transaction sees values as they were when opening it › Clojure: (def i (ref 0)) (def j (ref 0)) (dosync (alter i inc) (alter j dec)) – But also, in a nutshell: Uncoordinated Coordinated Synchronous Atom Reference (ref) Asynchronous Agent www.xebia.fr / blog.xebia.fr 49
  • 50.
    Let it Crash! Erlang philosophy  Cheap processes instead of threads  Monitor your processes  Make them restart on failure  Refer to the “library” example loop() -> process_flag(trap_exit, true), receive new -> register(revolver, spawn_link(fun russian_roulette_loop/0)), loop(); {'EXIT', From, Reason} -> self() ! new, loop() end. www.xebia.fr / blog.xebia.fr 50
  • 51.
    Questions? www.xebia.fr / blog.xebia.fr 51
  • 52.
    Exercises 1. Shopping Cart  Represent a catalog in the form of a list of tuples (article, quantity, price)  Write a function that returns the price of an article when present in the catalog or nothing/nil (depending on the language) otherwise  Using recursion, write a function that computes the total value of the catalog  Write a function that feeds a cart with items from the catalog until: ▶ either a maximum amount is reached for the cart value ▶ or the catalog is empty Note: It might be simpler to represent the cart as a list of tuples (article, price) at first (with the same article occuring serveral times).  Amends your function so that it also returns the catalog minus the items that are in the cart  Using fold/reduce (depending on the language), writes a function that computes the total value of the cart  Using a list comprehension, write a function that takes a cart and returns it with a given tax applied to its items  Interesting candidates are: Erlang, Haskell, Clojure and Scala www.xebia.fr / blog.xebia.fr 52
  • 53.
    Exercises 2. Tic-Tac-Toe  Write a pogram that accepts a tic-tac-toe board and returns whether there is a winner and, if it is the case, which one.  Depending on the language you choose, try to use the most different functional constructs you can think of: ▶ list processing with functions ▶ list comprehensions ▶ pattern matching and data deconstruction ▶ ...  Should you finish the first part early, modify your program so that it tells when there is a tie.  Interesting candidates are: Scala, Clojure, Erlang, Haskell  Alternatively, solve the problem with Prolog www.xebia.fr / blog.xebia.fr 53
  • 54.
    Exercises 3. Erlang: Chat  The aim of this exercise is to write a chat application allowing for discussing between two terminals, based on the "translate_service", "russian_roulette" and "library" examples.  You can find template files for a server, a supervisor and a client.  The server will be in charge to log in clients and dispatch their messages. It will be built with Erlang OTP's generic server feature.  The supervisor will be in charge to restart the server should a crash occur.  The client will spawn a process when the user requests a connection to the server, so that this underlying process can handle messages from the server while the user use the console process to give orders to the client. www.xebia.fr / blog.xebia.fr 54
  • 55.
    Exercises 4. Reverse Dependency Tree  Using Scala, write a program that can scan a local Maven repository for POM files and build a reverse dependency tree for a given module.  Use actors to load and parse files concurrently, and then send pieces of dependency model to a collecting actor.  Use Scala's XML capabilities to read POM files www.xebia.fr / blog.xebia.fr 55
  • 56.
    Exercises 5. The Sleeping Barber  A barber has one barber chair and a waiting room with a number of chairs in it.  When the barber finishes cutting a customer's hair, he dismisses the customer and then goes to the waiting room to see if there are other customers waiting: ▶ if there are, he brings one of them back to the chair and cuts his or her hair, ▶ if there are no other customers waiting, he returns to his chair and sleeps in it.  Each customer, when he arrives, looks to see what the barber is doing: ▶ if the barber is sleeping, then he wakes him up and sits in the chair, ▶ if the barber is cutting hair, then he goes to the waiting room: › if there is a free chair in the waiting room, he sits in it and waits his turn, › if there is no free chair, then the customer leaves.  Write a program that print events occurring in the shop: customer arrival and departure (and why), barber state (cutting hair, sleeping), etc...  Use the following durations: a hair cut last 100 to 500 ms, a customer enters the shop every 1 to 450 ms. Stop sending customers after the 20th one. www.xebia.fr / blog.xebia.fr 56