#lang racket


(display "hell yrah")


(define (sum term a next b)
  (define (iter a result)
    (if (>= a b)
        result
        (iter (next a) (+ result (term a)))))
  (iter a 0))

(define (integral f a b n)
  (define h (/ (- b a) n))
  (define (apply-f k)
    (f (+ a (* k h))))
  (define (term k)
    (+ (* 4 (apply-f k))
       (* 2 (apply-f (+ k 1)))))
  (* (/ h 3)
     (+ (apply-f 0) (- (apply-f n))
        (sum term 1 (λ (x) (+ x 2)) n))))

;;; HOLY SHIT. This has nothing to do with the integral example, I just
;;; found out while reading section 1.3.2 that let is/can be implemented
;;; using just lambdas.
;;; So of course, I wrote a macro to do it.
;;; now I'm wondering what are the absolute minimum amount of primitives
;;; I would need to implement an entire scheme from the ground up.
;;; (Ideally to write a compiler in itself, for itself!)
;;; I guess this kind of thing really puts it into perspective huh.
(define-syntax my-let
  (syntax-rules ()
    [(_ () body ...) (begin body ...)]
    [(_ ([var expr] binding ...) body ...)
     ((lambda (var) (my-let (binding ...) body ...))
      expr) ]))

;;; god. I thought Common Lisp was nice. Scheme and Racket are just something else.

;; some stuff from the next exercise
(define (pn x) (display x) (newline) x)
(define tolerance 0.00001)
(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2))
       tolerance))
  (define (try guess)
    (let ((next (f guess)))
      (if (close-enough? guess next)
          (pn next)
          (try (pn next))
          )))
  (try first-guess))
; value of phi i think?
(fixed-point (lambda (x) (+ 1 (/ 1 x))) 1)