In a shrubbery system, all data is addressable by its scry path. The design space for shrubberlicious application models is vast. Rather than jumping to a complex design focused on being ergonomic and featureful, this "young shrub" model (Yung Shrub is also acceptable spelling) aims for maximal simplicity of the implementation of the application runner, providing just enough capability to build arbitrary applications.
The goal of young shrub is to provide a low-level sandbox for application experiments. I want to get to working shrubberlicious apps as soon as possible.
Given its similarity to Plan 9, this could also be known as Plan X.
An app is a function from a pair of contextual information (our and tick) and a new scry binding (pact) to a list of new scry bindings. The app itself does not maintain state. Instead, it can .^ to read state from scry paths, and it can emit new scry bindings to "overwrite" state.
|%
+$ app
$- [=bowl =pact]
(list pact)
::
+$ bowl [our=ship =tick] :: contextual data for an application
+$ pact (each [=seal oath] oath) :: possibly signed $oath
+$ oath [=pith =noun] :: scry binding; $pith is a typed path
+$ tick @ux :: arvo activation tick
+$ seal @uvI :: signature
--
Note that most contextual information, which is injected directly in the bowl in current Gall, can be hidden behind a scry interface. This allows for a simpler model and potentially performance gains if other contextual information can be materialized lazily.
What we think of as events and effects need to be expressible as path-based interfaces.
:: lazily materialized contextual data for the application
::
/bowl/eny :: entropy
/bowl/pax :: endpoint path bound by the application
/bowl/ret :: data retention policies (writable)
::
:: writable vane interfaces
::
/sys/b :: behn timers this application has set
/sys/c :: external folder syncs
/sys/d :: terminal handling
/sys/e :: web bindings
/sys/i :: web requests
::
=> |%
+$ spar :: scryable path subset
$: [%p =ship]
[%ud =rift]
[%ud =life]
vane=@tas
=desk
=care
=case
spur=pith
==
+$ case
$% [%ud p=@ud] :: revision number
[%da p=@da] :: date
[%tas p=@tas] :: label
[%uv p=@uv] :: hash
[%ux p=@ux] :: arvo tick
==
--
::
|= [[our=ship =tick] =pact]
|^ ^- (list pact)
?- -.pact
%& (on-her +.p.pact) :: react to foreign binding
%| (on-our p.pact) :: react to domestic binding
==
++ on-her
|= =oath
^- (list pact)
!!
::
++ on-our
|= =oath
^- (list pact)
=+ .^(pax=pith /[our]/[tick]/bowl/pax)
?+ pith.oath !!
#/foo [pith=[p+our ux+tick (snoc pax %my-foo)] noun=[%foo noun.oath]]~
==
--