common-lisp-study/iteration-and-block-structu...

99 lines
2.8 KiB
Common Lisp

;; (dotimes (index-var n [result-form]
;; body)
;;
;; (dolist (index-var n [result-form]
;; body)
;;
;; result for is a thing to return, but is that joined from iterations?
(dotimes (x 5 `(list ,x))
(format t "~&iterating ~S" x))
;; i guess that's from the last
(dolist (x '(red blue green) 'x)
(format t "~&Roses are ~S" x)
(if (equal x 'blue) (return x)))
;;; so [result-form] is returned if iteration reaches the end
(assoc 'key1 '((key1 . value1) (key2 . "hello")))
(assoc 'key1 '((key1 value1) (key2 "hello")))
;;; applicative squaring with mapcar are simpler
;;; for the iterative, first get local variable around list, and return statement reverse it
(defun it-square-list (x)
(let ((result nil))
(dolist (i x (reverse result))
(push (* i i) result))))
(it-square-list '(1 2 4 10))
;; the DO macro is "most powerful" iteration in CL
;; (DO ((var1 init1 [update1])
;; (var2 init2 [update2]))
;; (test action1 action2 ... action-n)
;; body)
;; so, vars might not have update expressions
;; first assing vars, evaluate test, if test - to exit - evaluate end actions
;; if not test - evaluate body, then run updates to variables and repeat
(defun launch (n)
(do ((cnt n (- cnt 1)))
((zerop cnt) (format t "Blast off!~&"))
(format t "~S..." cnt)))
(launch 10)
(launch 20)
;; would be cool to find some kind of 2/3 dimentinal problem to be solved clearly with DO
;; like walking aroung the array
;; also - body can have (return [value]) expressions!
;; so nil can be exit expression, for infinite iteration
(defun read-a-number ()
(do ((answer nil))
(nil)
(format t "~&Please input a number: ")
(setf answer (read))
(if (numberp answer) (return answer)
(format t "~&Sorry, ~S is not a number. Try again." answer))))
;;; Blocks.
;; implicit blocks are bodies of function, with function name being a block name
;; and RETURN-FROM can be used to exit block
;; DO, DOLIST, DOTIMES are wrapped with block with name nil, so RETURN is just RETURN-FROM nil
;; but we can to return from function, short circuiting
(defun my-square-list (x)
(mapcar (lambda (i)
(if (numberp i) (* i i)
(return-from my-square-list `nope))) x))
(my-square-list '(1 2 51 4))
(my-square-list '(1 3 5 "hello" 4))
;; and can create explicitly with BLOCK function?
;; and use RETURN-FROM from inside that block? what about from inside functions that are called in the block?
(defun print-and-exit-my-block ()
(format t "~&in the function")
(return-from my-block))
(block my-block
(format t "~&Entering my block")
(print-and-exit-my-block) ; gets error - unknown block, so YAY
(format t "~&After calling function in my block"))
;;; Exercise
;;; about dna things
;; progn, prog1, prog2
;; prog1 returns value of first expression
;; prog2 -//- of second expression
;; progn -//- of last