Please send questions to st10@humboldt.edu .
; hello, I am a comment

; an expression of type number

(+ 3 5)

; LISP - list processing

; in Lisp and Scheme, programs not only manipulate
;    lists -- they ARE lists

; its syntax is basically abstract syntax trees --
;    so, a very basic form (of several) is:
; (operator-or-function operand-or-arg-expr 
;                       operand-or-arg-expr ...)

(+ 3 5)
(* (+ 3 5) (- 7 6))

; this isn't so different when function calls are involved;

; C++:  max(3, 4)
(max 3 4)
; C++: max(sqrt(4), sqrt(5))
(max (sqrt 4) (sqrt 5))

; Lisp's/Scheme's multi-way conditional expression

; (cond
;    (bool-expr1 result-expr1)
;    (bool-expr2 result-expr2)
;    ...
;    (else else-result)
; )
;
; each bool-expr is evaluated in turn, EXCEPT as
;    soon as one of them is true, that bool-expr's
;    result-expr is the value of this cond, and you're
;    done
; (= compares two numeric expressions for equality)
; ('boo is a literal of type symbol)

; (note that when a symbolic value is displayed,
;    say as the value of some expression, its
;    delimiting single quote is not displayed...
;    (like C++ doesn't cout double quotes around strings)

(cond
  ((= 3 5) 'boo)
  ((= 5 5) 'look)
  ((< 3 5) (/ 3 0))
  (else 'huh)
)

; there are MULTIPLE ways to write lists in Lisp/Scheme!
;    (especially when you want just a list, and to not
;    evaluate it yet...)

'(1 3 5)  ; the ' here says, don't try to apply 1 as a function
          ;    to 3 and 5;
          ; (notice the ' saying this isn't displayed when the    
          ;    value is displayed)

(list 1 3 5)

; to prove these are equivalent lists --
;    note that equal? expects two expressions of any type,
;    and produces whether they are equivalent

(equal? '(1 3 5) (list 1 3 5))

; NOTE that Scheme's boolean literals are #t and #f

; these are both syntactic sugar, though --
; really, a list is defined using cons (for construct),
;    based on linked lists!

; a list in Scheme/LISP is either:
; - empty, written as '()
; - (cons element list)

'()  ; the empty list
(cons 1 '())  ; a 1-element list containing the number 1
(cons 'boo (cons 1 '())) ; 2 element list, with boo and 1
(cons "hi" (cons 'boo (cons 1 '()))) ; 3 element list

(equal? (cons "hi" (cons 'boo (cons 1 '())))
        (list "hi" 'boo 1))

; why bother with cons?
; ...because it is NICE for recursive list manipulation!

; ASIDE: here is how you define a function in Scheme!
; (define (funct-name param1 param2 ... paramN)
;    expr
;    ...
;    expr
; )
; ...and the value of a function call is the value of its
;    the final expression evaluated

; SILLY WORKING EXAMPLE!

(define (tryit a-number)
  (+ a-number 5)   ; this is done, but we'll see NO effect from it
  (* a-number 10)
)

(tryit 15)

; given a number, produce a "countdown" list of numbers
; (produce an empty list for a number <= 0

(define (make-countdown-list size)
  (cond
    ((<= size 0) '())
    (else (cons size 
                (make-countdown-list (- size 1))))
  )
)

; lists are built with cons, with an element and a list --
; thus, there are also means to grab the first element of a list,
;    and the "rest" of the list, all but the first element;

; for historical reasons, these operations' "classic" names are:
; car - expects a non-empty list, and returns the 1st element
; cdr - "coulder" - expects a non-empty list, and returns the
;       list of all but the 1st element

(car '(1 3 5))
(cdr '(1 3 5))

; an easy way to see if a list is empty: null?
(null? '())
(null? '(1 3 5))