Muutke küpsiste eelistusi

Software Design for Flexibility: How to Avoid Programming Yourself into a Corner [Kõva köide]

  • Formaat: Hardback, 448 pages, kõrgus x laius: 229x178 mm
  • Ilmumisaeg: 09-Mar-2021
  • Kirjastus: MIT Press
  • ISBN-10: 0262045494
  • ISBN-13: 9780262045490
Teised raamatud teemal:
  • Formaat: Hardback, 448 pages, kõrgus x laius: 229x178 mm
  • Ilmumisaeg: 09-Mar-2021
  • Kirjastus: MIT Press
  • ISBN-10: 0262045494
  • ISBN-13: 9780262045490
Teised raamatud teemal:
"An advanced book on programming techniques to build flexible, robust, symbolic systems"--

Strategies for building large systems that can be easily adapted for new situations with only minor programming modifications.

Time pressures encourage programmers to write code that works well for a narrow purpose, with no room to grow. But the best systems are evolvable; they can be adapted for new situations by adding code, rather than changing the existing code. The authors describe techniques they have found effective--over their combined 100-plus years of programming experience--that will help programmers avoid programming themselves into corners.

The authors explore ways to enhance flexibility by:
  &;  Organizing systems using combinators to compose mix-and-match parts, ranging from small functions to whole arithmetics, with standardized interfaces
  &;   Augmenting data with independent annotation layers, such as units of measurement or provenance
  &;   Combining independent pieces of partial information using unification or propagation
  &;   Separating control structure from problem domain with domain models, rule systems and pattern matching, propagation, and dependency-directed backtracking
  &;   Extending the programming language, using dynamically extensible evaluators
Foreword xi
Preface xiii
Acknowledgments xix
1 Flexibility in Nature and in Design
1(20)
1.1 Architecture of computation
5(2)
1.2 Smart parts for flexibility
7(5)
1.3 Redundancy and degeneracy
12(2)
1.4 Exploratory behavior
14(3)
1.5 The cost of flexibility
17(4)
2 Domain-Specific Languages
21(46)
2.1 Combinators
22(15)
2.1.1 Function combinators
23(13)
2.1.2 Combinators and body plans
36(1)
2.2 Regular expressions
37(9)
2.2.1 A regular expression combinator language
38(1)
2.2.2 Implementation of the translator
39(7)
2.3 Wrappers
46(6)
2.3.1 Specialization wrappers
49(1)
2.3.2 Implementing specializers
50(2)
2.3.3 Adapters
52(1)
2.4 Abstracting a domain
52(12)
2.4.1 A monolithic implementation
53(5)
2.4.2 Factoring out the domain
58(6)
2.5 Summary
64(3)
3 Variations on an Arithmetic Theme
67(90)
3.1 Combining arithmetics
67(20)
3.1.1 A simple ODE integrator
68(3)
3.1.2 Modulating arithmetic operators
71(2)
3.1.3 Combining arithmetics
73(7)
3.1.4 Arithmetic on functions
80(3)
3.1.5 Problems with combinators
83(4)
3.2 Extensible generic procedures
87(16)
3.2.1 Generic arithmetic
90(4)
3.2.2 Construction depends on order!
94(3)
3.2.3 Implementing generic procedures
97(6)
3.3 Example: Automatic differentiation
103(22)
3.3.1 How automatic differentiation works
105(6)
3.3.2 Derivatives of n-ary functions
111(2)
3.3.3 Some technical details
113(10)
3.3.4 Literal functions of differential arguments
123(2)
3.4 Efficient generic procedures
125(7)
3.4.1 Tries
125(6)
3.4.2 Caching
131(1)
3.5 Efficient user-defined types
132(22)
3.5.1 Predicates as types
133(2)
3.5.2 Relationships between predicates
135(1)
3.5.3 Predicates are dispatch keys
136(2)
3.5.4 Example: An adventure game
138(16)
3.6 Summary
154(3)
4 Pattern Matching
157(76)
4.1 Patterns
158(2)
4.2 Term rewriting
160(10)
4.2.1 Segment variables in algebra
162(2)
4.2.2 Implementation of rule systems
164(2)
4.2.3 Aside: Magic macrology
166(2)
4.2.4 Pattern-directed invocation
168(2)
4.3 Design of the matcher
170(13)
4.3.1 Compiling patterns
176(3)
4.3.2 Match-variable restrictions
179(4)
4.4 Unification match
183(26)
4.4.1 How unification works
185(8)
4.4.2 Application: Type inference
193(3)
4.4.3 How type inference works
196(7)
4.4.4 Adding segment variables---an experiment!
203(6)
4.5 Pattern matching on graphs
209(22)
4.5.1 Lists as graphs
210(1)
4.5.2 Implementing graphs
211(2)
4.5.3 Matching on graphs
213(3)
4.5.4 Chessboards and alternate graph views
216(5)
4.5.5 Chess moves
221(4)
4.5.6 Implementing graph matching
225(6)
4.6 Summary
231(2)
5 Evaluation
233(66)
5.1 Generic eval/apply interpreter
234(16)
5.1.1 eval
235(9)
5.1.2 apply
244(6)
5.2 Procedures with non-strict arguments
250(9)
5.3 Compiling to execution procedures
259(10)
5.4 Exploratory behavior
269(11)
5.4.1 amb
271(2)
5.4.2 Implementing amb
273(7)
5.5 Exposing the underlying continuations
280(16)
5.5.1 Continuations as nonlocal exits
284(1)
5.5.2 Nonlocal transfer of control
285(3)
5.5.3 From continuations to amb
288(8)
5.6 Power and responsibility
296(3)
6 Layering
299(28)
6.1 Using layers
300(1)
6.2 Implemention of layering
301(8)
6.2.1 Layered data
302(3)
6.2.2 Layered procedures
305(4)
6.3 Layered arithmetic
309(6)
6.3.1 Unit arithmetic
310(5)
6.4 Annotating values with dependencies
315(8)
6.4.1 The support layer
317(5)
6.4.2 Carrying justifications
322(1)
6.5 The promise of layering
323(4)
7 Propagation
327(46)
7.1 An example: Distances to stars
329(13)
7.2 The propagation mechanism
342(7)
7.2.1 Cells
343(3)
7.2.2 Propagators
346(3)
7.3 Multiple alternative world views
349(2)
7.4 Merging values
351(4)
7.4.1 Merging base values
351(1)
7.4.2 Merging supported values
352(1)
7.4.3 Merging value sets
353(2)
7.5 Searching possible worlds
355(14)
7.5.1 Dependency-directed backtracking
358(6)
7.5.2 Solving combinatorial puzzles
364(5)
7.6 Propagation enables degeneracy
369(4)
8 Epilogue
373(26)
A Appendix: Supporting Software
377(2)
B Appendix: Scheme
379(20)
B.1 Essential Scheme
379(15)
B.2 More advanced stuff
394(5)
References 399(10)
Index 409(16)
List of Exercises 425