(define (square x)
  (* x x))

===

(define square
  (lambda (x)
    (* x x)))


(define (square-sum a b)
  (+ (square a) (square b)))


(define (fact n)
  (if (= n 1)
      1
      (* n (fact (1- n)))))


(define account 1000)
(define (withdraw1 sum)
  (if (> sum account)
      (error "Insufficient funds!" account)
      (set! account (- account sum))))


(define withdraw2
  (let ((account 1000))
    (lambda (sum)
      (if (> sum account)
          (error "Insufficient funds!" account)
          (set! account (- account sum))))))

===

(define withdraw2
  ((lambda (account)
     (lambda (sum)
       (if (> sum account)
           (error "Insufficient funds!" account)
           (set! account (- account sum)))))
   1000))


(define (create-account1 account)
  (lambda (sum)
    (if (> sum account)
        (error "Insufficient funds!" account)
        (set! account (- account sum)))))


(define (create-account2 init)
  (let ((account init))
    (lambda (sum)
      (if (> sum account)
          (error "Insufficient funds!" account)
          (set! account (- account sum))))))


(define (create-account3 init)
  (let ((account init))
    (define (deposit sum)
      (set! account (+ account sum)))
    (define (withdraw sum)
      (set! account (- account sum)))
    (define (dispatch m)
      (cond ((eq? m 'deposit) deposit)
            ((eq? m 'withdraw) withdraw)
            (else (error "Wrong message!" m))))
    dispatch))