## context on `rep_lang`
`rep_lang` is an interpreter for a lambda-calculus-based simply typed language.
it is written in Rust, which allows it to be plugged into Holochain easily.
## context on `rep_interchange`
`rep_interchange` is where `rep_lang` gets plugged into Holochain.
currently, the repo contains a "core DNA" (featuring an `InterchangeEntry` Holochain entry type) and frontend code, which is used to interact with the "core DNA".
one of the frontends is a Rust Terminal UI, aimed at exercising the `InterchangeEntry` at a low level.
we are calling this `rep_lang_playground`.
## context on `nh-mvp`
users and Neighbourinos, in most cases, will be more interested in what `InterchangeEntry` and `rep_interchange` *enable*, rather than the nitty-gritty details of what they are and how they work in computer-science terms.
***
example IE, for the `rep_lang` expression `(+ 1 2)` - addition of integer values 1 and 2.
```
InterchangeEntry {
operator: App(App(Prim(Add), Lit(LInt(1))), Lit(LInt(2))),
operands: [],
output_scheme: Scheme([], TCon("Int")),
output_flat_value: FlatValue(VInt(3)),
start_gas: 0
}
```
example IE which adds 1 to the above IE (note the operands hash which refers to the above entry):
for clarity, here we have the `rep_lang` expressin `(+ 1)` - the addition operation applied to only one argument, meaning that it requires another argument in order to output their sum.
the second argument is supplied by dereferencing the IE out of `operands` and passing its value into the not-fully-applied addition function in `operator`.
as we see, the result is equal to `(+ 1 (+ 1 2))` - `4`.
```
InterchangeEntry {
operator: App(Prim(Add), Lit(LInt(1))),
operands: [InterchangeOperand(HeaderHash(uhCkkTuml9LD8A9B9oIlsvOUgiuCDB9nYjf1_1kH_kLoR2CsRI2dG))],
output_scheme: Scheme([], TCon("Int")),
output_flat_value: FlatValue(VInt(4)),
start_gas: 1
}
```
***
`nh-mvp` aims to demonstrate the capabilities of `rep_lang` and `rep_interchange` - supporting "dynamic, living, shareable, forkable" reputations - in the context of meme-sharing.
at the core is a very simple widget which (ab)uses a Holochain entry type to store images (encoded as strings) in Holochain.
once the meme-images are "in Holochain", we can associate other Holochain entries with them - perhaps Likes or Claps to indicate our fondness for particular memez.
by applying a "scoring computation" to the reaction datatypes associated with a meme, we can get a score.
importantly, we can easily, dynamically swap between different "scoring computations" in order to change which memes rank highest.
for the MVP we will showcase super-simplistic scoring computations based on Likes (simply summing the number of likes), Claps (simply summing all of the counts of claps associated with the meme), or both (summing likes, summing claps, and multiplying both by scalars).
this will demonstrate how users or CAs can easily swap between different "views" into a social context.
they are free to choose their view, or create a new custom one.
(unlike current platform lock in, etc).
## `rep_lang_playground`
(
MH:
ppl have called it `rep_playground` too - I just think it is more a playground for `rep_lang` than for reputation (mostly because at present the former doesn't support much richness of the latter).
so I prefer `rep_lang_playground` and `rlp` as the abbreviation.
)
`rlp` allows us to see a "computational fabric" or "computational substrate" for reputation.
using Holochain validation rules, we are able to enter *computations* as Holochain entries, and check that they are valid.
(aside: including functions! because I can cheat and use a limited notion of equality, because everyone is running the same `rep_lang` interpreter, guaranteed by the Holochain DNA hash).
so, agents can create "reputation computations" (for example, a function which ingests the number of Likes and Claps on a post, and computes a weighted sum), share them around the network, and be able to verify that other entries (say, the application of the aforementioned function to a particular post, resulting in a score) are correctly computed.
this bears significant resemblance to verification of the smart-contract language of blockchain systems.
however it's important to note that Holochain validation rules are more flexible and don't insist on all nodes both storing and validating (executing) all computations.
this should allow for significantly lighter workloads.
also, since Holochain & `rep_interchange` are suited for working in many distinct contexts simultaneously, rather than one gigantic & universal context (blockchain), scaling and performance ought to be significantly better.
still, (MH: this is maybe more for internal sensemaking than external comms at this point - too much detail? idk) it is an open question for the NH architecture to what degree "intermediate computations" will be exposed and shared to the network.
`rlp` essentially exposes `rep_lang` to the network, allowing computations which could occur only "inside `rep_lang` " to be "paused" and sent "outside `rep_lang` " (from the POV if a single interpreter) into the network, then brought back "inside `rep_lang` ".
in the extreme case, we could chunk computations apart at every possible juncture (function application) and store all of that into the DHT.
e.g. `(+ 1 2)` - addition of 2 ints in `rep_lang` could become:
- store + as an `InterchangeEntry`
- store 1 as an `InterchangeEntry`
- store 2 as an `InterchangeEntry`
- reference all 3 above entries, and apply the first to the other 2.
obviously, this would be much larger to store (and slower to compute, due to network propagation latency & overhead in wrapping/unwrapping values) than a single `InterchangeEntry` of the result of the addition - `3`.
the benefit of "chunking" a program apart is that pieces of it can be shared, reused, and validated incrementally, rather than "all in one go".
striking the right balance here will take some learning & iteration.
## addendum: crude thought on implementation
- Likes are tuples of `(0, 0)` or `(0, 1)`
- Claps are tuples of `(1, x)` where `x` is the # of Claps
- since we don't yet have sum-types, or UDTs, this will allow us to feed data into the system.
- we define a fn `score : List (Int, Int) -> Int` and then the plugin code will feed data associated with each entry into `score`, assert that it gets an int out, and use that to order the feed.
- users can add in their own implementations of score, as long as they match the type signature
possibly good things to do:
- add an exponential decay function to keep a lid on claps
- Scoring computation examples:
```
# only count likes
(foldl
(lam [acc tup]
(+ acc
(if (== 0 (fst tup))
(clamp 0 1 (snd tup))
0)))
0)
# only count claps
(foldl
(lam [acc tup]
(+ acc
(if (== 1 (fst tup))
(max 0 (snd tup))
0)))
0)
# count both! (naively)
(foldl
(lam [acc tup]
(+ acc
(if (== 0 (fst tup))
(* 10 (clamp 0 1 (snd tup)))
(if (== 1 (fst tup))
(* 1 (max 0 (snd tup)))
0))))
0)
```