Вы должны понимать, как пара представлена . Пара состоит из трех вещей: первого элемента, второго элемента и функции. Наиболее важно, что два элемента не доступны «напрямую» (хотя см. Ниже): вы можете только получить к ним доступ через третий член пары. Эта функция принимает другую функцию и возвращает результат применения этой функции к двум «скрытым» элементам.
car
принимает парную функцию и применяет ее к функции, которая возвращает первый из двух аргументов.
cdr
принимает парную функцию и применяет ее к функции, которая возвращает второй из двух своих аргументов.
Вы можете отследить это следующим образом, это будет проще, если переписываешь cons = lambda a, b: lambda f: f(a, b)
:
car(cons(3, 5)) == cons(3, 5)(lambda x, y: x)
== (lambda a, b: lambda f: f(a, b))(3, 5)(lambda x, y: x)
== (lambda f: f(3, 5))(lambda x, y: x)
== (lambda x, y: x)(3, 5)
== 3
cdr(cons(3, 5)) == cons(3, 5)(lambda x, y: y)
== (lambda a, b: lambda f: f(a, b))(3, 5)(lambda x, y: y)
== (lambda f: f(3, 5))(lambda x, y: y)
== (lambda x, y: y)(3, 5)
== 5
cons(3, 5)
по существу сохраняет значения 3 и 5 в атрибуте __closure__
создаваемой им функции pair
.
>>> p1 = cons(3, 5)
>>> p1.__closure__[0].cell_contents
3
>>> p1.__closure__[1].cell_contents
5