170 likes | 472 Views
Declarative Programming Techniques Non-declarative needs (VRH 3.8) Program design in the small (VRH 3.9). Carlos Varela RPI Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL. Overview. What is declarativeness? Classification, advantages for large and small programs
E N D
Declarative Programming TechniquesNon-declarative needs (VRH 3.8)Program design in the small (VRH 3.9) Carlos Varela RPI Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Overview • What is declarativeness? • Classification, advantages for large and small programs • Control Abstractions • Iterative programs • Higher-order programming • Basic operations, loops, data-driven techniques, laziness, currying • Modularity and non-declarative needs • File and window I/O, large-scale program structure • Limitations and extensions of declarative programming • Lazy Evaluation C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Software components • What is a good way to organize a large program? • It is confusing to put all in one big file • Partition the program into logical units, each of which implements a set of related operations • Each logical unit has two parts, an interface and an implementation • Only the interface is visible from outside the logical unit, i.e., from other units that use it • A program is a directed graph of logical units, where an edge means that one logical unit needs the second for its implementation • Such logical units are vaguely called « modules » or « software components » • Let us define these concepts more precisely C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Basic concepts • Module = part of a program that groups together related operations into an entity with an interface and an implementation • Module interface = a record that groups together language entities belonging to the module • Module implementation = a set of language entities accessible by the interface but hidden from the outside (hiding can be done using lexical scope) • Module specification = a function whose arguments are module interfaces, that creates a new module when called, and that returns this new module’s interface • Module specifications are sometimes called software components, but the latter term is widely used with many different meanings • To avoid confusion, we will call our module specifications functors and we give them a special syntax (they are a linguistic abstraction) C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Standalone applications • A standalone application consists of one functor, called the main functor, which is called when the application starts • The main functor is used for its effect of starting the application and not for the module it creates • The modules it needs are linked dynamically (upon first use) or statically (upon application start) • Linking a module: First see whether the module already exists, if so return it. Otherwise, find a functor specifying the module according to some search strategy, call the functor, and link its arguments recursively. • Functors are compilation units, i.e., the system has support for handling functors in files, in both source and compiled form C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Constructing a module • Let us first see an example of a module, and then we will define a functor that specifies that module • A module is accessed through its interface, which is a record • We construct the module MyList • MergeSort is inaccessible outside the module • Append is accessible as MyList.append declare MyList in local proc {Append …} … end proc {MergeSort …} … end proc {Sort …} … {MergeSort …} … end proc {Member …} … end in MyList=‘export‘( append:Append sort: Sort member: Member …) end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Specifying a module • Now let us define a functor that specifies the module MyList • The functor MyListFunctor will create a new module whenever it is called • The functor has no arguments because the module needs no other modules fun {MyListFunctor} proc {Append …} … end proc {MergeSort …} … end proc {Sort …} … {MergeSort …} … end proc {Member …} … end in ‘export‘(append:Append sort: Sort member: Member …) end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Syntactic support for functors • We give syntactic support to the functor • The keyword export is followed by the record fields • The keyword define is followed by the module initialization code • There is another keyword not used here, import, to specify which modules the functor needs functor export append: Append sort: Sort member: Member … define proc {Append …} … end proc {MergeSort …} … end proc {Sort …} … {MergeSort …} … end proc {Member …} … end end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Example standalone application • Compile Dict.oz giving Dict.ozf • Compile WordApp.oz giving WordApp* File WordApp.oz File Dict.oz functor export new:NewDict put:Put condGet:CondGet entries:Entries define fun {NewDict} ... end fun {Put Ds Key Value} … end fun {CondGet Ds Key Default} … end fun {Entries Ds} … end end functor import Open Dict QTk define … (1. Read stdin into a list) … (2. Calculate word frequencies) … (3. Display result in a window) end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Library modules • A programming system usually comes with many modules • Built-in modules: available without needing to specify them in a functor • Library modules: have to be specified in a functor C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Non-declarative needs • Example modules exist for non-declarative needs, e.g.: • File I/O • Graphical User Interfaces C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Large-scale program structure • Modules: an example of higher-order programming • Module specifications C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Limitations and extensionsof declarative programming • Is declarative programming expressive enough to do everything? • Given a straightforward compiler, the answer is no • Examples of limitations: File I/O, GUI. • Extensions of declarative programming: • Concurrency • State • Concurrency and state • When to use each model • Use the least expressive model that gives a simple program (without technical scaffolding) • Use declarative whenever possible, since it is by far the easiest to reason about, both in the small and in the large C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Lazy evaluation • The functions written so far are evaluated eagerly (as soon as they are called) • Another way is lazy evaluation where a computation is done only when the results is needed • Calculates the infinite list:0 | 1 | 2 | 3 | ... declare funlazy {Ints N} N|{Ints N+1} end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Lazy evaluation (2) • Write a function that computes as many rows of Pascal’s triangle as needed • We do not know how many beforehand • A function is lazy if it is evaluated only when its result is needed • The function PascalList is evaluated when needed funlazy {PascalList Row} Row | {PascalList {AddList {ShiftLeft Row} {ShiftRight Row}}} end C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Lazy evaluation (3) declare L = {PascalList [1]} {Browse L} {Browse L.1} {Browse L.2.1} • Lazy evaluation will avoid redoing work if you decide first you need the 10th row and later the 11th row • The function continues where it left off L<Future> [1] [1 1] C. Varela; Adapted w/permission from S. Haridi and P. Van Roy
Exercises • Use the File I/O module in Oz to create a program that reads a file and and writes the word that occurs more frequently in the file. • Create a Stack module and an example program using the module. • Read VRH Section 4.5. C. Varela; Adapted w/permission from S. Haridi and P. Van Roy