1 / 48

Declarative Objects

ira
Download Presentation

Declarative Objects

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. Declarative Objects 7/22/10 Jonathan Edwards sdg csail MIT I want to talk about the future of programming. But first we need to talk about the present.I want to talk about the future of programming. But first we need to talk about the present.

    2. We still program as in assembly language, by sequencing instructions that read and write memory. This is barbaric. For example…We still program as in assembly language, by sequencing instructions that read and write memory. This is barbaric. For example…

    3. This class represents a task with a start and an endThis class represents a task with a start and an end

    4. We can add length as a calculated field, using get/set accessor methods in C# syntaxWe can add length as a calculated field, using get/set accessor methods in C# syntax

    5. We define a method slipAfter that will slip the start till after a specified task, and increment the current lengthWe define a method slipAfter that will slip the start till after a specified task, and increment the current length

    6. This is the obvious implementationThis is the obvious implementation

    7. But it is incorrect, because the length getter reads the modified value of startBut it is incorrect, because the length getter reads the modified value of start

    8. Swapping the statements is also wrong, because the length setter reads the old value of startSwapping the statements is also wrong, because the length setter reads the old value of start

    9. We need to save the old value of length, and then update start and length in precisely that order.We need to save the old value of length, and then update start and length in precisely that order.

    10. If we redefine the task to compute start from end and length, then everything changes again. Now this example is a little forced, but it is typical of what often happens at a larger scale with side-effecting API’s.If we redefine the task to compute start from end and length, then everything changes again. Now this example is a little forced, but it is typical of what often happens at a larger scale with side-effecting API’s.

    11. If the side effects in 10 lines of code can be this confusing… If the side effects in 10 lines of code can be this confusing…

    12. How can we possibly understand a real program? Sequencing every read and write to memory is beyond human capabilities. But it is exactly what compilers are good at.How can we possibly understand a real program? Sequencing every read and write to memory is beyond human capabilities. But it is exactly what compilers are good at.

    13. Here is what we really want. There is an atomic transition from one state to a new state. #Code specifies how the state changes #The compiler figures out an execution order for us, and saves copies of values when neededHere is what we really want. There is an atomic transition from one state to a new state. #Code specifies how the state changes #The compiler figures out an execution order for us, and saves copies of values when needed

    14. Here is some syntax for specifying this. But I don’t have time to talk about trivialities like syntax.Here is some syntax for specifying this. But I don’t have time to talk about trivialities like syntax.

    15. Here is some syntax for specifying this. #...Here is some syntax for specifying this. #...

    16. What’s important is that the syntax does not specify execution order. There is no control flow. The compiler figures out an order based on dataflow, and knows when it needs to keep a copy of a pre-state valueWhat’s important is that the syntax does not specify execution order. There is no control flow. The compiler figures out an order based on dataflow, and knows when it needs to keep a copy of a pre-state value

    17. This means we can program in terms of high level operations, and the compiler figures out a recipe for executing themThis means we can program in terms of high level operations, and the compiler figures out a recipe for executing them

    18. Declarative Programming This is called declarative programming. The programmer describes what to do in a high level notation, and the compiler figures out the low level details like execution order. Declarative languages have no concept of a program counter. This makes programming easier.This is called declarative programming. The programmer describes what to do in a high level notation, and the compiler figures out the low level details like execution order. Declarative languages have no concept of a program counter. This makes programming easier.

    19. Parallel Processing Since the programmer is no longer specifying the exact order of execution, the compiler is free to execute it in parallel on multiple cores. Since the programmer is no longer specifying the exact order of execution, the compiler is free to execute it in parallel on multiple cores.

    20. Distributed Processing The compiler is also free to distribute the program across a network, bundling interactions together to reduce latency. The compiler is also free to distribute the program across a network, bundling interactions together to reduce latency.

    21. Unfortunately, pointers destroy declarative programming. And we need pointers for standard object models of data. Philip Stein, aka Estańo http://www.mexicanmuralschool.com/gallery2/gal33.htmUnfortunately, pointers destroy declarative programming. And we need pointers for standard object models of data. Philip Stein, aka Estańo http://www.mexicanmuralschool.com/gallery2/gal33.htm

    22. What happens if t and this point to the same object?What happens if t and this point to the same object?

    23. We get this unexpected dataflowWe get this unexpected dataflow

    24. That causes a circular dataflow. Result is non-deterministic. This is a fundamental problem, called pointer aliasing. The problem is that a compiler can’t predict when pointer aliasing will happen. That means a compiler can’t predict dataflow.That causes a circular dataflow. Result is non-deterministic. This is a fundamental problem, called pointer aliasing. The problem is that a compiler can’t predict when pointer aliasing will happen. That means a compiler can’t predict dataflow.

    25. pointers ? undecidable dataflow Pointers make compilers stupidPointers make compilers stupid

    26. Pick two Therefore declarative programming is fundamentally constrained. #If we give up data structures, we can build circuits with registers and gates and wires. State machine and dataflow languages are like this. #If we give up mutability, and restrict data structures to trees, we can use functional programming #But if we want complex data structures that are mutable, we need to go back to manually ordering all operations with imperative programming.Therefore declarative programming is fundamentally constrained. #If we give up data structures, we can build circuits with registers and gates and wires. State machine and dataflow languages are like this. #If we give up mutability, and restrict data structures to trees, we can use functional programming #But if we want complex data structures that are mutable, we need to go back to manually ordering all operations with imperative programming.

    27. Here is my idea to solve this problem #First, restrict pointers with a new object model that uses nesting and binding #Second, prevent cycles with a new form of dataflow based on the Model-View architectureHere is my idea to solve this problem #First, restrict pointers with a new object model that uses nesting and binding #Second, prevent cycles with a new form of dataflow based on the Model-View architecture

    28. If we define a project to contain 2 tasks, we normally allocate the tasks in a heap and point to themIf we define a project to contain 2 tasks, we normally allocate the tasks in a heap and point to them

    29. Instead, I allocate the tasks inside the project object All objects are nested inside other objects. The entire program state is a tree. Nesting gives every object a location in the global tree. References to objects are relative paths in the tree. Aliasing is impossible. Nested objects have lots of other benefits, like the ability to make deep copies and comparisons, but I don’t have time for that now.Instead, I allocate the tasks inside the project object All objects are nested inside other objects. The entire program state is a tree. Nesting gives every object a location in the global tree. References to objects are relative paths in the tree. Aliasing is impossible. Nested objects have lots of other benefits, like the ability to make deep copies and comparisons, but I don’t have time for that now.

    30. Sometimes we use pointers to share values. Instead I use bindings to couple values.The start of task2 is bound to the end of task1. They are automatically kept equal after all changes. This binding is not a pointer: it is statically locked into a path within the object tree. Notice that the arrow heads on the binding are different. I will explain that later.Sometimes we use pointers to share values. Instead I use bindings to couple values.The start of task2 is bound to the end of task1. They are automatically kept equal after all changes. This binding is not a pointer: it is statically locked into a path within the object tree. Notice that the arrow heads on the binding are different. I will explain that later.

    31. We need to dynamically allocate and organize objects. A domain is a collection of nested objects of a specific type The objects are dynamically created and are given unique opaque ID’s, shown here as hex stringsWe need to dynamically allocate and organize objects. A domain is a collection of nested objects of a specific type The objects are dynamically created and are given unique opaque ID’s, shown here as hex strings

    32. A cursor is an object that can be bound to any one of the elements of a specific domain. Cursors are defined with a quantified binding.A cursor is an object that can be bound to any one of the elements of a specific domain. Cursors are defined with a quantified binding.

    33. Here are two cursors on the same domainHere are two cursors on the same domain

    34. Here we apply the slipAfter method on themHere we apply the slipAfter method on them

    35. If the cursors are aliased there is no dataflow cycle, because the change doesn’t feedback to the cursor, until after the method completesIf the cursors are aliased there is no dataflow cycle, because the change doesn’t feedback to the cursor, until after the method completes

    36. Bindings have a direction. Data flows through these two directions in two separate phases. This prevents dataflow cycles from aliased pointers. But how can we break dataflow into 2 phases?Bindings have a direction. Data flows through these two directions in two separate phases. This prevents dataflow cycles from aliased pointers. But how can we break dataflow into 2 phases?

    37. We already do this in the standard Model-View architecture for interactive systems. #Data flows in one of two directions: input from the external world towards the internal state towards, and output in the reverse directionWe already do this in the standard Model-View architecture for interactive systems. #Data flows in one of two directions: input from the external world towards the internal state towards, and output in the reverse direction

    38. Model-View dataflow I am basically building Model-View architecture into the language. Bindings have two directionsI am basically building Model-View architecture into the language. Bindings have two directions

    39. Model-View dataflow The compiler orders execution so that output does not feedback into inputThe compiler orders execution so that output does not feedback into input

    40. Model-View dataflow The opposite directions have opposite semantics. Note that input is exactly where functional programming becomes awkward.The opposite directions have opposite semantics. Note that input is exactly where functional programming becomes awkward.

    41. Model-View dataflow Input does not have the evils of imperative callbacks and asynchronous events, because the compiler orders actions for us.Input does not have the evils of imperative callbacks and asynchronous events, because the compiler orders actions for us.

    42. New rules, new patterns Synchronous reactive programming Input event triggers atomic state transition Output is pure function of new state Asynchronicity layered on top Syntax order irrelevant – no control flow Pre-state readable throughout transition Fields can change once per transition Actions can’t see effects of own changes This new semantics changes a lot of the usual rules and programming patterns… I am just starting to explore the terrain of this new world. For example, there are cases where we really need sequential multi-step algorithms.This new semantics changes a lot of the usual rules and programming patterns… I am just starting to explore the terrain of this new world. For example, there are cases where we really need sequential multi-step algorithms.

    43. Progression Progressions allow multi-step changes. #A progressive binding makes incremental versions of a structure #Here the first step does the slipAfter action. Then the second step checks the result of that action. If the end is gtr than 10, then it is set to 10. This code would be illegal without the progression, because actions can’t see their own effects. The statements in each step execute in parallel, like top-level statements. #The pre-state of the progressive variables is the result of the prior step #If a step contains a false guard then its changes are droppedProgressions allow multi-step changes. #A progressive binding makes incremental versions of a structure #Here the first step does the slipAfter action. Then the second step checks the result of that action. If the end is gtr than 10, then it is set to 10. This code would be illegal without the progression, because actions can’t see their own effects. The statements in each step execute in parallel, like top-level statements. #The pre-state of the progressive variables is the result of the prior step #If a step contains a false guard then its changes are dropped

    44. Here is a diagram of the progression. #progressions encapsulate side-effects. Changes can’t leak in or out of the steps inside the progression. The only get out at the end via the declared progressive bindings. Progressions are little islands of imperative programming in a declarative sea. Vs functional style opposite. Progressions operate on subtrees of the state. A progression on the entire state would simulate imperative programming. Hopefully that isn’t needed.Here is a diagram of the progression. #progressions encapsulate side-effects. Changes can’t leak in or out of the steps inside the progression. The only get out at the end via the declared progressive bindings. Progressions are little islands of imperative programming in a declarative sea. Vs functional style opposite. Progressions operate on subtrees of the state. A progression on the entire state would simulate imperative programming. Hopefully that isn’t needed.

    45. A hypothetical is a progression that exports no changes. This is useful for testing – you can simulate a series of inputs and check the responses without worrying about side effectsA hypothetical is a progression that exports no changes. This is useful for testing – you can simulate a series of inputs and check the responses without worrying about side effects

    46. Technical Summary Nesting gives objects a location in global tree Bindings propagate changes through relative paths in tree (precise static effects) Bindings are directed: input, output, or both Input is change-driven, cascades eagerly Output is lazy pure functional Each is statically acyclic based on tree path effects Outputs do not feedback to inputs Imperative islands in a declarative sea

    47. Pick two To summarize, pointer aliasing is a major constraint on programming language designTo summarize, pointer aliasing is a major constraint on programming language design

    48. Declarative Objects We can finesse this constraint by limiting pointers to be just powerful enough for what we need without causing uncontrolled aliasing. Nesting & binding lets us build data structures with tightly constrained pointers. A Model-View architecture prevents vicious dataflow cycles. This makes it possible to do declarative programming with objects. This is still an early idea that requires much more work to be validated. But one way or another,…We can finesse this constraint by limiting pointers to be just powerful enough for what we need without causing uncontrolled aliasing. Nesting & binding lets us build data structures with tightly constrained pointers. A Model-View architecture prevents vicious dataflow cycles. This makes it possible to do declarative programming with objects. This is still an early idea that requires much more work to be validated. But one way or another,…

    49. The future of programming is declarative. So let’s get on with it! Thank you.The future of programming is declarative. So let’s get on with it! Thank you.

More Related