Iterate provides defmacro-clause to make it easy to write new clauses. Here’s a simple one that builds up an FSet set:

(defmacro-clause (collecting-set x &optional into var)
  `(reducing ,x by #'with into ,var initial-value (empty-set)))

But the syntax of defmacro-clause is not as flexible as I would like. In particular, there is no way to supply more than one expression. To collect an FSet map, I would like to be able to write:

(collecting-map k v into result)

But the syntax of defmacro-clause won’t allow that.

However, there is still hope. Iterate uses a code walker that expands macros. All we have to do to get both the benefits of defmacro-clause (the ability to collect to a particular variable) and the syntax we want is to write two macros: a macro with the syntax that we want, which expands into an auxiliary Iterate macro.

(defmacro-clause (collecting-map-aux kv &optional into var)
  `(reducing ,kv by (lambda (map kv)
                      (with map (car kv) (cdr kv)))
             ,var initial-value (empty-map)))

(defmacro collecting-map (k v &rest args)
  `(collecting-map-aux (cons ,k ,v) ,@args))

And then we can write:

(iterate (for x in xs)
  (collecting-map x (* x 2))