Particularly a R7RS hash table that's supposed to do what?

It allows to add a state to the transaction in a generic way.

It used to extend to transaction behaviour somehow, it is used in fstore
It is workaround the fact one can not use okvs-in-transaction with custom semantics.
Another way around that would be to override/extend okvs-in-transaction (or okvs-transaction-begin et al.)
from user code but that is not possible in R7RS.


It's possible by importing the library and renaming okvs-in-transaction and then providing your own.

Yes, but that will forbid other abstraction defined in other libraries
to take advantage of that new okvs-in-transaction. Also, right now
in fstore, the state is modified in-flight, that is it is not okvs-in-transaction
or transaction-begin that change the transaction-state but okvs-set! via
nstore-add! and fstore-add!
 
I think however that instead of requiring a hash table, you should have a procedure that creates
the correct kind of opaque object that the implementation wants. 

I agree.
 
(I'm still not sure I understand it completely.)

In another email:

>> 6) What precisely are the semantics of the hash-table returned from okvs-transaction-metadata?  Does this documentation need to refer to a particular RnRs or other SRFI?
> Yes, it is a mistake. The hashtable is a R7RS hashtable. Thanks.
>> What happens if I mutate it? :)
> FWIW, it is at the start empty and is intended to be mutated.  I use in fstore to keep track of whether the transaction is "dirty" or not. In this context, a transaction is dirty if it has mutated the store.

It's not clear to me how it is intended to be mutated by the user.

okvs-transaction-metadata is a mutable hash-table. During the transaction, the user can hash-table-set! hash-table-ref stuff in it. Is it more clear?
 
It's not clear to me how mutating it impacts other parts of the SRFI.

Indeed, it doesn't impact other parts of the SRFI-167, but it allows to implement
abstractions on top of okvs while keeping things generic.

Also, I should add that hiding the okvs interface is an anti-pattern.

So doing things like wrapping okvs-in-transaction in another procedure
and exposing that as new-okvs-in-transaction is not good.

What I have experimented with is that when one provides its own transaction
procedures, it will forbid the extensions of the okvs. Therefore "layer" is not a
good name for database abstractions that rely on okvs. They are more
like extensions or composition of extensions.

When I started SRFI-168, it was wrapping the okvs-transaction-begin.
This was a mistake. Because if SRFI-168 start the transaction in say
nstore-in-transaction, another abstraction, can not know the transaction
was started or not. Instead, the new behaviour is that, it is always the
responsibility of okvs to start and finish the transaction. And abstraction,
take a transaction as an argument.

To some extent, this goes against the principle of:

"good abstractions don't leak"

okvs abstraction must leak to allow to implement other abstractions
that cooperate to build something bigger.

One way to workaround that bizarre thing, and instead every abstraction
works independently and doesn't have to be aware of what happens around it,
is to have some kind recursive transaction. That is start a transaction inside
another transaction, then each abstraction would have its class of transaction
that is created from a okvs handle or another instance of transaction.

Instead of "this is a transaction of transaction of transaction of okvs database".
With okvs-transaction-state we have a composition of different states...

I have only one use-case for okvs-transaction-state in fstore.scm where if
the transaction mutates the okvs it must add a commit to history and reference
its commit identifier in changes. To avoid that every fstore-add! in the same
transaction adds a commit, I need to add some information to the transaction
that says that the commit was already written for the current transaction.

If the transaction has not state, I can not tell whether the fact that the transaction
is a write transaction was ack'ed or not.

A way to workaround that, is to ask the user to specify upfront using transaction's
CONFIG whether the transaction is a read-and-write transaction or read-only transaction. That is what I am trying to avoid.

I will try to think about other use-cases, maybe I should leave transaction-metadata
out from the specification and just use it in my implementation as an extension.

--
Amirouche ~ amz3 ~ https://hyper.dev