How to say a lot with few words May 12, 2006 IRCAM Peter Van Roy Université catholique de Louvain Louvain-la-Neuve, Belgium May 12, 2006 P. Van Roy, IRCAM visit 1 Goal of the talk     The goal of this talk is to show that programming languages can be both concise and powerful We will show how adding a few powerful concepts can greatly increase the expressiveness of a programming language At the same time, we will give a comprehensive overview of concurrent programming and how simple it can be if done properly The language we will use is called Oz May 12, 2006 P. Van Roy, IRCAM visit 2 1 Prerequisites I assume some familiarity with programming  Preferably, in at least two languages Familiarity with algorithmic thinking   I am going to cover a lot of ground quickly  I hope some concepts will be new to you Some may be familiar concepts in a new jacket I will use simple examples to make everything intuitive    For many more examples and techniques, see the book “Concepts, Techniques, and Models of Computer Programming”, MIT Press, March 2004  All the example programs run on the Mozart system, available at http://www.mozart-oz.org  May 12, 2006 P. Van Roy, IRCAM visit 3 Programming language power   How do programming languages get their expressive power? There are two main ways:    The library approach soon hits a brick wall   By libraries: with a large number of libraries that provide extra functionality By design: with a small number of concepts that can be combined in many ways It is limited by the underlying language, e.g., Java always uses objects with mutable state The concept approach can go much further   We have used this approach since the early 1990s to design the Oz language This talk is a practical introduction to the approach May 12, 2006 P. Van Roy, IRCAM visit 4 2 Choosing the right concepts   Oz provides a large set of basic concepts Choose the concepts you need, for the paradigm you need           Functional programming Declarative concurrency Lazy functional programming Message-passing concurrency Asynchronous dataflow programming Relational programming Constraint programming Object-oriented programming … All these paradigms work together well because they differ in just a few concepts May 12, 2006 P. Van Roy, IRCAM visit 5 Symbolic data structures May 12, 2006 P. Van Roy, IRCAM visit 6 3 Symbolic data structures   Lists: the simplest linear structure [france belgium colombia] Records: a way to group data together nations(france:paris belgium:brussels colombia:bogota)  Atoms: simple constants nations, france, paris, belgium, brussels, colombia, bogota   Numbers: integers (true integers) or floating point All these data structures are first-class values   First class: Full range of operations to calculate with them Values: They are constants (this is very important!) May 12, 2006 P. Van Roy, IRCAM visit 7 nil Lists  paul george ringo Lists: the simplest linear structure    john A list is either an empty list or an element followed by a list L=nil % Empty list L=john|nil % Element followed by a list L=john|(paul|nil) L=john|(paul|(george|(ringo|nil))) Lists are used so often that we give them special syntax L=john|paul|george|ringo|nil L=[john paul george ringo] List operations   First element: L.1 (sometimes known as “head” or “car”) Rest of list: L.2 (sometimes known as “tail” or “cdr”) May 12, 2006 P. Van Roy, IRCAM visit 8 4 suit Records    shirt beige pants ochre socks coral Records: a way of grouping data together R=suit(shirt:beige pants:ochre socks:coral) Records have a label (“suit”) and a set of field names (“shirt”, “pants”, “socks”) and their values (“beige”, “ochre”, “coral”) Calculations with records {Browse R.shirt} % Displays beige {Browse {Label R}} % Displays suit {Browse {Arity R}} % Displays [pants shirt socks] {Browse {Width R}} % Displays 3 (number of fields) R2={AdjoinAt R shirt mauve} % Record with new field  Browse is a tool for displaying data structures May 12, 2006 P. Van Roy, IRCAM visit 9 Functional programming May 12, 2006 P. Van Roy, IRCAM visit 10 5 Functional programming  We use a simple functional language as the starting point    (Actually it is a process calculus with procedures, but you don’t really need to know that yet) This is a powerful way to begin a programming language Functions are building blocks   This is called higher-order functional programming and it gives an enormous expressive power (the whole area of functional programming is based on this) A function is a value in the language (like an integer), sometimes called a “lexically scoped closure” May 12, 2006 P. Van Roy, IRCAM visit 11 Examples of functions   Here is a simple factorial function fun {Fact N} if N==0 then 1 else N*{Fact N-1} end end We can use it to define combinations fun {Comb N K} n n! = {Fact N} div ({Fact K} * {Fact N-K}) k k! (n-k)! end This follows exactly the mathematical definition of combinations Because Oz integers are true integers (arbitrary precision), this definition really works! ()      May 12, 2006 For example, {Comb 52 5} returns 2598960 (number of poker hands) This does not work in C++ or Java since Comb will overflow (they only have integers modulo 232) This shows why a language should have a simple semantics P. Van Roy, IRCAM visit 12 6 Pattern matching fun {SumList L} case L of nil then 0 [] H|T then H+{SumList T} end end    nil L 1 2 T Pattern  3 Pattern matching takes apart a data structure by matching it against a corresponding shape {Sum [1 2 3]} will try to match [1 2 3] first against nil and then against H|T Matching [1 2 3] against nil fails (no way to make them equal) Matching [1 2 3] against H|T succeeds and gives H=1 and T=2|3|nil    Remember that [1 2 3]=1|2|3|nil H+{Sum T} becomes 1+{Sum [2 3]} Final result is 1+(2+(3+0))=6 H May 12, 2006 P. Van Roy, IRCAM visit 13 Higher-order programming in one slide  Higher-order programming uses functions of any order!      A function whose arguments and results are not functions is of first order  fun {$ X Y} X+Y end is a first-order function (note: this function has no name!) A function that has a function of order n in an argument or result is of order n+1 A function that returns a function that adds N to a number: fun {MakeAdder N} fun {$ X} N+X end end Add1={MakeAdder 1} (Note that the Add1 function has memorized the value of N, which is 1) A function that takes a function F of two arguments and an argument N, and returns a function of one argument X that does F on N and X fun {MakeOneArg F N} fun {$ X} {F N X} end end Add1={MakeOneArg fun {$ X Y} X+Y end 1} (This Add1 function has memorized the values of F and N) What is the order of MakeAdder and the order of MakeOneArg? May 12, 2006 P. Van Roy, IRCAM visit 14 7 Generic programming in one slide    Summing the elements of a list: fun {SumList L} case L of nil then 0 [] H|T then H+{SumList T} end end We make this generic by replacing 0 and +: fun {FoldR L F U} case L of nil then U [] H|T then {F H {FoldR T F U}} end end Why FoldR? It associates to the right: {F X0 {F X1 {F X2 … {F Xn-1 U}…}}} Now we can define many variations: fun {SumList L} {FoldR L fun {$ X Y} X+Y end 0} end fun {ProdList L} {FoldR L fun {$ X Y} X*Y end 1} end fun {Some L} {FoldR L fun {$ X Y} X orelse Y end false} end fun {All L} {FoldR L fun {$ X Y} X andthen Y end true} end May 12, 2006 P. Van Roy, IRCAM visit 15 Dataflow and concurrency May 12, 2006 P. Van Roy, IRCAM visit 16 8 Dataflow variables  Single-assignment store    Variables are initially unbound and can be bound to just one value declare X in {Browse X} % Displays “X” X=100 % X is bound, display becomes “100” Data structures with holes that are filled in later (“partial values”) declare X K V L R in X=tree(K V L R) % Build tree with holes in it K=dog V=chien % Fill key and value L=tree(cat chat leaf leaf) % Fill left subtree R=tree(mouse souris leaf leaf) % Fill right subtree This is an important concept for many paradigms   Functional programs can be simpler and more efficient (tail recursion) Declarative concurrency becomes possible (streams) May 12, 2006 P. Van Roy, IRCAM visit 17 Concurrency  Concurrency is a language concept that allows to express when two computations are independent   Concurrency should be easy to use   This is very important and should be taught early It’s hard in the usual object-oriented languages We will see just how easy concurrency can be     Let us add just one concept: the thread Declarative concurrency Message-passing concurrency Asynchronous dataflow programming May 12, 2006 P. Van Roy, IRCAM visit 18 9 Dataflow computation    A calculation proceeds when its inputs become available thread Z=X+Y {Browse Z} end thread {Delay 1000} X=25 end thread {Delay 2000} Y=144 end When this is executed, nothing is displayed right away After 1000 milliseconds, X is bound   Still nothing is displayed! After 2000 milliseconds, Y is bound  X+Y can proceed, and the Browse then displays 169 May 12, 2006 P. Van Roy, IRCAM visit 19 Dataflow with streams  Eager producer/consumer example with dataflow synchronization fun {Ints N Max} if NY then Y|{Merge Xs Yr} else X|{Merge Xr Yr} end end end  At first, all the calls to Merge and Times will wait When the second value of H is needed, then some calculation will be done     May 12, 2006 The first Merge is activated This will activate Times and the second Merge The second Merge will activate the last two Times This will cause the second value to be calculated P. Van Roy, IRCAM visit 35 Importance of declarative concurrency May 12, 2006 P. Van Roy, IRCAM visit 36 18 Why is declarative concurrency important?  Declarative concurrency is much easier to program with than more standard paradigms (e.g., Java style with monitors) Programs have no race conditions, i.e., results that depend on exact timing, which makes them unpredictable Programs have no memory, i.e., internal state that can get a wrong value    It does have a limitation, though It cannot express nondeterminism, e.g., when programs have multiple independent inputs from the external world This is not usually a problem, because nondeterminism can be isolated to a small part of the program We recommend this programming style!    May 12, 2006 P. Van Roy, IRCAM visit 37 Declarative concurrent model ::=  Empty statement Sequential composition Procedure creation Procedure invocation thread end Thread creation local in end = if then 1 else 2 end case of

