144 lines
3.1 KiB
Common Lisp
144 lines
3.1 KiB
Common Lisp
rlwrap -- helps deal with readline
|
|
rlwrap sbcl -- makes it so I have history and navigation
|
|
|
|
Functions shoudl be verbs -- clear-screen
|
|
variables should be nouns -- dog
|
|
globals should be surround with asterisks --
|
|
*some-global-var*
|
|
It should be rare to have more than one expression in a function.
|
|
|
|
Instead of using variables, like we do in other languages, we should instead nest functions.
|
|
|
|
For exampe, in python we may do something like this:
|
|
|
|
|
|
;;; Python
|
|
def addTwoNumbers(x, y):
|
|
sum = x + y
|
|
return sum
|
|
|
|
sum = addTwoNumbers(1, 3)
|
|
print(sum)
|
|
|
|
;;; Lisp
|
|
|
|
(defun addTwoNumbers(x y)
|
|
(+ x y))
|
|
|
|
(print
|
|
(addTwoNumbers(1 3)))
|
|
|
|
Of course, the python one could simply be "return x + y" but the point is to
|
|
show the normal differences in thought, not to say that it's not possible
|
|
to do it in a lispy way in python.
|
|
|
|
To copy an example in only lisp to show the differenes from
|
|
cs.gmu.edu/~sean/lisp/LispTutorial.html
|
|
|
|
;;; Declaritive style (I.E. the python way above)
|
|
|
|
(defun my-equation (n)
|
|
(let (x y z)
|
|
(setf x (sin n))
|
|
(setf y (cos n))
|
|
(setf z (* x y))
|
|
(+ n z)))
|
|
|
|
;;; Functional style
|
|
|
|
(defun my-equation (n)
|
|
(+ n (* (sin n) (cos n))))
|
|
|
|
As we can see, we avoid variables and make it look pretty
|
|
|
|
|
|
;; Closure example:
|
|
;; So what happens here? All of these functions get to share the "account" var
|
|
;; yet, "account" is not asseble outside the functions.
|
|
;; Since the functions are there, the let statement doesn't get garbage
|
|
;; collected?
|
|
;; In a manner of speaking, defining functions within a let statement
|
|
;; allows for a private global variable
|
|
|
|
;; not much different from a java or C++ object
|
|
|
|
(let ((account 0))
|
|
(defun deposit ($$$)
|
|
(setf account (+ account $$$)))
|
|
(defun withdraw ($$$)
|
|
(setf account (- account $$$)))
|
|
(defun amount ()
|
|
account))
|
|
|
|
;; grabbing an element from a sequence (i.e. not multi-dimentional array)
|
|
|
|
;; Generic
|
|
(elt "hello world" 4)
|
|
(elt '(yo 1 3 4) 2)
|
|
(elt #(yo yo dur cob so 2 3) 3)
|
|
|
|
;; String
|
|
(aref "hi there" 3)
|
|
|
|
;; list
|
|
(nth 3 '(1 2 3 4 5 6 7))
|
|
|
|
;; simple-vector
|
|
(svref #(d 1 3 f g e) 4)
|
|
|
|
;; P-Lists (property lists)
|
|
|
|
(setf my-list '(armor (head
|
|
(dragon helmet)
|
|
legs ()
|
|
arms ())
|
|
weapon (left
|
|
(wooden-shield)
|
|
right ())
|
|
ring (left
|
|
()
|
|
right ())))
|
|
|
|
(getf my-list 'armor) >> (HEAD LEGS ARMS)
|
|
(getf (getf my-list 'armor) 'head)
|
|
|
|
;; Let's make it less crazy
|
|
(defun equipted-helmet (my-list)
|
|
(getf (getf my-list 'armor) 'head))
|
|
|
|
;; doing something like (setf (equipted-helmet my-list) 'hammer) doesn't
|
|
;; seem to work. Perhaps a closure would be better
|
|
|
|
(let ((equipment '(armor (head
|
|
(dragon helmet)
|
|
legs ()
|
|
arms ())
|
|
weapon (left
|
|
(wooden-shield)
|
|
right ())
|
|
ring (left
|
|
()
|
|
right ()))))
|
|
(defun get-armor()
|
|
(getf equipment 'armor))
|
|
(defun get-helmet()
|
|
(getf (get-armor) 'head))
|
|
(defun change-helmet ()
|
|
(push (getf (getf equipment 'armor) 'head) x))
|
|
;;(setf (getf (getf equipment 'armor) 'head) x))
|
|
#| Etc... |# )
|
|
|
|
Why doesn't this work?
|
|
|
|
(defvar mylist '(j 1 v 2))
|
|
|
|
;; Works
|
|
(setf (getf mylist 'j) 3)
|
|
|
|
(defun get-j ()
|
|
(getf mylist `j))
|
|
|
|
;;doesn't work
|
|
(setf (get-j) 'j)
|
|
|