On the Will to Adapt: A Resource story

The will to adapt

Margo found herself stuck inside of her chambers glued to the bluish glow of her monitor. Margo was still feeling her way around the dominion, as she only recently managed to successfully immigrate from the Alliance for Unix. Normally alliance members find the Dominion… alien; not in the sense that every day things are “alien”, no those feel the same, but it is instead how those items are composed and the underlying assumptions that went into those items. Take for example a standard record found in every chamber throughout the dominion, some of these records look just like the various files and paperwork found in the alliance, one can even modify it and everything looks normal. However if one peeks under the hood, they would see that the record never changed! Rather the newly added record was added to the record base and became the predominate display. The alliance could of course reproduce this, although most attempts left this as a baroque feature that never fully integrated itself into alliance systems. Thus an alliance member can get used to raw unstructured records however the real kicker that made the endeavor completely alien was interacting with structured. Upon simply saving the updated record entire system would adapt as if it went into jurisprudence replacing the old with new. In fact unbeknownst to the user they aren’t actually editing text, they are hacking directly on resources with the full might of the dominion machine.

Thankfully for Margo, she was not a typical defector from the alliance; instead of practicing the old faith of C nor new rustic schools of faith that is at the center of the alliance, she studied the occult. Her father, Lukas Fisher, carried the tradition down to Margo from his father who was a priest of the symbolic order. The knowledge of these orders has been relegated to the occult ever since the Alliance for Unix took over the surrounding region and civilized the inhabitants. Old ways are hard to fully stamp out though, they simply tend to fester quietly through the kin of the devout. Her upbringing brought her to use the old order’s systems, systems that felt alien in the same way the dominion machines felt alien. To those followers the dominion machine’s felt more human than any alliance structure ever could. The path forward for Margo to learn was clear, she cleared the monitor of all distractions and opened up a primitive dialog prompt and typed…

luser Margo> 1
1

The machine returned to Margo rightfully back 1, Margo let out a slight smile, as this was the expected result. Margo almost moved the pointer device of her machine to inspect the result, but decided to stop herself, “No, I opened the most basic system dialog to force myself to learn how machines here truly operate” Margo thought. Margo then types the incantation to do the job by hand.

luser Margo> (inspect 1)

From here, a graphical window flew infront of Margo’s eyes, displaying high level details about this 1. The graphical window had many pages one can dive into, from showing what operations one can run on this 1 along with the hash, to most importantly for Margo the fact that 1 is a native resource object. “Right”, Margo thought to herself, she remembered that underlying every item in a dominion system is a resource of some kind backed by some kind of object protocol to tie it together. Margo didn’t fully understand how the object protocol worked, and so decided to press on trying to dissect how everything related. Margo wanted to start simple, however the 1 resource was not the best target to start, “no Ι want to see what these class-side slots and instance-side slots correspond to first, then I’ll dive into how messages work…”. So Margo began to create a very simple object, not using the typical class browser but once again by hand.

luser Margo>
(defclass toy () (toy-val :SIDE :INSTANCE) (call-val :SIDE :CLASS :val 5))
luser Margo> (inspect (new toy :toy-val 20))

Once again a screen flashes infront of Margo.

 ------------------------------------------------
 | Meta | Raw | Raw Resource |      ....        |
 | ====                                         |
 ------------------------------------------------
 | a Toy                                        |
 -----------------------------------------------|
 | class                                        |
 | TOY                                          |
 |   --------------------------------------------
 |   | instance-side slots: | toy-val | + |     |
 |   | class-side slots:    | call-val | + |    |
 |   | ....                                     |
 |   --------------------------------------------
 | Methods | References |       ....            |
 | =======                                      |
 | ...                                          |
 ------------------------------------------------