then 1 else 2 end Variable creation Variable binding Conditional (synchronizes on bind) Pattern matching (synchronizes on bind) {WaitNeeded } By-need synchronization Declarative concurrency adds threads and single-assignment variables with dataflow synchronization to a simple functional language    skip 1 2 proc { 1 … n} end { 1 … n} This is a process calculus that is a subset of Oz Declarative concurrency adds “slack” between producer and consumer Lazy evaluation adds by-need synchronization  Lazy evaluation does coroutining between producer and consumer May 12, 2006 P. Van Roy, IRCAM visit 38 19 Message passing and multiagent systems May 12, 2006 P. Van Roy, IRCAM visit 39 Message-passing concurrency  Multiagent systems    In this paradigm, programs consist of independent entities (called “agents”) that communicate through asynchronous message passing The agents work together to achieve a common goal We can implement agents by adding just one new concept, a communication channel  Note that this removes the limitation of the declarative concurrent model: the channel can accept inputs from the external world May 12, 2006 P. Van Roy, IRCAM visit 40 20 Communication channel     We add a simple communication channel, called a port declare S P in {NewPort S P} A port P has a corresponding stream S Messages sent to the port will appear on S {Browse S} {Send P alpha} % S is alpha|_ {Send P beta} % S is alpha|beta|_ With a port and a thread we can make an agent May 12, 2006 P. Van Roy, IRCAM visit 41 Defining an agent (1)  We define an agent with a port, a thread, and a function    The thread reads messages M from the port’s stream Msgs and calls the function Fun for each message The function has two arguments, the agent’s internal state State and the message M, and it returns the new agent state fun {NewAgent Init Fun} proc {AgentLoop State Msgs} case Msgs of M|Msgs2 then {AgentLoop {Fun State M} Msgs2} [] nil then skip end end Msgs in thread {AgentLoop Init Msgs} end % The NewPort call returns the port as its result: {NewPort Msgs} end May 12, 2006 P. Van Roy, IRCAM visit 42 21 Defining an agent (2)  A clever programmer will realize that we can define NewAgent with FoldL fun {NewAgent Init Fun} Msgs Out in thread {FoldL Msgs Fun Init Out} end {NewPort Msgs} end  FoldL is exactly a loop with accumulator: it starts with Init, the second value is {Fun Init M1}, the third value is {Fun {Fun Init M1} M2}, and so forth   Each new value Mi on the message stream is accumulated Out is the final state when the stream terminates May 12, 2006 P. Van Roy, IRCAM visit 43 Three agents playing ball Player 1 ball(N) Player 2 ball(N) Player 3 ball(N)     Let us define a simple multiagent system with three agents Each agent upon receiving a ball(N) message will send a ball(N+1) message to a randomly chosen other player Each agent will count the number of ball(N) messages it has received and keep track of N Each agent also accepts a getstate(S) message and will bind its internal state to S. This lets us observe the agent’s behavior. May 12, 2006 P. Van Roy, IRCAM visit 44 22 A ball-playing agent fun {Player Others} {NewAgent state(0 0) fun {$ state(M B) Msg} case Msg of ball(N) then Ran=({OS.rand} mod {Width Others})+1 in {Send Others.Ran ball(N+1)} state(M+1 N) [] getstate(S) then S=state(M B) state(M B) end end end} end May 12, 2006 P. Van Roy, IRCAM visit 45 Playing a game    Create the three players P1={Player others(P2 P3)} P2={Player others(P1 P3)} P3={Player others(P1 P2)} Start the game by tossing in a ball {Send P1 ball(0)} Observe a game in progress {Browse {Send P1 getstate($)}} May 12, 2006 P. Van Roy, IRCAM visit 46 23 Functional building blocks as concurrency patterns   We can combine the expressive power of functional programming with message-passing concurrency Functional building blocks      We can use these building blocks in message-passing programs   {ForAll L F}: Apply a function to all elements of a list L2={Map L1 F}: Transform all elements of a list X={Fold L F U}: Merge elements of a list together L2={Filter L1 F}: Filter out elements of a list They were originally designed for sequential programs, but used in a dataflow setting they become powerful concurrency patterns Let us show one example: a contract net protocol May 12, 2006 P. Van Roy, IRCAM visit 47 Contract net protocol (1) Round 1 query Round 2 response Buyer Round 3 accept/cancel d  d d d d d Sellers A contract net protocol is a simple negotiation protocol    A buyer sends a query to a set of sellers Each seller sends a response with the price The buyer then chooses the best price, sends an accept to that seller, and a cancel to the others May 12, 2006 P. Van Roy, IRCAM visit 48 24 Contract net protocol (2)   Assume that Sellers is a list of sellers Then we can program a contract net protocol in just four lines of code: % Send queries and collect seller/price responses Rs={Map Sellers fun {$ S} S#{Send S query($)} end} % Find seller/price pair with lowest price S1#R1={FoldL Rs.2 fun {$ S1#R1 S#R} if R ::= skip 1= 2 = | | 1 2 local in end Empty statement Variable binding Value creation Sequential composition Variable creation if then 1 else 2 end case of

then 1 else 2 end { 1 … n} thread end {WaitNeeded } Conditional Pattern matching Procedure invocation Thread creation By-need synchronization {NewName } 1= !! 2 try 1 catch then 2 end raise end {NewPort 1 2} {Send 1 2} Name creation Read-only view Exception context Raise exception Port creation Port send Encapsulated search May 12, 2006 P. Van Roy, IRCAM visit Descriptive declarative Declarative Less and less declarative 64 32 Complete set of concepts (so far) ::= skip 1= 2 = | | 1 2 local in end Empty statement Variable binding Value creation Sequential composition Variable creation if then 1 else 2 end case of

then 1 else 2 end { 1 … n} thread end {WaitNeeded } Conditional Pattern matching Procedure invocation Thread creation By-need synchronization {NewName } 1= !! 2 try 1 catch then 2 end raise end {NewCell 1 2} {Exchange 1 2 3} Name creation Read-only view Exception context Raise exception Cell creation Cell exchange Encapsulated search May 12, 2006 Alternative P. Van Roy, IRCAM visit 65 Taxonomy of paradigms Declarative programming Strict functional programming, Scheme, ML Deterministic logic programming, Prolog + concurrency + by-need synchronization Declarative (dataflow) concurrency Lazy functional programming, Haskell + nondeterministic choice Concurrent logic programming, FCP Functional reactive programming + exceptions + explicit state Object-oriented programming, Java, C++, C# + search Nondeterministic logic prog., Prolog May 12, 2006 P. Van Roy, IRCAM visit   This diagram shows some of the important paradigms and how they relate according to the creative extension principle Each paradigm has its pluses and minuses and areas in which it is best Concurrent OOP (message passing, Erlang, E) (shared state, Java, C#) + computation spaces Constraint programming 66 33 History of Oz  The design of Oz distills the results of a long-term research collaboration that started in the early 1990s, based on concurrent constraint programming (Saraswat, Maher, Ueda)     ACCLAIM project 1991-94: SICS, Saarland University, Digital PRL, …  AKL (SICS): unifies the concurrent and constraint strains of logic programming, thus realizing one vision of the Japanese FGCS  LIFE (Digital PRL): unifies logic and functional programming using logical entailment as a delaying operation (logic as a control flow mechanism)  Oz (Saarland U): breaks with Horn clause tradition, is higher-order, factorizes and simplifies previous designs After ACCLAIM, several partners decided to continue with Oz Mozart Consortium since 1996: SICS, Saarland University, UCL The current language is Oz 3    May 12, 2006 Both simpler and more expressive than previous designs Distribution support (transparency), constraint support (computation spaces), component-based programming High-quality open source implementation: Mozart Programming System, http://www.mozart-oz.org P. Van Roy, IRCAM visit 67 34