正在加载图片...
6.001 Structure and Interpretation of Computer Programs. Copyright o 2004 by Massachusetts Institute of Technology Slide 9.1.13 How do we add a label to our complex numbers? Let's just glue Labeled complex numbers it onto the front We can change our constructor to have the ( define(make-complex-from-rect rl im) following behavior. Given two parts, we will just glue them list ' rect rl im)) together into a list. But if the parts represent real and imaginary ( define( make-complex-from-polar mg an) components, we will put a symbolic label at the front to tell us(define (tag obj)(car obi) this, while if the parts are magnitude and angle, we will still just( define(contents obi) (edr objy glue them together but we'll put a different label at the front to tell us this What else do I need? I'll want a selector to pull the labels off of hese new abstractions, as well as a selector to get out the actual contents of the abstraction Notice the use of cdr in this cased 6001 SCP to get the remaining list of elements from the representation Note that in this case we are not doing any work to convert representations. We just glue the parts together, and put label on it so we know what those parts mean Labeled complex numbers Slide 9.1.14 ( define(make-complex-from-rect rl im To make sure my contract holds, I'll need to adjust my selectors Here is where I am going to bury the work I just saved in (define(make-complex-from-polar mg an constructing numbers. i will have a single selector real that (define(tag obj)(car obj) works with numbers represented in either form. This selector (define(contents obj)(cdr obj)) will first rip the tag off of the number to see who made it. Notice how we use eq? to test equality of symbols, and how we use (cond ((eq?(tag z)rect)(car(contents z))) the selector tag to get out the tag, and how we use the quoted (eq?(tag 2)polan( e lf adr (contents z2):angle symbols to represent the things to check against the tag (else (error "unknown for object ))) If this is in fact a Cartesian number. we use contents to 03P get everything but the tag, then can use car to get the real part since that is where it is stored in this representation, just as Bert did it If this is a polar number, then we have to do the work to convert the underlying representation from polar form to the real part. In this case, contents will get the actual representation, and the car of that list we know is the magnitude of the vector. Similarly the cadr gets us the angle, and we can then do the trigonometry to convert to the real part Thus in this case, my constructor just glues pieces together, with an appropriate label. My selectors use the label to tell me how to interpret the pieces, and thus what additional work I may have to do to convert those pieces to the esired value Slide 9.1.15 Labeled complex numbers Note the key point here. It's not that I am dealing with complex (define(make-complex-from-rect rl im numbers,they simply provide the motivation. The key point is(list rect rd im) that now I can use any of the procedures I wrote to manipulate (define(make-complex-from-polar mg an complex numbers on any kind of complex number. Thus (list polar mg an)) independent of whether a complex number is actually glued (define(tag obj)(car ob)) together in Cartesian or polar form, the same procedure applies To make this happen, I use tags(or types)to tell the selectors (cond ((eq?(tag z)rect)(car(contents z))) which pieces to pull out, and what to do to convert the pieces to (eq?(tag z)polar)((car(contents z)'mag the right form. And these tags are exactly what support the idea (else (error "unknown form of object)))) of having different versions of the same abstraction be handled 6001联0 by the same procedures6.001 Structure and Interpretation of Computer Programs. Copyright © 2004 by Massachusetts Institute of Technology. Slide 9.1.13 How do we add a label to our complex numbers? Let's just glue it onto the front. We can change our constructor to have the following behavior. Given two parts, we will just glue them together into a list. But if the parts represent real and imaginary components, we will put a symbolic label at the front to tell us this, while if the parts are magnitude and angle, we will still just glue them together but we'll put a different label at the front to tell us this. What else do I need? I'll want a selector to pull the labels off of these new abstractions, as well as a selector to get out the actual contents of the abstraction. Notice the use of cdr in this case to get the remaining list of elements from the representation. Note that in this case we are not doing any work to convert representations. We just glue the parts together, and put a label on it so we know what those parts mean. Slide 9.1.14 To make sure my contract holds, I'll need to adjust my selectors. Here is where I am going to bury the work I just saved in constructing numbers. I will have a single selector real that works with numbers represented in either form. This selector will first rip the tag off of the number to see who made it. Notice how we use eq? to test equality of symbols, and how we use the selector tag to get out the tag, and how we use the quoted symbols to represent the things to check against the tag. If this is in fact a Cartesian number, we use contents to get everything but the tag, then can use car to get the real part, since that is where it is stored in this representation, just as Bert did it. If this is a polar number, then we have to do the work to convert the underlying representation from polar form to the real part. In this case, contents will get the actual representation, and the car of that list we know is the magnitude of the vector. Similarly the cadr gets us the angle, and we can then do the trigonometry to convert to the real part. Thus in this case, my constructor just glues pieces together, with an appropriate label. My selectors use the label to tell me how to interpret the pieces, and thus what additional work I may have to do to convert those pieces to the desired value. Slide 9.1.15 Note the key point here. It's not that I am dealing with complex numbers, they simply provide the motivation. The key point is that now I can use any of the procedures I wrote to manipulate complex numbers on any kind of complex number. Thus, independent of whether a complex number is actually glued together in Cartesian or polar form, the same procedure applies. To make this happen, I use tags (or types) to tell the selectors which pieces to pull out, and what to do to convert the pieces to the right form. And these tags are exactly what support the idea of having different versions of the same abstraction be handled by the same procedures
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有