;(if '()
;		'i-am-true
;		'i-am-false)
;>> I-AM-FALSE
;
;(if '(1)
;		'i-am-true
;		'i-am-false)
;>> I-AM-TRUE
;
;This means empty lists are false. This significantly helps with recurison.
;
;We can take items from the front of a list and send the rest back 
;(cdr) until the list is empty.

;example:
;
;(defun my-length (list)
;	(if list
;			(1+ (my-length (cdr list)))
;			0))
;
;(my-length '(list with four symbols))

;The empty list is the only false value in common lisp. 
;Any value not equivalent to an empty list will be considered true.

(defvar *number-was-odd* nil)

(if (oddp 5)
		(progn (setf *number-was-odd* t)
					 'odd-number)
		'even-number)
;progn allows us to do extra commands in a single expression.
;nly the last evaluation in progn is returned as the value.

;Other conditionals have implicit prgn such as when and unless

(defvar *number-is-odd* nil)
(when (oddp 5)
			(setf *number-is-odd* t)
			'odd-number)

(unless (oddp 4)
				(setf *number-is-odd* nil)
				'even-number)

;The tradeoff is that there is no "else: with these commands. 
;In those cases they just return nil and do nothing.

;cond is sometimes considered to be the one true Lisp conditional.
;It has been around for long long time.

(defvar *arch-enemy* nil)
(defun pudding-eater (person)
			(cond ((eq person 'henry) (setf *arch-enemy* 'stupid-lisp-alien)
																'(curse you lisp alien -- you ate my pudding))
						((eq person 'johnny (setf *arch-enemy* 'useless-old-johnny)
																'(i hope you choked on my pudding johnny))
						(t									'(why you eat my pudding stranger ?)))))

;Note: "eq" and "eql" Ask if the two things being compared is the same thing.
;"equal" checks to see if the two thing return the same thing
;So... something like this:

(defun bob ()
		"bob")

(let ((x "bob"))
			(eq x (bob)))

;Will return False as x's "bob" is different 
;from the "bob" returned by the function
;Yet

(let ((x "bob"))
			(equal x (bob)))

;will return true as they both end up returning the same result "bob"

(defun pudding-eater (person)
	(case person
		((henry)	(setf *arch-enemy* 'stupid-lisp-alien)
							'(curse you lisp alien -- you ate my pudding))
		((johnny)	(setf *arch-enemy* 'useless-old-johnny)
							'(i hope you choked on my pudding johnny))
		(otherwise '(why you eat my puding stranger ?))))

;This is how we do cases. 
;Unfortunatly, cases are only really useful in the case of matching symbols
;This is because case uses (eq) to do the comparisons. 
;As noted earlier, this doesn't work well with strings.

(and (oddp 5) (oddp 7) (oddp 9))
;This is how we could use the (and) macro to check of three numbers are odd

(or (oddp 4) (oddp 7) (oddp 8))

;This is how we can check to see if at least one of the numbers is odd.

(or (oddp 4) (setf *is-it-even* t))

;This is a way we can use (or) as a conditional.
;If the first number was odd, it would never make it to the (setf)
;But, it is even so it does.
;This is called "shortcut boolean evaluation"
;This means once Lisp determines that an earlier statement 
;in a list of (or) values is true,
;It doesn't bother evaluating the rest.
;Same happens with (AND)
;If a statement returns false, it doesn't bother checking the rest

;Another example, think about saving a document:
(if *file-modified*
	(if (ask-user-about-saving)
			(save-file)))

;could be rewriten as an (and) statement

(and *file-modified* (ask-user-about-saving) (save-file))

;This is like asking the following
;Has the file been modified? If true then...
;Ask the user about saving, did the user's answer return true? If so, then:
; run the (save-file) function

;And of course, the way I probably would have written it in c or something

(if (and *file-modified*
				 (ask-user-about-saving))
		(save-file))

So basically, we could use (and) or (or) as a conditional 
;and put what we want to happen at the end

(if (member 1 '(3 4 1 5))
		'one-is-in-the-list
		'one-is-not-in-the-list)

>> ONE-IS-IN-THE-LIST

;Should be obvious, but member checks if an item is in a list or not.
;It then returns that item, plus the rest of the list
;This being a non-empty list returns true, which allows are (if) conditional
;To chose the "if-True" option of the (if)
;Remember, lisp blocks only return the last thing it computes
;That's why it does not return the normal functionality of (member)
;Could be useful for games.

;back to the (eq)/(equal)/(eql) issue...
;Conra'ds Rule of thumb for compargint Stuff:
;1. use (eq) to compare symbols
;2 use (equal) for everything else

;Why bother with (eq) at all? Well, apprently it's faster

;(equalp) can compare things that are mostly the same. So...
(equalp "BoB" "bob") 
;will return true and:
(equalp 1 1.0)
;will also return true

;Oh shit, chapter 5 is exciting. "Building a text game engine"
