[{"id":0,"hasCaret":false,"label":"Foreword","nodeData":"foreword02"},{"id":1,"hasCaret":false,"label":"Foreword to Structure and Interpretation of Computer Programs, 1984","nodeData":"foreword84"},{"id":2,"hasCaret":false,"label":"Preface","nodeData":"prefaces03"},{"id":3,"hasCaret":false,"label":"Prefaces to Structure and Interpretation of Computer Programs, 19961984","nodeData":"prefaces96"},{"id":4,"hasCaret":false,"label":"Acknowledgments","nodeData":"acknowledgements"},{"id":6,"hasCaret":true,"label":"1 Building Abstractions with Functions","nodeData":"1","childNodes":[{"id":7,"hasCaret":true,"label":"1.1 The Elements of Programming","nodeData":"1.1","childNodes":[{"id":8,"hasCaret":false,"label":"1.1.1 Expressions","nodeData":"1.1.1"},{"id":9,"hasCaret":false,"label":"1.1.2 Naming and the Environment","nodeData":"1.1.2"},{"id":10,"hasCaret":false,"label":"1.1.3 Evaluating Operator Combinations","nodeData":"1.1.3"},{"id":11,"hasCaret":false,"label":"1.1.4 Compound Functions","nodeData":"1.1.4"},{"id":12,"hasCaret":false,"label":"1.1.5 The Substitution Model for Function Application","nodeData":"1.1.5"},{"id":13,"hasCaret":false,"label":"1.1.6 Conditional Expressions and Predicates","nodeData":"1.1.6"},{"id":14,"hasCaret":false,"label":"1.1.7 Example: Square Roots by Newton's Method","nodeData":"1.1.7"},{"id":15,"hasCaret":false,"label":"1.1.8 Functions as Black-Box Abstractions","nodeData":"1.1.8"}]},{"id":16,"hasCaret":true,"label":"1.2 Functions and the Processes They Generate","nodeData":"1.2","childNodes":[{"id":17,"hasCaret":false,"label":"1.2.1 Linear Recursion and Iteration","nodeData":"1.2.1"},{"id":18,"hasCaret":false,"label":"1.2.2 Tree Recursion","nodeData":"1.2.2"},{"id":19,"hasCaret":false,"label":"1.2.3 Orders of Growth","nodeData":"1.2.3"},{"id":20,"hasCaret":false,"label":"1.2.4 Exponentiation","nodeData":"1.2.4"},{"id":21,"hasCaret":false,"label":"1.2.5 Greatest Common Divisors","nodeData":"1.2.5"},{"id":22,"hasCaret":false,"label":"1.2.6 Example: Testing for Primality","nodeData":"1.2.6"}]},{"id":23,"hasCaret":true,"label":"1.3 Formulating Abstractions with Higher-Order Functions","nodeData":"1.3","childNodes":[{"id":24,"hasCaret":false,"label":"1.3.1 Functions as Arguments","nodeData":"1.3.1"},{"id":25,"hasCaret":false,"label":"1.3.2 Constructing Functions using Lambda Expressions","nodeData":"1.3.2"},{"id":26,"hasCaret":false,"label":"1.3.3 Functions as General Methods","nodeData":"1.3.3"},{"id":27,"hasCaret":false,"label":"1.3.4 Functions as Returned Values","nodeData":"1.3.4"}]}]},{"id":28,"hasCaret":true,"label":"2 Building Abstractions with Data","nodeData":"2","childNodes":[{"id":29,"hasCaret":true,"label":"2.1 Introduction to Data Abstraction","nodeData":"2.1","childNodes":[{"id":30,"hasCaret":false,"label":"2.1.1 Example: Arithmetic Operations for Rational Numbers","nodeData":"2.1.1"},{"id":31,"hasCaret":false,"label":"2.1.2 Abstraction Barriers","nodeData":"2.1.2"},{"id":32,"hasCaret":false,"label":"2.1.3 What Is Meant by Data?","nodeData":"2.1.3"},{"id":33,"hasCaret":false,"label":"2.1.4 Extended Exercise: Interval Arithmetic","nodeData":"2.1.4"}]},{"id":34,"hasCaret":true,"label":"2.2 Hierarchical Data and the Closure Property","nodeData":"2.2","childNodes":[{"id":35,"hasCaret":false,"label":"2.2.1 Representing Sequences","nodeData":"2.2.1"},{"id":36,"hasCaret":false,"label":"2.2.2 Hierarchical Structures","nodeData":"2.2.2"},{"id":37,"hasCaret":false,"label":"2.2.3 Sequences as Conventional Interfaces","nodeData":"2.2.3"},{"id":38,"hasCaret":false,"label":"2.2.4 Example: A Picture Language","nodeData":"2.2.4"}]},{"id":39,"hasCaret":true,"label":"2.3 Symbolic Data","nodeData":"2.3","childNodes":[{"id":40,"hasCaret":false,"label":"2.3.1 Strings","nodeData":"2.3.1"},{"id":41,"hasCaret":false,"label":"2.3.2 Example: Symbolic Differentiation","nodeData":"2.3.2"},{"id":42,"hasCaret":false,"label":"2.3.3 Example: Representing Sets","nodeData":"2.3.3"},{"id":43,"hasCaret":false,"label":"2.3.4 Example: Huffman Encoding Trees","nodeData":"2.3.4"}]},{"id":44,"hasCaret":true,"label":"2.4 Multiple Representations for Abstract Data","nodeData":"2.4","childNodes":[{"id":45,"hasCaret":false,"label":"2.4.1 Representations for Complex Numbers","nodeData":"2.4.1"},{"id":46,"hasCaret":false,"label":"2.4.2 Tagged data","nodeData":"2.4.2"},{"id":47,"hasCaret":false,"label":"2.4.3 Data-Directed Programming and Additivity","nodeData":"2.4.3"}]},{"id":48,"hasCaret":true,"label":"2.5 Systems with Generic Operations","nodeData":"2.5","childNodes":[{"id":49,"hasCaret":false,"label":"2.5.1 Generic Arithmetic Operations","nodeData":"2.5.1"},{"id":50,"hasCaret":false,"label":"2.5.2 Combining Data of Different Types","nodeData":"2.5.2"},{"id":51,"hasCaret":false,"label":"2.5.3 Example: Symbolic Algebra","nodeData":"2.5.3"}]}]},{"id":52,"hasCaret":true,"label":"3 Modularity, Objects, and State","nodeData":"3","childNodes":[{"id":53,"hasCaret":true,"label":"3.1 Assignment and Local State","nodeData":"3.1","childNodes":[{"id":54,"hasCaret":false,"label":"3.1.1 Local State Variables","nodeData":"3.1.1"},{"id":55,"hasCaret":false,"label":"3.1.2 The Benefits of Introducing Assignment","nodeData":"3.1.2"},{"id":56,"hasCaret":false,"label":"3.1.3 The Costs of Introducing Assignment","nodeData":"3.1.3"}]},{"id":57,"hasCaret":true,"label":"3.2 The Environment Model of Evaluation","nodeData":"3.2","childNodes":[{"id":58,"hasCaret":false,"label":"3.2.1 The Rules for Evaluation","nodeData":"3.2.1"},{"id":59,"hasCaret":false,"label":"3.2.2 Applying Simple Functions","nodeData":"3.2.2"},{"id":60,"hasCaret":false,"label":"3.2.3 Frames as the Repository of Local State","nodeData":"3.2.3"},{"id":61,"hasCaret":false,"label":"3.2.4 Internal Declarations","nodeData":"3.2.4"},{"id":62,"hasCaret":false,"label":"3.2.5 CSE Machine","nodeData":"3.2.5"}]},{"id":63,"hasCaret":true,"label":"3.3 Modeling with Mutable Data","nodeData":"3.3","childNodes":[{"id":64,"hasCaret":false,"label":"3.3.1 Mutable List Structure","nodeData":"3.3.1"},{"id":65,"hasCaret":false,"label":"3.3.2 Representing Queues","nodeData":"3.3.2"},{"id":66,"hasCaret":false,"label":"3.3.3 Representing Tables","nodeData":"3.3.3"},{"id":67,"hasCaret":false,"label":"3.3.4 A Simulator for Digital Circuits","nodeData":"3.3.4"},{"id":68,"hasCaret":false,"label":"3.3.5 Propagation of Constraints","nodeData":"3.3.5"}]},{"id":69,"hasCaret":true,"label":"3.4 Concurrency: Time Is of the Essence","nodeData":"3.4","childNodes":[{"id":70,"hasCaret":false,"label":"3.4.1 The Nature of Time in Concurrent Systems","nodeData":"3.4.1"},{"id":71,"hasCaret":false,"label":"3.4.2 Mechanisms for Controlling Concurrency","nodeData":"3.4.2"}]},{"id":72,"hasCaret":true,"label":"3.5 Streams","nodeData":"3.5","childNodes":[{"id":73,"hasCaret":false,"label":"3.5.1 Streams Are Delayed Lists","nodeData":"3.5.1"},{"id":74,"hasCaret":false,"label":"3.5.2 Infinite Streams","nodeData":"3.5.2"},{"id":75,"hasCaret":false,"label":"3.5.3 Exploiting the Stream Paradigm","nodeData":"3.5.3"},{"id":76,"hasCaret":false,"label":"3.5.4 Streams and Delayed Evaluation","nodeData":"3.5.4"},{"id":77,"hasCaret":false,"label":"3.5.5 Modularity of Functional Programs and Modularity of Objects","nodeData":"3.5.5"}]}]},{"id":78,"hasCaret":true,"label":"4 Metalinguistic Abstraction","nodeData":"4","childNodes":[{"id":79,"hasCaret":true,"label":"4.1 The Metacircular Evaluator","nodeData":"4.1","childNodes":[{"id":80,"hasCaret":false,"label":"4.1.1 The Core of the Evaluator","nodeData":"4.1.1"},{"id":81,"hasCaret":false,"label":"4.1.2 Representing Components","nodeData":"4.1.2"},{"id":82,"hasCaret":false,"label":"4.1.3 Evaluator Data Structures","nodeData":"4.1.3"},{"id":83,"hasCaret":false,"label":"4.1.4 Running the Evaluator as a Program","nodeData":"4.1.4"},{"id":84,"hasCaret":false,"label":"4.1.5 Data as Programs","nodeData":"4.1.5"},{"id":85,"hasCaret":false,"label":"4.1.6 Internal Declarations","nodeData":"4.1.6"},{"id":86,"hasCaret":false,"label":"4.1.7 Separating Syntactic Analysis from Execution","nodeData":"4.1.7"}]},{"id":87,"hasCaret":true,"label":"4.2 Lazy Evaluation","nodeData":"4.2","childNodes":[{"id":88,"hasCaret":false,"label":"4.2.1 Normal Order and Applicative Order","nodeData":"4.2.1"},{"id":89,"hasCaret":false,"label":"4.2.2 An Interpreter with Lazy Evaluation","nodeData":"4.2.2"},{"id":90,"hasCaret":false,"label":"4.2.3 Streams as Lazy Lists","nodeData":"4.2.3"}]},{"id":91,"hasCaret":true,"label":"4.3 Nondeterministic Computing","nodeData":"4.3","childNodes":[{"id":92,"hasCaret":false,"label":"4.3.1 Search and amb","nodeData":"4.3.1"},{"id":93,"hasCaret":false,"label":"4.3.2 Examples of Nondeterministic Programs","nodeData":"4.3.2"},{"id":94,"hasCaret":false,"label":"4.3.3 Implementing the amb Evaluator","nodeData":"4.3.3"}]},{"id":95,"hasCaret":true,"label":"4.4 Logic Programming","nodeData":"4.4","childNodes":[{"id":96,"hasCaret":false,"label":"4.4.1 Deductive Information Retrieval","nodeData":"4.4.1"},{"id":97,"hasCaret":false,"label":"4.4.2 How the Query System Works","nodeData":"4.4.2"},{"id":98,"hasCaret":false,"label":"4.4.3 Is Logic Programming Mathematical Logic?","nodeData":"4.4.3"},{"id":99,"hasCaret":false,"label":"4.4.4 Implementing the Query System","nodeData":"4.4.4"}]}]},{"id":100,"hasCaret":true,"label":"5 Computing with Register Machines","nodeData":"5","childNodes":[{"id":101,"hasCaret":true,"label":"5.1 Designing Register Machines","nodeData":"5.1","childNodes":[{"id":102,"hasCaret":false,"label":"5.1.1 A Language for Describing Register Machines","nodeData":"5.1.1"},{"id":103,"hasCaret":false,"label":"5.1.2 Abstraction in Machine Design","nodeData":"5.1.2"},{"id":104,"hasCaret":false,"label":"5.1.3 Subroutines","nodeData":"5.1.3"},{"id":105,"hasCaret":false,"label":"5.1.4 Using a Stack to Implement Recursion","nodeData":"5.1.4"},{"id":106,"hasCaret":false,"label":"5.1.5 Instruction Summary","nodeData":"5.1.5"}]},{"id":107,"hasCaret":true,"label":"5.2 A Register-Machine Simulator","nodeData":"5.2","childNodes":[{"id":108,"hasCaret":false,"label":"5.2.1 The Machine Model","nodeData":"5.2.1"},{"id":109,"hasCaret":false,"label":"5.2.2 The Assembler","nodeData":"5.2.2"},{"id":110,"hasCaret":false,"label":"5.2.3 Instructions and Their Execution Functions","nodeData":"5.2.3"},{"id":111,"hasCaret":false,"label":"5.2.4 Monitoring Machine Performance","nodeData":"5.2.4"}]},{"id":112,"hasCaret":true,"label":"5.3 Storage Allocation and Garbage Collection","nodeData":"5.3","childNodes":[{"id":113,"hasCaret":false,"label":"5.3.1 Memory as Vectors","nodeData":"5.3.1"},{"id":114,"hasCaret":false,"label":"5.3.2 Maintaining the Illusion of Infinite Memory","nodeData":"5.3.2"}]},{"id":115,"hasCaret":true,"label":"5.4 The Explicit-Control Evaluator","nodeData":"5.4","childNodes":[{"id":116,"hasCaret":false,"label":"5.4.1 The Dispatcher and Basic Evaluation","nodeData":"5.4.1"},{"id":117,"hasCaret":false,"label":"5.4.2 Evaluating Function Applications","nodeData":"5.4.2"},{"id":118,"hasCaret":false,"label":"5.4.3 Blocks, Assignments, and Declarations","nodeData":"5.4.3"},{"id":119,"hasCaret":false,"label":"5.4.4 Running the Evaluator","nodeData":"5.4.4"}]},{"id":120,"hasCaret":true,"label":"5.5 Compilation","nodeData":"5.5","childNodes":[{"id":121,"hasCaret":false,"label":"5.5.1 Structure of the Compiler","nodeData":"5.5.1"},{"id":122,"hasCaret":false,"label":"5.5.2 Compiling Components","nodeData":"5.5.2"},{"id":123,"hasCaret":false,"label":"5.5.3 Compiling Applications and Return Statements","nodeData":"5.5.3"},{"id":124,"hasCaret":false,"label":"5.5.4 Combining Instruction Sequences","nodeData":"5.5.4"},{"id":125,"hasCaret":false,"label":"5.5.5 An Example of Compiled Code","nodeData":"5.5.5"},{"id":126,"hasCaret":false,"label":"5.5.6 Lexical Addressing","nodeData":"5.5.6"},{"id":127,"hasCaret":false,"label":"5.5.7 Interfacing Compiled Code to the Evaluator","nodeData":"5.5.7"}]}]},{"id":128,"hasCaret":false,"label":"References","nodeData":"references"},{"id":129,"hasCaret":false,"label":"Background","nodeData":"making-of"}]