Margo confirms visually that the toy-val slot and the call-val were made for the toy class she made. After doing so, she flipped the tab view from Meta to Raw Resource

 ------------------------------------------------
 | Meta | Raw | Raw Resource |    ....          |
 |              ============                    |
 ------------------------------------------------
 | Slots                | Value                 |
 | logic-ref            | ↪ #logic at: /blob/.  |
 | label-ref            | ↪ (prim-arr 5)        |
 | value-ref            | ↪ (prim-arr 20)       |
 | nonce                | #x0abdea12121aa11aa1  |
 | .................... | ..................... |
 ------------------------------------------------

The values made sense to Margo, so the object protocol uses the value-ref for instance-side slots and label-ref for class-side slots. She wasn’t quite sure why, but she can see the correspondence, however what peeked her interest was the :arrow_right_hook: graphic, curious she decided to mouse over it.

 ------------------------------------------------
 | Meta | Raw | Raw Resource |    ....          |
 |              ============                    |
 ------------------------------------------------
 | Slots                | Value                 |
 | logic-ref            | ↪ #logic at: /blob/.  |
 |                       ▝▚▞▘                   |
 | label-ref            | ↪ (prim-arr 5)        |
 |                       ▗▞▚▖\                  |
 |                         『reference to /blob/#j9jbfa1』
 |                                              |
 | value-ref            | ↪ (prim-arr 20)       |
 | nonce                | #x0abdea12121aa11aa1  |
 | .................... | ..................... |
 ------------------------------------------------

“Ahh, so these are indeed references to something in the path blob”, Margo though to herself. “Let’s see how well I understand the system”.

