I’m struggling to find another egg that uses *-rm
as a function name. Copying from hashtable, is *-clear
or *-remove
more standard?
Indeed, I will replace it with okvs-clear!
because R7RS hash-table use hash-table-clear!
I also notice that you’ve elided range clears entirely from your API. Was that intentional? They are inconsistently supported across kv stores…
I will add it.
I feel like isolation is something you’d be better off leaving out of the SRFI. Which you kind of did already, as it’s in an optional config struct.
Ok.
The only difference between an ordered and unordered key-value store is if it supports efficient range operations. If your SRFI requires arbitrary get-ranges, you’re going to require someone to write an almost-equivalent unordered key-value store SRFI, and
Unordered key-value store seems not very useful to compose higher abstraction. I will think about it. I might make the okvs-range
and okvs-prefix
optional.
you also technically ban systems like Cassandra that distributes data such that a known prefix of the key is randomly distributed and a suffix of the key is sequentially distributed.
I don’t have enough experience with Cassandra to support it.
I don’t recall seeing “decorator” be a common scheme pattern?
It is not really a common pattern in the sens there is no word for it. That said, higher order procedures, that is procedures that take procedure as argument are common place. memoize
is an example of high order procedure that is also a decorator.
I feel like I see explicit transaction runner functions in most other language’s database bindings.
I don’t understand this paragraph:
You could just offer a function like (okvs-run okvs proc)
, and then (okvs-run okvs (lambda (db) (okvs-ref db key)))
would be equivalent to the current ((okvs-transaction (lambda (db) (okvs-ref db key))) okvs)
, the latter of which I find harder to mentally parse.
Right now, the way to use okvs-ref
is as follow:
(define db (okvs config))
(okvs-set! db #vu8(42) #vu8(2019))
(define value (okvs-ref db #vu8(42))
Which is equivalent to:
(define db (okvs config))
;; set
(define tr (okvs-transaction-begin db))
(okvs-set! tr #vu8(42) #vu8(2019))
(okvs-transaction-commit tr)
;; ref
(define tr (okvs-transaction-begin db))
(define value (okvs-ref tr #vu8(42))
(okvs-transaction-commit tr)
That said, I have enjoyed @fdb.transaction
making life simple in the python bindings, and I don’t really have a great sense of what is or is not idiomatic for scheme anyway.
As far as I understand, it transactional
in scheme is not very idiomatic. The R7RS sheperd proposed something else:
A more Schemey approach would be (in-transaction database proc failure success)
, which evaluates PROC
passing a newly created transaction as its argument. When PROC
returns, the transaction is committed and in-transaction
applies whatever PROC
returned to the SUCCESS
procedure and returns its result. If PROC
calls “rollback” instead, then the transaction is rolled back, the execution of PROC
is abandoned, FAILURE
is called with no arguments, and in-transaction
returns its result. By default FAILURE
is raise
and SUCCESS
is identity
.
My rationale behind transactional
, tell me if I am mistaken, is that it is very easy to use procedures decorated with transactional
in REPL. The in-transaction
approach is a little bit more ceremony.
It seems like the above okvs-run
you mention looks like in-transaction
.