99 lines
2.8 KiB
Common Lisp
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
|