luser Margo> (read /blob/#j9jbfa1)
(arr 5)

“Neat, so Ι can just read this plainly… Ι wonder…”

luser Margo> (reference (arr 5))
/blob/#abac1ada

??? Margo thought to herself, shouldn’t these be the same, after all she remembers reading that content on this system are content based, the given data back is the hash after all! Margo stops in thought for a minute before opening up the system documentation browser and reads about references, when she comes upon this passage:

“All data stored in the blob… path is content based, however one will often find that typing in data such as 0 will result in wildly different addresses. This is because each item is a new allocation… they under the hood have a different unique identifier stored in the underlying resource representation, you can view it in your inspector or by running (raw-nonce ) on the object of interest”

It suddenly made sense to Margo, each one is truly unique, she then
begins to type:

luser Margo> (values (raw-nonce (arr 5)) (raw-nonce (read /blob/#j9jbfa1)))
(#x0aaaaadasa #x0abaca1adaa)

Margo is starting to feel comfortable, however something is nagging at the back of her mind, “I understand how data is stored, now how do these dang methods work”. Margo sets herself off again, entering in something simple yet demonstrative:

luser Margo> (+ 1 1)
2

“Hmm… this is nice and all” Margo thought, clearly not satisfied with the output. So she opens up another window to read about how to read more about the underbelly of the dominion. After glancing at manuals for half and hour she finally hits upon the following passage:

"SECTION 20.1 INSPECTING RESOURCE OPERATIONS

We have now introduced how most of the semantics on how resource transactions work, one notable exception is how expressions entered into the system compose into resources and transactions themselves.

Chapters 3, 4, and 8 introduce the basic concepts represented by the resource model and chapters 5, 7, and 10 give the underpinning of evaluation, we will now explicate on how to inspect the underlying transactions formed in normal interaction. … … The next figure shows operations relating to inspecting the underlying machinery of transactions

… raw-transaction to-transaction inspect-reduction raw-logic…
"

Margo feeling confident decides to read on how to-transaction works
and after doing so writes the following:

luser Margo> (inspect (to-transaction `(+ 1 1)))

Margo is overjoyed, in the inspection screen she sees that what is really happening is that these two 1 objects are being consumed in a transaction and the operation creates a new resource 2 that will be given back to display. Further, on another tab she sees that inspect-reduction is being ran and sees that each of the 1 objects are forming an action together with the message {:+, 1}, which the 1 is the other resource it wishes to consume in the transaction. “Neat, so the message is passed into resource logic, I wonder what that dispatch looks like”, after paging through some tabs, Margo rests her eyes upon the following definition:

 ------------------------------------------------
 | Meta | Raw | .. | ... | Raw Loop | ....      |
 |                         ========             |
 |-----------------------------------------------
 |             Generic Selection                |
 | I determine whether a transition is accepted |
 |----------------------------------------------|
 | Resource ⊢ Object                            |
 | (def acceptance (message arguments)          |
 |   (apply (acceptance-criteria                |
 |             (find-method self message))      |
 |          (cons self arguments)))             |
 |----------------------------------------------|
 | an Integer                                   |
 |----------------------------------------------|
 | Methods | References |       ....            |
 | =======                                      |
 | ...                                          |
 | (def + another)                              |
 | ...                                          |
 ------------------------------------------------

It seems that all objects in this system have their corresponding resource-logic formed from their acceptance method… by the looks of it one can write a custom object that inherently changes how this works! Further, it seems that we can search the method by name given ourselves. “I wonder if Ι can find a way to trace this process”, with that comment Margo again dives into the online documents, finding the following command:

luser Margo> (trace (+ 1 1))
Object (Acceptance 1 + 1 2)
(find-method 1 +) ↦ (>> Integer +) “plus on integer”
(acceptance-criteria (>> Integer +)) ↦ (fun (self arg res) (= res (hardware:plus self arg)))
(apply (fun (self arg res) (= res (hardware:plus self arg))) (self 1 1 2))

With this, Margo was mostly satisfied, not fully understanding the model, but knew enough to be dangerous… enough to hack under the system and understand what the implications of writing something as simple as “(+ 1 1)” is. “Well there is always, tomorrow” Margo thought to herself before retiring for the night. For tomorrow comes and a new day of understanding comes about, she still wants to dive into how the inner loop of how her chambers is composed of these resources and where the meta extensions lie in the model.

3 Likes

Thanks for the lovely write-up! This definitely helps me get a better intuition for the correspondence between resources and an object model that you have in mind, although I think many points remain to be clarified. Here are some clarification questions and ideas that come to mind for me:

(A) Correspondence between objects and resources

As I understand your proposal here:

  1. In a simple object system, at any point in time, there is a set of object instances. Each object instance belongs to a class, where some memory is shared between all objects of a given class (“class-side slots”), but each object instance also has its own memory (“instance-side slots”).
  2. In the resource machine, at any point in time, there is a set of unconsumed resources. Each unconsumed resource has a kind (derived from the label and logic), and also a value, where there may be many distinct resources of the same kind but different values.
  3. In your proposal, we map a class of objects to a kind of resources, and instance slots in objects to the value field in resources, such that each object instance (at this point in time) corresponds 1-1 to an unconsumed resource, where class slots are stored in (or referenced by) the label/logic (some details TBD here), and instance slots are stored in (or referenced by) the value.

Is that all accurate? This makes sense to me at a basic level, but I have a few questions:

  1. In an object model, do you expect to be able to modify class-side slots after you’ve created the class? That would be difficult to do in this representation (you’d need to consume all of the current object-resources and create new ones with a new label/logic). If this is desired, it could be done with a more complex correspondence, where “mutable class slots” would be represented by some designated resource kinds that would be referenced in the label.
  2. The resource model implies a certain separation of “object transitions” from “object invariants”. Namely, the resource logic (associated with a given class) constrains what updates are possible, but it does not itself specify how to compute them. Object “methods” as in the object model I assume would typically specify how to compute particular updates. It would be possible to simply write some methods and reference them in a resource label, but I also wonder if a more elegant solution would be possible here that allows for methods to be written even after one has defined a class (or something like that). What do you think?

(B) Distributed object system

A really nice aspect of implementing an object model on top of the resource machine is that with the controller system we should get a distributed object system (almost) for free. At least in my basic extrapolation, we could preserve the same REPL-like interaction loop, but the objects themselves would be owned by a particular controller (where maybe the default one is just the local chambers-controller) - but you could reference resources elsewhere easily, perform operations on them using the same syntax, etc. - and if all users are running Anoma nodes, the object operations they perform would be fully consistent thanks to the underlying RM and controllers system. Does that seem directionally correct to you?