⚓ bulkf » Description
bulkfupdate-function-form &rest mode-markers-and-items ⇒ results
bulkfallows mass updating of places.
update-function-form is evaluated first to produce update-function. The arguments and return values of this function depend on mode-markers-and-items and are described below.
mode-markers-and-items is a list of mode-markers and items to be processed from left to right at macroexpansion-time. A mode-marker is one of the symbols
:pass. Any other form is an item. Whenever a mode-marker is encountered, the mode with that name becomes the current mode and remains so until the next mode-marker. The current mode at the start of mode-markers-and-items is
:accessmode. There are 4 different types of items, corresponding to the 4 different modes that can be the current mode at the time the item is encountered. Here are the semantics of each type of item:
item is a place that will be both read from and written to. At runtime, the subforms of the place are evaluated and the place is read. The primary value is contributed as an additional argument to update-function. update-function also returns an additional value that will be written back into the place (reusing the temporary variables bound to the results of the subforms).
item is a place that will be read from. At runtime, the subforms of the place are evaluated and the place is read. The primary value is contributed as an additional argument to update-function.
item is a place that will be written to. update-function returns an additional value that will be written into the place. The evaluation of the subforms of the place happens at the same time as it would have happened if the place had been read from.
item is a form to be evaluated normally. Its primary value is passed as an additional argument to update-function.
If update-function returns more values than there are places to write to (
:writeitems), the additional values are ignored. If it returns less values than there are of these places, the remaining ones are set to
bulkfreturns the values that were written into these places. This might be more or less values than were returned by update-function. If a place to be written to has more than one store variable, the remaining such variables are set to
nilprior to evaluation of the storing form.
bulkfaccepts an optional unevaluated argument before update-function-form (as very first argument). This must be the symbol
applyand determines which operator will be used to call the update-function with its arguments. The default is
funcall, which is expected to be used an overwhelming majority of the time. This is the reason this argument has not been made a normal required parameter.
⚓ bulkf » Examples
bulkf is very versatile and can be used to easily implement many different types of modify macros. Here are just a few examples:
defunbulkf-transfer (quantity source destination) (
-source quantity) (
+destination quantity))) (
defmacrotransferf (quantity source destination) `(
:access,source ,destination)) (let ((account-amounts (
list35 90))) (
values(transferf 10 (
secondaccount-amounts)) account-amounts)) ⇒ 25, 100, (25 100)
defunbulkf-init (value number-of-places) (
make-listnumber-of-places :initial-element value))) (
defmacroinitf (value &rest places) `(
let(a b (c (
make-list3 :initial-element nil))) (initf 0 a b (
valuesa b c)) ⇒ 0, 0, (NIL 0 NIL)
defunbulkf-spread (spread-function sum-function &rest place-values) (
values-list(let ((number-of-places (length place-values))) (
make-listnumber-of-places :initial-element (
applysum-function place-values) number-of-places))))) (
defmacrospreadf (spread-function sum-function &rest places) `(
let((a 5) (b (
list10 18 20))) (spreadf #'
valuesa b)) ⇒ 11, (11 11 20) (
let((a 2) (b (
list2 4 8))) (spreadf #'
valuesa b)) ⇒ 512, (512, 512, 512)
defunbulkf-map (function &rest place-values) (
mapcarfunction place-values))) (
defmacromapf (function &rest places) `(
let((a 0) (b 5) (c (
list10 15))) (
1+a b (
secondc))) a b c)) ⇒ (1 6 16), 1, 6, (10 16)
defunbulkf-steal (sum-function steal-function initial-assets &rest target-assets) (
let(stolen leftovers) (
multiple-value-bind(steal leftover) (
funcallsteal-function assets) (
pushsteal stolen) (
pushleftover leftovers))) target-assets) (
defmacrostealf (sum-function steal-function hideout &rest targets) `(
:access,hideout ,@targets)) (
let((cave :initial-assets) (museum '(:paintings :collection)) (house 20000) (triplex (list :nothing-valuable :random-stuff 400))) (stealf #'
lambda(assets) (if (eq assets :nothing-valuable) (values nil assets) (values assets (
numberpassets) 0 nil)))) cave museum house (
valuescave museum house triplex)) ⇒ (:INITIAL-ASSETS (:PAINTINGS :COLLECTION) 20000 NIL :RANDOM-STUFF 400) NIL 0 (:NOTHING-VALUABLE NIL 0)