(FIRST '(5 2 3)) (SECOND '(5 2 3)) (THIRD '(5 2 3)) (REST '(5 2 3 5 1 6)) (cons 1 '( 2 )) ; adds number to the list (cons 1 2) ; just a cons element (cons 'SINK '(OR SWIM)) ; adds symbol to the list (cons 'SINK 'SWIM) ; just a cons element with symbols (cons 'start nil) ; list is when last cons ends with `nil (cons 'start (cons 'end nil)) ; if we are to construct list from cons cells (and not from print notation) (cons 'nil 'nil) ; putting nil into CDR means having list with that item as CAR (cons '(PHONE HOME) nil) ;; even though `nil is same as '() many properties of lists hold only for non-empty lists, i.e ;; with at least one cons cell ;; for example main relationship between CAR, CDR & CONS (equal '(1 2 3 4) (cons (car '(1 2 3 4)) (cdr '(1 2 3 4)))) ;; doesn't work for () : (equal '() (cons (car '()) (cdr '()))) (cons (car '()) (cdr '())) ; => (NIL) ;;; exercises 3 (defun half (x) (/ x 2)) (defun cube (x) (* x x x)) (defun pythag (x y) (sqrt (+ (* x x) (* y y)))) ;; variables /are named by/ symbols, they are *not* symbols ;; funcitons are /aldo named by/ symbols ;;; symbols and lists as data ;; use ` - tilde to tell lisp interpreter ;; to treat symbol not as a name for variable (and evaluate to its value) ;; but to treat it as symbol (data) ;; ;; most symbols need to be quoted to be treated as symbols ;; some exceptions are t and nil which are self evaluating (defun riddle (x y) (list `why `is `a x `like `a y)) (riddle `raven `desk) ;;; Evaluation Rule for quoted Quoted Objects: ;;; quoted object evaluates to the object itself without the quote ;; 3 ways of creating lists `(foo bar baz) ; everything inside list is not evaluated (list `foo `bar `baz (* 33 33)) ; allows for "computed elements"" " (cons `foo `(bar baz)) ;; 3.11 (defun longer-than (l1 l2) (> (length l1) (length l2))) (defun call-up (caller callee) (list `hello callee `this `is caller `calling)) (defun crank-call (caller callee) `(hello callee this is caller calling)) ;; 3.22 c (defun myfun (a b) (list (list a) b)) ;; 3.22 d (defun firstp (item list) (equal item (first list))) ;; 3.22 e (defun mid-add1 (list) (cons (car list) (cons (+ 1 (cadr list)) (cddr list)))) ;; 33.2 f (defun f-to-c (farenheit-temp) (/ (* 5 (- farenheit-temp 32)) 9)) (symbol-name `equal) (symbol-function `equal) (symbol-name `lambda) (symbol-function `lambda) (eval (list `cons t nil)) ;;; equivalence of COND, IF, AND & OR - conditionals ;; (and x y z w) ;; (equal 1 1 1) (setq x 1 y nil z 1 w 1) (cond ((not x) nil) ((not y) nil) ((not z) nil) ((not w) nil) (t t)) (defun boilingp (temp scale) (cond ((and (equal scale `celsius) (> temp 100)) t) ((and (equal scale `farenheit) (> temp 212)) t))) (defun boilingp-2 (temp scale) (or (and (equal scale `celsius) (> temp 100)) (and (equal scale `farenheit) (> temp 212)))) (cond) ;; 4.28 (if (oddp 5) (evenp 7) `foo) (or (and (oddp 5) (evenp 7)) `foo) ;; not sure what's up with that ;; was that attempt to rewrite if into or&and? ;; So, that written correctly! I get stops because of forced debugger! ;; (step (eval (or (and (oddp 5) `(evenp 7)) ``foo))) (eval `(evenp 7)) (eval ``foo) (step (if (oddp 5) `yes `no)) (defun my-abs (x) (if (< x 0) (- x) x)) (step (my-abs 15)) ;;; variables & side-effects (defun price-change (old new) (let* ((diff (- new old)) (proportion (/ diff old)) (percentage (* proportion 100.0))) (list `widgets `changed `by percentage `percent))) ;;; 5.6 die exercise (defun throw-die () "Return random value [1 6]." (+ 1 (random 6))) (defun throw-dice () "Return list of 2 random die trows" (list (throw-die) (throw-die))) (defun snake-eyes-p (throw) "True if both dice in throw equal to 1." (and (equal 1 (first throw)) (equal 1 (second throw)))) (defun boxcars-p (throw) "True if both dice in throw equal to 6." (and (equal 6 (first throw)) (equal 6 (second throw)))) (defun instant-win-p (throw) "True if sum of dice in throw is 7 or 11" (let ((sum (+ (first throw) (secon throw))) (special-values (list 7 11))) nil)) ;; they meant type of word that is an article (setq articles `(the a an)) (defun contains-article-p-1 (list) "Check whether article contains in the list." (intersection articles list)) (setq test-sentence `(we will rock the boat)) ;; checks for each article (mapcar (lambda (article) (member article test-sentence) ) articles) ;; attempt to fold them into single boolean with or (apply `or (mapcar (lambda (article) (member article test-sentence) ) articles)) (step (apply `+ `(1 2 3))) (apply `equal `(2 3)) (equal 2 3) (or nil nil t) (apply `or `( nil nil t)) (step (apply `or (list nil nil nil))) (setq comparing-sentence `(large red shiny kube -vs- small shiny red four-sided pyramid)) (list (length (intersection (cdr (member `-vs- comparing-sentence)) (cdr (member `-vs- (reverse comparing-sentence))))) `common `features) ;;; 6.9 programming with tables (as lists) (setq table1 `((object1 large green shiny cube) (object2 small wihte dull cube) (object3 large red shiny pyramid) (object3 green shiny sphere))) (setf quality-table `((green . color) (red . color) (white . color) (cube . shape) (pyramid . shape) (sphere . shape) (shiny . luster) (dull . luster) (large . size) (small . size) )) (defun quality (x) "Get from hardcoded table." (cdr (assoc x quality-table)) ) (defun description (key) "Get description of object from hardcoded table." (cdr (assoc key table1))) (description `object2) ;; notion of ~sublis~ function instead of mapcar for getting types of properties (defun differences (x y) "Get different properties from hardcoded table." (set-exclusive-or (description x) (description y))) (differences `object1 `object2) (remove-duplicates (sublis quality-table (differences `object1 `object2))) ;;; 6.35 finite state automata (setq nerd-states `((sleeping . eating) (eating . waiting-for-a-computer) (waiting-for-a-computer . programming) (programming . debugging) (debugging . sleeping))) (defun nerdus (current-state) "Return next state for the nerdus in the provided CURRENT-STATE." (cdr (assoc current-state nerd-states))) (nerdus `programming) (defun sleepless-nerd (current-state) "Nerd that never sleeps." ;; consequtive `sleep -> sleep` considered to be impossible (let ((possible-state (nerdus current-state))) (if (equal possible-state `sleeping) (nerdus `sleeping) possible-state))) (sleepless-nerd `sleeping) (sleepless-nerd `debugging) (nerdus `playing-guitar) (defun nerd-on-caffeine (current-state) "Advancing two states in one step." (nerdus (nerdus current-state))) (nerd-on-caffeine `sleeping) ;; nested lists are trees and there are functions that can be used on them (subst `bb `aa `(In this list symbol aa would be substituted)) ;; args are NEW OLD TREE ;; and whole tree structure is checked: (subst `bb `a `((a tree) In this list symbol (a hatter) aa would be substituted (a test))) ;; sublis takes many substitutions, instead of first two args, the plist (defun royal-we (sentence) "Substitute all I to We." (subst `we `i sentence)) ;;; eq compares addresses, so lists would not be eq ;;; equal compares elements of the lists ;; symbols are singletons, so using ~eq~ is ok ;; numbers might not be primitive in lisp implementations! ;; ;; eql - compares addresses in general case, for numbers: if of the same type compares values (eql 3 3) (eql 3 3.0) ;; to test value of the numbers across types ;; but works only with numbers, ok! (= 3 3.0) ;;; Keyword arguments :keyword-symbol ; evaluates to self, cannot change value keyword-symbol ; different and not equal to actual keyword (symbolp :keyword) (keywordp :keyword) (keywordp `keyword) ;;; 7.3 Applicative programming ;; one of the styles, along with recursive and iterative (funcall #'cons 'a 'b) (setf fn #'cons) fn (type-of fn) (funcall fn 'c 'd) ;; using mapcar (defun squaring (x) "Square input." (* x x)) (squaring 9) (squaring '(1 2 2 3)) (mapcar #'squaring '(1 2 2 3 9)) (mapcar #'zerop '(20 340 0 -5 -6)) (mapcar #'(lambda (x) `(hi there ,x)) '(joe fred martha)) ;; 195 (funcall #'(lambda (x) (or (equal x t) (equal x nil))) 1) (defun half (x) "" (/ x 2.0)) (defun average (x y) "" (+ (half x) (half y))) (defun fact (n) "" (cond ((zerop n) 1) (t (* n (fact (- n 1)))))) (fact 4)