; Notes
; -----

; 1. In this lecture, we have used "define" to define commonly used
; functions. However, we can write the whole program with all the functions
; defined by such constructs:

(

(
lambda
(succ
)

(

;;; Do something with succ - for example:

(succ
(
lambda
(f
)
(
lambda
(x
)
(f
(f
(f x
))))))

)

)

; This is the definition of succ that is accepted as a value to the

; function call.

(
lambda
(n
)

(
lambda
(f
)

(
lambda
(x
)

(f
((n f
) x
))

)

)

)
)

; 2. Representing arrays: arrays (a.k.a vectors) can be constructed using
; a binary tree complex of pairs whose leaves are the array's values.

; 3. Church Numerals are base-1 numbers so they are not very efficient. If
; you strive for calculation efficiency in lambda calculus you may wish
; to represent numbers as vectors of digits, and define calculations on them
; using Al-Khwarizmi's algorithms.

; 4. In order to do things like write to the screen, to files, or etc. You
; need to supply the lambda calculus program with stubs. That way, everything
; can be done in LC.

; 5. It was proved that every recursive function can be implemented in
; Lambda Calculus.

; 6. Lambda Calculus is fairly easy to write in languages that support lexical
; scoping and closures. For example: Scheme, Perl, Python and ML
; can all do LC without any special programming.

; In other languages, like C, Pascal, Assembly or Basic, one can implement
; Lambda Calculus using a stack. I don't remember the exact details, but it's
; possible.

; 7. One can define Y-like combinators that take functions of more than
; one argument (I mean (lambda (x) (lambda (y) ... ))). For example, the
; two-argument Y is:

(
define Y2

(
lambda
(g
)

(

(
lambda
(f
)

(g
(
lambda
(x
)
(
lambda
(y
)
(((f f
) x
) y
))))

)

(
lambda
(f
)

(g
(
lambda
(x
)
(
lambda
(y
)
(((f f
) x
) y
))))

)

)

)
)

; 8. Instead of using pairs one can use a three-object tuple, or a four object
; tuple, etc. For example, the definition of the three-item tuple functions
; are:

(
define lc-cons-tuple3

(
lambda
(first
)

(
lambda
(second
)

(
lambda
(third
)

(
lambda
(which
)

(((which first
) second
) third
)

)

)

)

)
)

(
define tuple3-get-first

(
lambda
(tuple
)

(tuple
(
lambda
(x
)
(
lambda
(y
)
(
lambda
(z
) x
))))

)
)

(
define tuple3-get-second

(
lambda
(tuple
)

(tuple
(
lambda
(x
)
(
lambda
(y
)
(
lambda
(z
) y
))))

)
)

(
define tuple3-get-third

(
lambda
(tuple
)

(tuple
(
lambda
(x
)
(
lambda
(y
)
(
lambda
(z
) z
))))

)
)

; 9. It is sometimes useful to make a lambda expression into a tuple in which
; its car is a Church numeral that denotes its type, and specifies whether
; the cdr is a tuple, a church numeral, a function, a vector, etc.

; 10. Lambda Calculus still has a certain degree of arbitrarity. For example:
; Church numerals could have been defined as:

(
define zero
(
lambda
(x
)
(
lambda
(f
) x
)))
(
define one
(
lambda
(x
)
(
lambda
(f
)
(f x
))))
(
define two
(
lambda
(x
)
(
lambda
(f
)
(f
(f x
)))))

; Etc.
; Or true could have been defined as false and false as true...