; my version (def leftmost "The function leftmost finds the leftmost atom in a non-empty list of S-expressions that does not contain the empty list" (fn [l] (cond (null? l) '() (atom? (first l)) (first l) :else (leftmost (first l)))))
(def insertR* (fn [new old l] (cond (null? l) '() (non-atom? (first l)) (cons (insertR* new old (first l)) (insertR* new old (rest l))) true (cond (= (first l) old) (cons old (cons new (insertR* new old (rest l)))) true (cons (first l) (insertR* new old (rest l))))))) (println (insertR* 'chicken 'baked '(((baked)) (with roast) vegetables)))
;; v2 (def insertR* (fn [new old l] (cond (null? l) '() (atom? (first l)) (cond (= old (first l)) (cons old (cons new (insertR* new old (rest l)))) :else (cons (first l) (insertR* new old (rest l)))) :else (cons (insertR* new old (first l)) (insertR* new old (rest l))) ) ) )
When recurring on a list of atoms, lat, or a tup, tup, ask two questions about them, and use (rest lat) or (rest tup) for the natural recursion.
When recurring on a list of S-expressions, l, ask three questions: (null? l), (atom? (first l)), and (non-atom? (first l)); and use (first l) and (rest l) for the natural recursion.
When recurring on a number, n, ask two questions, and use (sub1 n) for the natural recursion.
(def subst* (fn [new old l] (cond (null? l) '() (non-atom? (first l)) (cons (subst* new old (first l)) (subst* new old (rest l))) true (cond (= (first l) old) (cons new (subst* new old (rest l))) true (cons (first l) (subst* new old (rest l))))))) (println (subst* 'baked 'creamy '(((creamy) cheesecake) (with (hot (espresso))))))
;; or (def subst* (fn [new old l] (cond (null? l) '() (atom? (first l)) (cond (= old (first l)) (cons new (subst* new old (rest l))) :else (cons (first l) (subst* new old (rest l)))) :else (cons (subst* new old (first l)) (subst* new old (rest l))))))
(def insertL* (fn [new old l] (cond (null? l) '() (non-atom? (first l)) (cons (insertL* new old (first l)) (insertL* new old (rest l))) true (cond (= (first l) old) (cons new (cons old (insertL* new old (rest l)))) true (cons (first l) (insertL* new old (rest l))))))) (println (insertL* 'fresh 'creamy '(((creamy) cheesecake) (with (hot (espresso))))))
;; or (def insertL* (fn [new old l] (cond (null? l) '() (atom? (first l)) (cond (= old (first l)) (cons new (cons old (insertL* new old (rest l)))) :else (cons (first l) (insertL* new old (rest l)))) :else (cons (insertL* new old (first l)) (insertL* new old (rest l))))))