exercises and notes from "Gentle introduction"
This commit is contained in:
365
basics.lisp
Normal file
365
basics.lisp
Normal file
@@ -0,0 +1,365 @@
|
||||
(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)
|
||||
Reference in New Issue
Block a user