common-lisp-study/recursion.lisp

101 lines
2.7 KiB
Common Lisp

(null 'a)
(null ())
(null nil)
(defun anyoddp (x)
(cond ((null x) nil)
((odd (first x)) t)
(t (anyoddp (rest x)))))
(trace anyoddp)
(anyoddp (list 6 1))
(untrace)
(rest '(5 4 3 2 1))
;;; my error was - function wasn't named odd, it was oddp
;;; and in the debugger it looked like:
;;; ("undefined function" 6)
;;; and I thought that 6 was treated as undefined function in list (6 1) for some reason
(defun laugh (n)
(defun laugh-inner (n acc)
(cond ((eq 0 n) acc)
(t (laugh-inner (- n 1) (cons 'HA acc )))))
(laugh-inner n ()))
;; I tried to use append
;; but how the hell do I add elements to list?
;; do I just fucking manually create cons? ugh
(cons 1 '(4 5 6))
(laugh 4)
(defun square-list (x)
(cond ((null x) ())
(t (cons (* (first x) (first x))
(square-list (rest x))))))
(square-list '(1 3 5 6))
;;; count atoms.
;;; recursion on nested lists - think of them as binary trees, with car and cdr, that's it
(atom 1)
(defun count-atoms (tree)
(cond
((null tree) 0) ; without that ends of lists would be counted, but didn't include that due to misunderstanding
((atom tree) 1)
(t (+ (count-atoms (car tree))
(count-atoms (cdr tree))))))
(count-atoms '(1 (4 5) 2 ))
(defun pairings (x y)
(cond ((or (null x) (null y)) ())
(t (cons (list (first x) (first y))
(pairings (rest x) (rest y))))))
(pairings '(1 2 3 7) '(a b c d))
;;; looking into debugger
(defun my-fact (n)
(cond ((zerop n) (break "N is zero")
;; 1
)
(t (* n (my-fact (- n 1))))))
(my-fact 4)
;;; So - debugger keys and functions
;; C-j and C-k are for moving between frames
;; for frame context commands R - return from frame with particular value (sly-db-return-from-frame)
;; x - step over, s - step
;; e - eval in frame, i - inspect in frame (show additional info on evaluated value)
;; RET - toggle details for current frame
;; v - show frames code
;; d - pretty-print-eval-in-frame
;; (searching all of functions by going into debugger bugger and looking at *helpful* (C-h C-f) "sly-db-"
;; could also try to recompile thing, maybe r for restart, or R to return with value 1 from last frame and check how it all works
;;; better way to define inner functions : LABELS
;;; similar to LET form, binding names to arglists and body
;;; they are "local functions"
;;; can call each other, and reference parent variables
(defun factor-tree (n)
(factors-help n 2))
(defun factors-help (n p)
(cond
((equal p n) n)
((zerop (rem n p)) (list n p (factors-help (/ n p) p)))
(t (factors-help n (+ 1 p)))))
(factor-tree 60)
(trace factors-help)
(untrace) ; and there's no need to try to do println, and less errors in that