Bind optional arguments

Problem

You have a list, example from a function, and you want to simplify checking optional parameters with default values.

Solution

(define-syntax let-optionals
  (syntax-rules ()
    ((_ expr ((v d) ... . tail) . body)
     ($let-optionals (v ...) () (d ...) () f tail expr body))))

(define-syntax $let-optionals
  (syntax-rules ()

    ((_ () (vt ...) _ (cl ...) f tail expr body)
     (letrec ((f (case-lambda cl ... ((vt ... . tail) . body))))
       (apply f expr)))

    ((_ (vrf . vr*) (vt ...) (df . dr*) (cl ...) f . tailexprbody)
     ($let-optionals vr* (vt ... vrf) dr* (cl ... ((vt ...) (f vt ... df))) f . tailexprbody))))

Credit @tallflier

NOTE: this macro is requirement for base implementation of SRFI-1.

Usage

(define (calc num . rest)
  (let-optionals rest ((multiplier 1) (factor 10))
    (/ (* num multiplier) factor)))

(calc 10)
;; ==> 1
(calc 10 2)
;; ==> 2
(calc 10 2 5)
;; ==> 4

Back to the Scheme Cookbook