with symbolic data structures.
The "list-let" macro below allows you to map
the elements of a list to "let" bindings.
Code: Select all
(define-macro (list-let _values _vars)
(let ((bindings (map (fn (_var _value) (list _var _value))
_vars (eval _values)))
(body (rest (rest (args)))))
(eval (cons 'let (cons bindings body)))))
(list-let '("John Doe" "Acme Widgets" "1-800-123-4567")
(name company phone)
(list company phone name))
;; => ("Acme Widgets" "1-800-123-4567" "John Doe")
The "alist-let" macro below allows you to map association
list values to let-bindings. The key name can be aliased
optionally along with a default value if the association is
not present.
Code: Select all
(define-macro (alist-let _alist _var-alias-defaults)
(let ((_alist (eval _alist)))
(let ((bindings
(map (fn (_var-alias-default , _value _alias _default)
(if (list? _var-alias-default)
(begin
(set '_value (assoc (first _var-alias-default) _alist))
(set '_alias (first (rest _var-alias-default)))
(set '_default (rest (rest _var-alias-default))))
(begin
(set '_alias _var-alias-default)
(set '_value (assoc _var-alias-default _alist))))
(if (list? _value)
(if (> (length _value) 2)
(list _alias (cons 'list (rest _value)))
(list _alias (first (rest _value))))
(list _alias _value)))
_var-alias-defaults))
(body (rest (rest (args)))))
(eval (cons 'let (cons bindings body))))))
(alist-let '((name "John" "Doe") (company "Acme Widgets") (phone "1-800-123-4567"))
(phone (name name1) (country country1 "USA") (company company1))
(list company1 phone name1 country1))
;; => ("Acme Widgets" "1-800-123-4567" ("John" "Doe") "USA")
a list is returned (see ("John Doe")).
While you can use context objects for synthesizing structures
these two macros allow you to to "crack" list structures
conveniently.