On Fri, Jul 23, 2021 at 10:29 AM Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:
Unfortunately, SRFIs 69 and 125 don't support -fold.  It might be better to have a little stub here that makes them do so.

I was wrong: they do.  But folding over an unordered dictionary does not produce a consistent result.
BTW, what we are missing for all kinds of dictionaries is a fold that allows passing more than one value between each iteration (which is a general thing in, say, named let loops).

If you really need to do that, pass a tuple of some sort (a vector or record).
SRFI 1's fold doesn't allow this because it uses the rest argument for multiple lists. This reasoning does not apply to the dictionary fold because it only folds over a single dictionary.

The problem of unordered dictionaries when folding over one of them is only amplified when folding over more than one, which is why it is not provided.
Moreover, I can easily substitute a list fold with a named let if I need more than one value to pass between iterations. I can't do this with dictionary folds because I have no (cheap) car and cdr for dictionaries.

So we want and need a more general

(dict-fold dtd proc dict seed ...)

where PROC takes two more arguments than there are SEEDs.

That would require a lot of retrofitting into existing SRFIs.

If you don't like the reversed order with respect to SRFI 1's fold, rename it to `dict-iterate'. Indeed, this is quite sensible because dicts aren't ordered sequences, and so the theory of list folds do not really apply to them.

Well, some are and some are not.

I looked into the procedures that aren't dto-first and they are all procedure-first, which I consider a very important Scheme convention to preserve, so I'm not going to change that.

It should be part of the dictionary-type-object's contract whether mutation actually happens or not.

There can be no guarantee that mutation happens in every case.  Adding an association to a plist, for example, will mutate if possible, but if the plist is empty, it can't.

This, by the way, shows that we need another procedure "dict-copy" in SRFI 225's API that guarantees an instance so that applying SRFI 225 procedures on its argument doesn't change its return value and vice versa. With such a procedure, generic code can be as efficient as it can get.

Alas, it has the same basic problem as the constructors.  It would be possible to provide dict-copy for existing SRFIs, since they all happen to support it. But SRFI 167 doesn't even have a concept of copying.