diff --git a/recipes/bind-optional-arguments.md b/recipes/bind-optional-arguments.md new file mode 100644 index 0000000..d729ff0 --- /dev/null +++ b/recipes/bind-optional-arguments.md @@ -0,0 +1,43 @@ +# Bind optional arguments + +## Problem + +You have a list, example from a function, and you want to simplify checking optional parameters with default values. + +## Solution + +```scheme +(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](https://www.reddit.com/user/tallflier/) + +**NOTE**: this macro is requirement for base implementation of [SRFI-1](https://github.com/scheme-requests-for-implementation/srfi-1). + +## Usage + +```scheme +(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 +``` diff --git a/www-index.scm b/www-index.scm index d710b9e..f29f38e 100644 --- a/www-index.scm +++ b/www-index.scm @@ -1,5 +1,6 @@ (("Pairs and lists" "create-k-combinations-from-list" + "bind-optional-arguments" "find-depth-of-list" "find-index-of-element-in-list" "find-most-frequent-element-in-list"