(note: reply at the end of this post) Second function
(define (swap-ends x) ; swap [] = [] (if (or (equal (length x) 0) (equal (length x) 1)) ; swap [x] = [x] x ; swap (x:xs) (cons (first (swap-ends (rest x))) ; | (a:b) <- swap xs (swap-ends (cons (first x) ; = a : swap (x : b) (rest (swap-ends (rest x))))))))
(with Haskell translation in the comments), what are you doing, you ask? Data flow diagram for alternative if clause -
/-> first ----------------------> cons x --> first ------/-------------> cons --> swap --/ \-> rest -> swap ---> rest ---/
(follow the arrows from left to right). In this way,
[] -> [] [1] -> [1] /-> 2 -----------------------> [2,1] [1,2] --> 1 --------/------------> [1] --> [1] --/ \-> [2] -> [2] ---> [] ---/ /-> 3 -------------------------> [3,2,1] [1,2,3] --> 1 ------------/----------> [1,2] --> [2,1] --/ \-> [2,3] -> [3,2] -> [2] --/ /-----> 4 ----------------------------> [4,2,3,1] [1,2,3,4] --> 1 ------------/---------------> [1,3,2] -> [2,3,1] -/ \-> [2,3,4] -> [4,3,2] -> [3,2] -/
So far, it really replaces the finite elements of the list. Let this be proved by natural induction,
true(N-1) => true(N)
/-> N --------------------------------------> [N,2..N-1,1] [1..N] --> 1 ---------/-----------> [1,3..N-1,2] -> [2,3..N-1,1] -/ \-> [2..N] -> [N,3..N-1,2] / -> [3..N-1,2] -/
So this is proven. Thus, we need to develop a data flow diagram that, on the assumption of changing the list (N-1) -length, will change the list of N-lengths:
[1..N] --> 1 ------------------------------------\ \-> [2..N] -> [N,N-1..2] -> N -------------\------------------\ \-> [N-1,N-2..2] -> [2..N-1] -> [1..N-1] -> rev -> cons
What gives us the implementation
(define (rev ls) ; rev [] = [] (cond ; rev [x] = [x] ((null? ls) ls) ; rev (x:xs) ((null? (rest ls)) ls) ; | (a:b) <- rev xs (else ; = a : rev (x : rev b) (cons (first (rev (rest ls))) (rev (cons (first ls) (rev (rest (rev (rest ls)))))))))) (rev '(1 2 3 4 5)) ; testing ;Value 13: (5 4 3 2 1)
Haskell's translation in the comments follows the diagram quite naturally. This is really readable: a is the last element, b is the inverse "core" (that is, the input list without its first and last element), so we cancel the inverse core, add the first element to get the value of the input list, then cancel it and add the last item. Just.:)