common-lisp-study/basics.lisp

366 lines
8.9 KiB
Common Lisp

(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)