# Application read & write interfaces

**URL:** <https://forum.anoma.net/t/application-read-write-interfaces/661>\
**Category:** RM\
**Created:** [June 23, 2024, 11:54am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661 "2024-06-23T11:54:37Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [June 23, 2024, 11:54am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/1 "2024-06-23T11:54:37Z")

</div>

Currently, we define applications as a pair of a set of resource logics and a set of transaction functions (for full details, see the RMv2 report). The resource logics define the transition rules of the application’s state, and the transaction functions define some specific actions which can change that state (~ writes).

We currently lack a standardized (well-defined) way for applications to define how their state can be _read_. I propose that:

- We rename the current “application interface” (set of transaction functions) to the _ApplicationWriteInterface_.
- We create an _ApplicationReadInterface_ defined as part of an application definition (so an application is now a triple of (application logic, application write interface, application read interface).
- The _ApplicationReadInterface_ consists of a set of _declarative projections_ of the application’s state, i.e. functions of type `ApplicationState -> T` for some arbitrary `T`.

Note that here `ApplicationState` can include both resources (with resource logics defined in the `ApplicationLogic`) and also other non-linear state written to blob storage (further details to be worked out here).

For example, a read interface for the kudos application could include functions which:

- compute the current balance of a specific denomination owned by a specific user
- compute the overall ownership distribution of a specific denomination (subject to available information)
- compute the current balances for all denominations owned by a specific user and use known price data to convert them to other denominations (as UoA)
- … etc

I propose that this read interface is entirely _declarative_ - i.e. it says nothing about _how_ the projection functions should be computed, but merely defines what they are. Separately, we will need to figure out how to compute different projection functions and how to efficiently route updates to interested agents. Hopefully this will map somewhat naturally to our existing publish-subscribe system.

Definitions of application composition and related operations should be able to be updated in a straightforward manner.

> As a side note, this is not altogether dissimilar from a “model-view-controller” design pattern, where the resource logics are the model, the transaction functions (write interface) are the controller, and the projection functions (read interface) are the view.

cc @vveiln @degregat @jonathan @Michael @mariari for input.

---

<div class="post-metadata">

**Author:** ![graphomath](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/graphomath/32/9_2.png) [@graphomath](https://forum.anoma.net/u/graphomath)\
**Post date:** [June 24, 2024, 8:08am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/2 "2024-06-24T08:08:50Z")

</div>

I associate lenses to this (view + update), especially since compositionality is mentioned:

> **[Actegories and Lenses](https://bartoszmilewski.com/2021/12/05/actegories-and-lenses/)**
>
> A PDF of this post is available on github. Motivation A lens is a reification of the concept of object composition. In a nutshell, it describes the process of decomposing the source object $latex s…

Composition of applications is of course a very cool feature, no matter how it will be implemented.

---

<div class="post-metadata">

**Author:** ![Michael](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/michael/32/434_2.png) [@Michael](https://forum.anoma.net/u/Michael)\
**Post date:** [June 24, 2024, 10:05am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/3 "2024-06-24T10:05:59Z")

</div>

The definition as a triple is very straightforward to me.

> As a side note, this is not altogether dissimilar from a “model-view-controller” design pattern,

While reading a bit about MVC alternatives, I stumbled upon the Model View Intent (MVI) pattern being rather new and popularized by a library called [https://cycle.js.org/](https://cycle.js.org/) in the context of android app development. It emphasizes its composability and seems to fit quite well:

> Model-View-Intent (MVI) is reactive, functional, and follows the core idea in MVC. It is reactive because Intent observes the User, Model observes the Intent, View observes the Model, and the User observes the View. It is functional because each of these components is expressed as a referentially transparent function over streams. It follows the original MVC purpose because View and Intent bridge the gap between the user and the digital model, each in one direction.

Source: [Cycle.js - Model-View-Intent](https://cycle.js.org/model-view-intent.html#model-view-intent-what-mvc-is-really-about)

Other texts also mention intent **interpreters** (that could be LLMs in our case) and **reducers** (that would be the projection functions that you mention).

 ![Bildschirmfoto 2024-06-24 um 11.57.02](https://europe1.discourse-cdn.com/flex013/uploads/anoma1/original/1X/b3c114e18424269fcabcb2a69ab2632d45886528.png)

Image Source: [The Basics of Model-View-Intent](https://commonsware.com/AndroidArch/pages/chap-mvi-005)

Perhaps we can borrow from this.

More reads: [Model-View-Intent (MVI) Pattern in Reactive Programming: A Comprehensive Overview - GeeksforGeeks](https://www.geeksforgeeks.org/model-view-intent-mvi-pattern-in-reactive-programming-a-comprehensive-overview/)

**Question:**

> this will map somewhat naturally to our existing publish-subscribe system

Where can I read about the existing publish-subscribe system?

---

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [June 24, 2024, 12:05pm UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/4 "2024-06-24T12:05:43Z")

</div>

> [@Michael](#):
>
> While reading a bit about MVC alternatives, I stumbled upon the Model View Intent (MVI) pattern being rather new and popularized by a library called [https://cycle.js.org/](https://cycle.js.org/) in the context of android app development. It seems to fit quite well:

Nice find! Interesting to see the linguistic convergence (“intent”) as well 🙂

> [@Michael](#):
>
> Other texts also mention intent **interpreters** (that could be LLMs in our case) and **reducers** (that would be the projection functions that you mention).

Yes, exactly - although we typically use the word “intent” to refer to the _definite_ user action (i.e. what they call “action”), as opposed to the _indefinite_ pre-action, we could absolutely use LLMs as a way to help users craft their definite intents. A good topic for a future prototype!

> [@Michael](#):
>
> Where can I read about the existing publish-subscribe system?

The upcoming network architecture ART will cover this topic in detail. In the meantime, you can take a look at the (wip) [specification](https://anoma.github.io/nspec/v2/architecture-2/networking/intra-domain/pubsub/index.html), or ask @tg-x / @nzarin directly.

---

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [June 24, 2024, 12:27pm UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/5 "2024-06-24T12:27:26Z")

</div>

I think the particularly compelling aspect of logic-write-read / MVC / MVI in our case is that not only the logics, but also the actions (transaction functions) and views (projection functions) are first-class objects in the database system, so (e.g.) transaction functions and projection functions could be compiled/analyzed, and Anoma can figure out (in most cases) how to optimize routing data around to the right nodes at the right time when state changes happen.

---

<div class="post-metadata">

**Author:** ![vveiln](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/vveiln/32/60_2.png) [@vveiln](https://forum.anoma.net/u/vveiln)\
**Post date:** [June 25, 2024, 10:42am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/6 "2024-06-25T10:42:29Z")

</div>

If the read interface only describes the output projection but doesn’t specify how to compute it, how would it work in practice? There must be some function that actually performs the computations to satisfy the read interface, how does it connect to the application? I assume these functions also have to be written by the application developers (or some compute services?)

---

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [June 25, 2024, 11:33am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/7 "2024-06-25T11:33:21Z")

</div>

Yes, there must be functions that actually perform the computations. In some cases perhaps the application developer will also have to specify those, and we should make provisions for doing so. My expectation is that many projection functions will have similar structures - e.g. indexing data in certain ways - and the necessary steps to compute these kinds of views can be written once and then reused for many projection functions with different specifics but shared structure. Eventually it should be possible to automatically analyze most projection functions, figure out what known steps can be applied, and then let the developer know what (if anything) they must additionally specify.

At a high level, this problem is not altogether dissimilar from e.g. query analysis in SQL, which takes a declarative query and figures out what internal lookup structures (typically indices) to use to compute it efficiently, which tables need to be scanned/joined, etc. - although obviously we aren’t implementing SQL, and routing data around the network will require different sorts of analysis.

---

<div class="post-metadata">

**Author:** ![degregat](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/degregat/32/449_2.png) [@degregat](https://forum.anoma.net/u/degregat)\
**Post date:** [June 26, 2024, 8:19am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/8 "2024-06-26T08:19:13Z")

</div>

Separating the interface declaration and implementation make sense, since implementations become updateable.

It seems to me that we want to still be able to mark which implementations are compatible/tested, since composability could very well depend on implementation details.  
But since there will be cases where behavior can depend on local views of the network (e.g. compute balances subject to available information), applications need to be robust against that anyways.

If I understand correctly, decomposing into intents and actions, mediated by interpreters and reducers sounds like a good approach to model this:  
Here the interpreters and reducers would be responsible for providing this robustness in practice, but I don’t know how that would play out concretely.

It feels like we’re moving towards tradeoffs similar to [“be conservative in what you send, be liberal in what you accept”](https://en.wikipedia.org/wiki/Robustness_principle) of which there are valid criticisms. For a relatively recent perspective on that see: [Maintaining Robust Protocols](https://datatracker.ietf.org/doc/html/rfc9413).

Edit: Just talked to @cwgoes and it seems we should be able to alleviate this by requiring specific proofs of correctness/consistency. Specifying the properties these proofs need to validate will be important and require careful analysis for each application.

---

<div class="post-metadata">

**Author:** ![cwgoes](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.anoma.net/cwgoes/32/22_2.png) [@cwgoes](https://forum.anoma.net/u/cwgoes)\
**Post date:** [June 26, 2024, 9:51am UTC](https://forum.anoma.net/t/application-read-write-interfaces/661/9 "2024-06-26T09:51:24Z")

</div>

The point about consistency of read levels is a very important one. I think requirements will vary for different applications and network scenarios. For example, for something like multichat, it might make sense to apply updates to the state (in this case, display new messages) as soon as I hear about them over the network (even before transactions are ordered by a controller), and then update the UI again (e.g. reorder messages) after the transactions are ordered and the controller sends out a new header. On the other hand, for an application like kudos which might often want to query price data, exact consistency is very important, and we wouldn’t want to include any unconfirmed intents/transactions.

I think what we will ultimately need here is a data structure specifying different possible levels of consistency, which can be used along with the projection function(s) to determine how exactly to aggregate and collate state across the network. For example, some options could be:

- read the state exactly as known to a particular controller at a particular point in time, only (so e.g. their state, and state on other controllers which they have endorsed, at a particular block height)
- read the latest state associated to each controller, as known to each controller
- read the “most recent” state, _including_ speculative updates (intents/transactions in flight)
- read the “most recent” state, _including_ speculative updates _judged as likely to be confirmed_ (here we start to introduce probabalistic models)
