"Ordinary" functions are usually only defined on a domain of objects of a given type, but certain functions, such the Scheme type predicates list? or procedure?, are defined for arguments of any type, and can even be applied to themselves. So e.g. (list? procedure?) evaluates to #f and (procedure? procedure?) evaluates to #t. I am trying to figure out how one would write a totally defined function of this sort, but haven't been able to find a source that discusses this.
For example, suppose we implement a pair data type as described in Exercise 2.4 of Structure and Interpretation of Computer Programs using the following constructor and selectors:
(define (cons x y)
(lambda (m) (m x y)))
(define (car z)
(z (lambda (p q) p)))
(define (cdr z)
(z (lambda (p q) q)))
How would I then define a predicate pair? that returns #t for anything that was constructed using cons, and #f for anything that wasn't? More generally, how are type predicates like list? and procedure? implemented?
pair?as a list that is not null, and whose cdr is not null, but where recursion on the cdr is#f. I'm pretty sure thelist?predicate needs to be a built-in function, as it's too fundamental. - d11wtq(define (list? x) (and (pair? x) (or (null? (cdr x)) (list? (cdr x)))))checks whether an argument object is a finite proper list.pair?only checks whether it is a cons cell data object.(let ((a (list 1))) (set-cdr! a a) (pair? (cdr a)))must be able to return#t. - Will Ness