Added lisp along with some study work

This commit is contained in:
2017-06-23 02:16:42 -07:00
parent 0523d93916
commit 0d49347cb7
10 changed files with 496 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
;example of printing proper
;t indicates that the output is to be sent to the default place
; normally this will be toplevel
; ~% indcates newline
; it's like printf
;(format t "~A plus ~A equals ~A.~%" 2 3 (+ 2 3))
;user-input
(defun askem (string)
(format t "~A" string)
(read))
;example
;(format t "You wrote: ~A ~%" (askem "What is you????? "))
;user-input plus variables
(defun ask-number ()
(format t "Please enter a number. ")
;;;create a variable "val" to store read (first two arguments of let)
(let ((val (read)))
;;;;Now after asigning values in let, we can do expressions
;;;;Note that the variables are local to the let block
;;;;Test if val is number
(if (numberp val)
val
(ask-number))))
;example
;(format t "~A~%" (ask-number))
;global variables
;The asterisks are simply a standard to show that the variable is global
(defparameter *glob* 99)
;global constants can be declared as such
;They don't need special names because if they share the name of a variable
;it'll throw an error
(defconstant limit (+ *glob* 1))
;We can check if a symbol is the name of a global variable/constant like this
;(format t "~A~%" (boundp '*glob*))
;(format t "~A~%" (boundp 'limit))
;The most general assignment operator is setf
(setf *glob* 98)
(format t "~A~%" (let ((n 10))
(setf n 2)
n))
;If the first arg to setf is a symbol that is not a local variable, it is
;taken to be global and thus creates one if it didn't exist already
;Note that this is bad practice because it pisses off my linter
;also, implicit declarations are weird.
;(setf x (list 'a 'b 'c))
;(format t "~A~%" x)
; we could also do something like (assuming the above code has also happened)
;We can use an expression instead of a variable. In these cases the second
;argument is inserted in the place refered by the first arg
;So here:
;(setf (car x) 'n)
;We would be replacing the A in (A B C) with an N
;You can also give any even about of arguments to setf... so...:
;(setf a b
; c d
; e f)
;Would be equivalnt to doing three seperate setf statements
;print out the square of the integer from start to end
;do works as (variable inital update)
;So here we have the first arg:
;;;i is set to start and then updates by 1
;The next argumen to (do) is when the test should end and
;;;what happens after end
;The third and last argument is what's actually happening (the format list)
(defun show-squares (start end)
(do ((i start (+ i 1)))
((> i end) 'done)
(format t "~A ~A~%" i (* i i))))
;Recursive version
;progn can take any number of expressions, it evaluates them in order, and
;returns the value of the last
(defun show-square-rec (i end)
(if (> i end)
'done
(progn
(format t "~A ~A~%" i (* i i))
(show-squares (+ i 1) end))))
;function that iterates through a list
;dolist takes an argument as (variable expression) followed
;by a body of expressions
(defun our-length (lst)
(let ((len 0))
(dolist (obj lst)
(setf len (+ len 1)))
len))
;rec version
(defun our-length-rec (lst)
(if (null lst)
0
(+ (our-length (cdr lst)) 1)))
;define function tha takes two arguments and returns the greater
(defun is-greater (arg1 arg2)
(if (> arg1 arg2)
(format t "~A~%" arg1)
(format t "~A~%" arg2)))

View File

@@ -0,0 +1,26 @@
;; Take a positive int and print that many dots
;; repetition
(defun print-dots(num-of-dots)
(do ((i 0 (+ i 1)))
((= i num-of-dots) 'done)
(format t ". ")))
;; recursion
(defun print-dots-rec(num-of-dots)
;plusp checks if it's a positivie integer above 0.0
(if (plusp num-of-dots)
(progn
(format t ". ")
(print-dots-rec(- num-of-dots 1)))))
;; Take a list and return the number of times the symbol "a" occurs in it
(defun count-a-symbols(lst)
(do ((new-lst lst (cdr new-lst))
(n 0 (+ n (if (eq (car new-lst) 'a) 1 0))))
((not new-lst) n)))
;; Now do a recursive version (which is probably easier)
(defun count-a-symbols-rec(lst)
(if lst
(+ (if (eq (car lst) 'a)1 0) (count-a-symbols-rec(cdr lst)))
1))

View File

@@ -0,0 +1,85 @@
(eql x y) -- Tests of it's the same object
(setf x '(a b c))
(setf y x) -- This will copy the poiner, so any changes to either will affect the other.
(setf x '(a b c)
y (copy-list x)) -- This will actually create a new list (eql x y) will return nil
(append '(a b) '(c d) '(e)) -- append lists together. Will result in a single combined list.
(nth 0 '(a b c)) -- Find the nth element. In this cas 'A'
(nthcdr 1 '(a b c)) -- Find the nth cdr. In this case (B C)
(zerop n) -- Checks if value is 0
(last '(a b c)) -- Returns last cons in a list. So it'll return "(C) here
(car(last '(a b c))) -- Returns last element of a list. In this case "C"
--first - tenth are defined as functions that are not zero indexed so for example:
(fifth '(a b c d e f g h i)) -- Will return "E" (the element, not the cons)
(mapcar #'(lambda (x) (+ x 10))
'(1 2 3)) -- Takes a function and applies everything in the list to it. In this case it will return (11 12 13)
(mapcar #'list
'(a b c)
'(1 2 3 4)) -- Would return:
((A1) (B2) (C 3))
(member 'b '(a b c d e)) -- (member) finds what it's looking for, and returns it as well as the cdr from that point. So here we would see "b" - "e"
-- Keywords are a symbol preceded by a colon... so ":test" for example
-- Member defaults to testing with eql, perhaps we want equal instead:
-- NOTE: Equal is less strict than eql. Equal returns true if it's arguemnts print the same.
-- EQL only if they are the same object
(member '(a) '((a) (z)) :test #'equal) -- Will result in ((A) (Z))
--There is also :key
(member 'a '((a b) (c d)) :key #'car) -- will return ((A B) (C D)) -- We asked if there was an element whose car was a
-- keywords are always at the end, and multiple are acceptable.
If we want to find an element satisfying an arbitrary predicate, like oddp, which returns true for odd ints, we can use member-if
(member-if #'oddp '(2 3 4)) -- This will find the first odd number, 3 in this case, and return it along with the rest of the list
(adjoin) -- conses an object into a list if it's not already a member
(adjoin 'b '(a b c)) -- (A B C)
(adjoin 'z '(a b c)) -- (Z A B C)
(union '(a b c) '(c b s)) -- (A C B S)
(intersection '(a b c) '(b b c)) -- (B C)
(set-difference '(a b c d e) '(b e)) -- (A C D) -- So, expected stuff
-- The above creates sets, and as we know, sets have no specific order
(length ' (a b c)) -- 3
-- Grab a part of a list
-- Think python slices, third argument (second number) is optional.
(subseq '(a b c d) 1 2) -- (B)
(subseq '(a b c d) 1) -- (B C D)
(reverse '(a b c)) -- Obvious, returns (A B C)
(subseq(reverse '(a b c)) 0 2) -- (C B) -- A way to grab the last two
(subseq(reverse '(a b c)) 1) -- (B A) -- Start with second to last and go backwards. Basically cut off the last (or however many ) element
(sort '(0 2 1 3 8) #'>) -- (8 3 2 1 0) -- Is destructive to the origional list. Of course, < would sort in order
(every #'oddp '(1 3 5)) -- Are they all odd? -- True
(some #'evenp '(1 2 3)) -- Are some of the even? -- True
(every #'> '(1 3 5) '(0 2 4)) -- Think math, is every element greater than it's corresponding element so...
-- is 1 > 0? AND is 3 >2 AND is 5>4? True
If sequences are different lengths, the shortests determines how many tests are performed.
(push x y) push object x onto the front of list y
(pop x) -- remove and return the first element of list x
(let ((x '(a b)))
(pushnew 'c x)
(pushnew 'a x)
x) -- This will only push to "x" if the object doesn't already exist.
-- Conses are not just for building lists, an improper list, or dotted list, can be used make a structure with two fields
(setf pair (cons 'a 'b)) -- (A . B)
-- car will return A, while cdr will return B

View File

@@ -0,0 +1,7 @@
(setf arr (make-array '(2 3) :initial-element nil)) -- Makes a 2x3 array -- :initial-element is optional, the whole array is init to this value
(aref arr 0 0) -- Retrieve an array element
(setf (aref arr 0 0) 'b) -- Set array element 00 to b
(setf vec (make-array 4 :initial-element nil)) -- Makes a one-dimentional array known as a vector