Definitions and Procedures

6.1 define and lambda

(define pi-approx 3.14159)            ; variable definition
(define my-square (lambda (x) (* x x)))  ; a procedure is just a lambda value
(define (cube x) (* x x x))           ; shorthand form of the same idea
(my-square 5)                         ; 25
;; Note: R7RS already provides `square` in (scheme base); R7RS programs may not redefine imported names.
((lambda (x y) (+ x y)) 3 4)          ; 7: immediate application

6.2 Variadic Procedures

(define (sum . nums)                  ; all arguments as a list
  (apply + nums))
(sum 1 2 3 4)                         ; 10

(define (greet name . rest)           ; one required + rest
  (if (null? rest)
      (string-append "Hello, " name)
      (string-append (car rest) ", " name)))
(greet "Ana")                         ; "Hello, Ana"
(greet "Ana" "Hi")                    ; "Hi, Ana"

(define all-args (lambda args args))  ; (lambda args ...) takes any number
(all-args 1 2 3)                      ; (1 2 3)

;; case-lambda: dispatch on the number of arguments (R7RS)
(define area
  (case-lambda
    ((r) (* 3.14159 r r))             ; circle
    ((w h) (* w h))))                 ; rectangle
(area 1) (area 2 3)                   ; 3.14159 6

;; Optional arguments with defaults (SRFI-89 / implementation-specific; portable via case-lambda)
(define power
  (case-lambda
    ((base) (power base 2))
    ((base exp) (expt base exp))))

6.3 Internal Definitions and Block Structure

(define (hypotenuse a b)
  (define (sq x) (* x x))             ; internal definitions are local (like letrec*)
  (sqrt (+ (sq a) (sq b))))
(hypotenuse 3 4)                      ; 5

6.4 Procedures Are First-Class

(define (apply-twice f x) (f (f x)))
(apply-twice square 3)                ; 81
(define (make-multiplier n) (lambda (x) (* x n)))
((make-multiplier 3) 7)               ; 21
(procedure? car)                      ; #t
(apply max '(3 9 2))                  ; 9
(apply + 1 2 '(3 4))                  ; 10