6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology what value to return We call this style of programming, message passing, because the procedure accepts a message as input, and then does something based on the value of that Slide 13. 2.3 Example: Pair as a Procedure with State This looks a bit weird! Our constructor for gluing things together gives us a procedure as the actual object. Should we (lambda (cond ((eq? msg CAR) x) Of course we know that we shouldn't care. To complete the ((eq? msg 'PAIR2) #t abstraction for a pair, we simply need to create car and cdr t”m8))))) to fulfill the contract of the abstraction of a pair (odr p) (p CDR)) Each of those is itself a procedure that takes as input a pair, to a single argument, which in this case is just a symbole qure which we know is a procedure, and then applies that procedi message. Ideally, that message should get back for us the value we need to satisfy the contract. If we look at this definition for car, we see it takes as input one of these new pairs, and then applies that pair(a procedure) to the symbol carr which in principle should return for us the value we used when we created the pair Note the other procedure we built here. Our predicate for testing whether something is a pair now relies on the identifying itself. This is the version of our tag. Before we attached a tag as a symbol on a data structure. Here tags are part of the procedure Example: What is our"pair"object? Slide 13.2.4 To check it out, let,'s take this strange implementation of pairs and verify that this implementation satisfies the contract for a Slide 13. 2.5 Example: What is our"pair object? To test this, lets cons together the numbers l and 2, and give the resulting pair the name foo (det ine too (cons 1 2)) 600SC
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. what value to return. We call this style of programming, message passing, because the procedure accepts a message as input, and then does something based on the value of that message. Slide 13.2.3 This looks a bit weird! Our constructor for gluing things together gives us a procedure as the actual object. Should we care? Of course we know that we shouldn't care. To complete the abstraction for a pair, we simply need to create car and cdr to fulfill the contract of the abstraction of a pair. Each of those is itself a procedure that takes as input a pair, which we know is a procedure, and then applies that procedure to a single argument, which in this case is just a symbolic message. Ideally, that message should get back for us the value we need to satisfy the contract. If we look at this definition for car, we see it takes as input one of these new pairs, and then applies that pair (a procedure) to the symbol car, which in principle should return for us the value we used when we created the pair. Note the other procedure we built here. Our predicate for testing whether something is a pair now relies on the pair identifying itself. This is the version of our tag. Before we attached a tag as a symbol on a data structure. Here, our tags are part of the procedure. Slide 13.2.4 To check it out, let's take this strange implementation of pairs and verify that this implementation satisfies the contract for a pair. Slide 13.2.5 To test this, lets cons together the numbers 1 and 2, and give the resulting pair the name foo
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 13.2.6 Example: What is our"pair"object? So here is an environment diagram that would represent the (define foo (cons 1 2)) state of the world, before we do this definition. In the global environment, we would have a binding for cons as a procedure, based on the previous slide 6 001 SICP Slide 13.2.7 Example: What is our"pair object? What happens when we evaluate this expression? Since cons (define too (ooms 1 2))P is just a procedure, evaluating (cons 1 2) says to apply the procedure associated with cons to the arguments I and 2 Thus, we drop a frame, scope it by the environment pointer of the procedure, bind the formal parameters(X and y) of the procedure to the values of the arguments, and relative to that new frame, and evaluate the body of the procedure. That body is itself a lambda! So it makes a new procedure object whose environment pointer points to the frame El because that where the l ambda was evaluated. Then, the procedure object is returned as the value of the cons. Finally, the define binds foo in the global environment to this returned value, this procedure object Example: What is our "pair object? Slide 13.28 Notice what this does. It gives us an object in this environment, (olefine too where by object I mean the thing enclosed in red, which is a procedure that has a local frame with some bindings or values within it. Thus, x being bound to 1, and y being bound to 2 constitutes local state information. That frame is scoped by the global environment, and the procedure that points to all of this is referred to by a name in the global environment. Thus, from the perspective of a user interacting at the global environment, foo refers to a structure that has within it information about 6001Sc I what is the first part of the object(1)and what is the second part of the object (2). It should also have information about how to extract those values from the structure So this pattern: of a procedure that accepts messages, has access to a local frame with state and methods to extract that local state; is a very common pattern that we are going to use a lot
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 13.2.6 So here is an environment diagram that would represent the state of the world, before we do this definition. In the global environment, we would have a binding for cons as a procedure, based on the previous slide. Slide 13.2.7 What happens when we evaluate this expression? Since cons is just a procedure, evaluating (cons 1 2) says to apply the procedure associated with cons to the arguments 1 and 2. Thus, we drop a frame, scope it by the environment pointer of the procedure, bind the formal parameters (x and y) of the procedure to the values of the arguments, and relative to that new frame, and evaluate the body of the procedure. That body is itself a lambda! So it makes a new procedure object, whose environment pointer points to the frame E1 because that is where the lambda was evaluated. Then, the procedure object is returned as the value of the cons. Finally, the define binds foo in the global environment to this returned value, this procedure object. Slide 13.2.8 Notice what this does. It gives us an object in this environment, where by object I mean the thing enclosed in red, which is a procedure that has a local frame with some bindings or values within it. Thus, x being bound to 1, and y being bound to 2 constitutes local state information. That frame is scoped by the global environment, and the procedure that points to all of this is referred to by a name in the global environment. Thus, from the perspective of a user interacting at the global environment, foo refers to a structure that has within it information about what is the first part of the object (1) and what is the second part of the object (2). It should also have information about how to extract those values from the structure. So this pattern: of a procedure that accepts messages, has access to a local frame with state and methods to extract that local state; is a very common pattern that we are going to use a lot
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 13.2.9 Now all we have to do is check that the contract holds for thisExample: What is our"pair"object? data abstraction. In doing so, we will see how this structure of a (cons 1 2)) procedure with access to local state captures exactly the becomes(f∞tCR) behavior we want To check this, lets evaluate(car foo). We know that this"as should get converted into (foo car), so how does this happen? 6001 sICP Example: What is our"pair"object? Slide 13.2.10 aluating(car foo) in the globa ( Define foo(cons12)】 (car fod) becomes (foo 1CRR) applies the procedure that is the value associated with car to the value of foo which is the procedure object shown. Now he definition of car shows that this reduces to evaluating the body of car namely (foo 'car)with respect to some po new environment Slide 13.2.1 Example: What is our "pair object? and what does that do? It says to apply the value associated with foo, which is a procedure, so the standard environment (cons 1 2)) model says to drop a frame, and scope it by the environment ar foo) becomes (foo .CAR) pointer of foo. This is important as E3 now points to E1 Inside e3 we bind the parameter ms g to the argument car Relative to this frame we evaluate the body of the procedure epresented by foo. but that is just a cond clause that looks at the value of ms g and compares it to a set of symbols. In this case, the cond says to return the value of x with respect to 60015e this frame, which is just 1. This is exactly what I wanted, as it shows that my contract is satisfied
6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 13.2.9 Now all we have to do is check that the contract holds for this data abstraction. In doing so, we will see how this structure of a procedure with access to local state captures exactly the behavior we want. To check this, lets evaluate (car foo). We know that this should get converted into (foo 'car), so how does this happen? Slide 13.2.10 Evaluating (car foo) in the global environment simply applies the procedure that is the value associated with car to the value of foo which is the procedure object shown. Now the definition of car shows that this reduces to evaluating the body of car namely (foo 'car) with respect to some new environment. Slide 13.2.11 ... and what does that do? It says to apply the value associated with foo, which is a procedure, so the standard environment model says to drop a frame, and scope it by the environment pointer of foo. This is important as E3 now points to E1. Inside E3 we bind the parameter msg to the argument car. Relative to this frame we evaluate the body of the procedure represented by foo. But that is just a cond clause that looks at the value of msg and compares it to a set of symbols. In this case, the cond says to return the value of x with respect to this frame, which is just 1. This is exactly what I wanted, as it shows that my contract is satisfied