sicp/chapter2/exercise-2.4
Lambda expression syntax
(Lambda kw-formals body)
Title Description
Rewrite the cons, car, CDR of the ordered pair with procedural representations
Scheme code
(define (cons-24 x y) (lambda (m) (m x y)))(define (car-24 z) (z (lambda (p q) p)))
This code is only 4 lines, but the logical relationship is not well understood.
The reason is that the top-down implementation of functional language does not conform to the general logic habit.
Lambda provides a common interface in the same way as a function pointer, which implements the function of dynamic binding.
Disassembly
(In order of bottom-up)
1-procedure_1 = (lambda (p q) p) Scheme semantics:
- Parameter format: p,q
- Body part: P, meaning is return p
C Implementation:
- There is no deeper nesting for the complete function body.
- P,q defined as int type
int GetCar(int p,int q){return p;}
2-(define (car-24 z) (z procedure_1)) scheme semantics:
- CAR-24 accepts a parameter Z
- Body part: Because (z procedure_1), can judge Z as a function, its parameter is Procedure_1
- The parameter of function z is procedure_1 as a function (see 1)
C Implementation:
- A procedure_1 function framework should be defined first (see 1 for a function instance)
typedef int (*procedure_1)(int,int)
- Then according to (Z Procedure_1) can write out the car-24 parameter Z frame, the return value inherits from M:
typedef int (*ARG_Z)(procedure_1)
- The car-24 parameter is Z, and the return value inherits from Z. This allows you to write a car-24 function framework:
int car-24(ARG_Z z){ return z(procedure_1);//只实现框架,并未绑定实例}
- Because the instance of Procedure_1 is already in the define of car-24, at this point m has a function implementation that can be bound. Car-24 thus becomes:
int car-24(ARG_Z z){ return z(GetCar);}
3-procedure_2 = (lambda (m) (m x y) scheme semantics:
- Parameter format--receives an m as a parameter
- Because the body part of the Lambda (m) is (m x y), the M is a process, and the process m requires two parameters, X and Y.
C Implementation:
- There is only a function frame but no concrete implementation, similar to a function pointer. The concrete implementation needs to instantiate the abstraction, so the return value cannot be determined.
- First define the frame of the parameter m:
typedef unknown (*m)(x,y);
- You can then write out the procedure_2 frame:
typedef unknown (*procedure_2)(m);
- The return value is unknown, depending on the binding type. The return value of Procedure_2 is inherited from M
4-(define (cons-24 x y) procedure_2) scheme semantics:
- Parameter format is x, y
- The body part is the procedure_2 of the previous analysis, so this define generates a process that requires the X y parameter to be accepted.
C Implementation:
Currently, the inner layer function is not bound, only the framework is given. The only certainty is that the return value is the procedure_2 type, which returns a function pointer.
typedef procedure_2 (*cons-24)(x,y)
(Disassembly completed)
Binding Process Instance
(define test (cons-24 1 2))(car-24 test)
Procedure 1-Generates a cons-24 instance named test that requires a procedure as a parameter to the parameters 2-car-24 the test,car-24 built-in Getcar function as the parameter of its parameter test, the implementation function is test (GETCAR). 3-The difficulty of logical comprehension:
- The framework and data are given in cons-24 without any processing; instead, the entire framework is abstracted into a variable of a procedure (or abstract as a function pointer).
- When used, car-24 receives this function pointer, passing its own built-in function to the function pointer as a parameter, forming a nested link.
- Car-24 is just a wrapper over built-in functions, adding a shell to the built-in functions
- Normal use between the two parts requires a default rule: The car-24 parameter must be a cons-24 type procedure. This is not logically reflected.
- From the point of view of C, the hierarchical relationships between functions are not clear and interdependent.
- But only from the point of view of abstract interfaces, a fairly good process interface is provided. A three-level nested definition is required if the C function is implemented. This shows the difference between functional language and process-oriented language.
A small example of lambda expression and function pointer in scheme