Please Review: The Heart of Spritely (HoS)

I started reading the new draft and made a few comments before I realized that I could do a diff and just read the changes. Just a few minor comments in https://docs.google.com/document/d/130bzascI8h7F4lLA-H1an0LC9jE3o1cDGartwzMicDk/edit#. Kate saved me a lot of work by making several comments I would have had to compose.

I am still concerned about using a less familiar language for the examples. Is there anyone else reviewing the document who isn’t a lisper?

2 Likes

For what it’s worth, I think the blogging example was good given the “federated social web” context. I imagine money examples are nice if you’re writing a game (or actually seriously trying to write financial applications), but personally when my goal is to write social applications they’re not that motivating. The blog example feels closer to what I might actually use Goblins for most often.

As far as other risks go, the one that comes to mind offhand is spam via email, which ocap addressing seems pretty well-positioned to mitigate. That may be too involved to include as an example in a doc like this though.

2 Likes

Managed to find some more time to poke at this and spotted one more thing: one of the return values of spawn-logged-revocable-proxy-pair is the revoked? cell itself, and the revoker object defined in the body is never used.

define (spawn-logged-revocable-proxy-pair username object log)
  ;; The cell which keeps track of whether or not the proxy user's
  ;; access is revoked.
  define revoked?
    spawn ^cell #f

  ;; The proxy which both logs and forwards arguments (if not revoked)
  define (^proxy _bcom)
    lambda args
      ;; check if access has been revoked
      when ($ revoked? 'get)
        error "Access revoked!"
      ;; If not, first send a message to log the access
      <- log 'append-to-log username object args
      ;; Then proxy the invocation to the object asynchronously
      apply <- object args

  ;; The revoker only has one behavior.  It is called with no
  ;; arguments and revokes access to the proxy.
  define (^revoker _bcom)
    lambda ()
      $ revoked? 'set #t

  define proxy
    spawn ^proxy

  values proxy revoked?

I think it’d make sense to either return an instance of the revoker or to remove the revoker definition altogether. (Probably the former, as it’s straightforward to augment the revoker to be able to un-revoke if you want to, but having it there is a nice example of what’s possible.)

3 Likes

I recently learned about this type of approach. Some call it “Architecture Decision Records”

2 Likes

Thanks for the pointer @bengo!

Store key historical architecture design decisions, rationale, and consequences in an easily identifiable text/markup file in your source repository and use the same peer-review tools in place to have the team participate. Different from a typical “wiki” approach in that the decision is made (as a group) before creating the document.

This sounds pretty neat to me. Would have loved this at more than a few of my companies back then. Is anyone here familiar with this approach used in open source projects or projects you’ve worked on?

When you get a few cycles, @cwebber - check out the video (it’s OK to watch at 2x speed.)

1 Like

Whoops, thanks @jfred! That was a plain-old goof-up.

New update!

There are some various changes, but the main one is that there’s a section about OCapN/CapTP now.

I still have some comments from y’all to get to. More soon. But back on this, trying to get a “good enough for the first public viewing” draft done on this asap.

I’ve pushed out quite a few updates yesterday, see the ChangeLog for more info. But most notably, there are four new sections that could use review:

More coming later today!

1 Like

New section: Application and library safety (and beyond).

Hello! Well, I’m happy to say that the whitepaper has… all the main parts in it! See the ChangeLog for more info.

I still have to add a “how to follow along with the code” section that explains how to get a hacking setup up and running but… all the main sections are written now.

But the big, big addition is… the Scheme tutorial, which kinda lies about being “brief-ish” and is going to be split out into its own paper! But for the moment, it’s still in the appendix until I extract everything.

This was going to be a very short introduction to Scheme, but it ended up as… well, kind of a highly compressed version of SICP. It ends with how to write Scheme in Scheme…!

Anyway. I still have to get some feedback incorporated, but since one of the biggest pieces of feedback was “major chunks are missing”, that part is at least there :slight_smile:

Your feedback welcome. I do promise I’ll be reviewing and considering all of it, and integrating wherever possible!

2 Likes

Here’s a Google Docs version for those of you would prefer to leave comments using that tool:

I just had to share something I personally think is really cool about the latest whitepaper release (and all releases going forward): All of the code is “live” in the paper, which means that it gets extracted to source files, compiled and tested automatically!

In a very real sense, the whitepaper is the source code with really, really detailed inline documentation. Congratulations, @cwebber !

2 Likes

Keeping Knuth’s literary programming dream alive in Spritely! :wink:

3 Likes

Btw, I made the spritely-papers repository publicly available. Should be possible to submit feedback via issues/PRs/etc now!

Here’s my feedback after reading the document and trying out the code. Hope it helps!

Having not been familiar with guile or wisp, it was a little unclear to me which syntax was which. A more explicit explanation of guile keyword arguments would probably clear most of that up.

Sections 3.2.2 and 3.2.3 show two different ways of holding state: 3.2.2. through the constructor’s parameters (e.g., val in (^cell bcom val)) and 3.2.3. through definitions in the constructor body (e.g., (define times-called …)). It seems that one key difference is that constructor parameters can be passed through bcom, while enclosed definitions cannot. So if bcom was used in 3.2.3 ^cgreeter, it would reset times-called to 0. It would be informative to discuss how these different types of state fit into the goblins philosophy and what the use cases are for each. It also raises the question of whether it is possible/recommended to use both types of state in the same object.

Is the return value of bcom undefined? If so, it could be useful to have an optional parameter that specifies a return value. I’m thinking of cases like a stack object where you want to pop something off the stack but also return the value that was popped off.

1 Like

I just finished reading thru this yesterday and have given Christine some feedback via the fediverse before she invited me here.

I’m looking forward to reading some of the implementation. For the code in the document itself, I have a lot of experience reading Scheme, but the combination of Wisp and the heavy use of define over let for locals made it difficult to follow some of the examples. I don’t think Wisp is a bad fit for this necessarily, but Wisp mixes poorly with the let-less style IMO. Not a huge fan of the “hard-hat” constructor convention nor of spelling “become” as “bcom” but I got used to those quickly enough.

I understand that the concept of an “unum” is important, but the way it’s introduced, it feels like it’s getting ahead of itself; there’s some discussion of how unums are implemented but it’s difficult to connect it to what I’ve already learned of the system by that point. (Also for me personally it’s confusing because I kept reading it as “umum” which means “public” in Bahasa but that’s just me.)

I really love the way this design brings together so many of my favorite things from the various languages I’ve used over the years into one place; actors from Erlang, “lexical scope for everything” from Lua, and Clojure’s epochal model of identity as a connected series of immutable values over time. I thought to myself that it might be helpful to call that idea out as being related to Clojure’s, but I can’t find a good reference that lays out the Clojure concept succinctly. (closest I could find was Clojure - Values and Change: Clojure’s approach to Identity and State which is about a lot more than that and also a lot about not using actors)

One thing that helped me understand capabilities before I started reading this document was Preventing log4j with Capabilities which explains the concept in terms of a widely-known vulnerability using examples in Java. Might be worth linking to.

Reading the section on OCapN really had me hungry for more.

But I think the first step for me is to take the ideas around capabilities systems and take them for a spin in a small way. I’ve got an IRC bot written in Fennel that I’ve been using the past few years to demo things for people who come by our channel, and it seems like it would be a great fit for capabilities. I’ve wondered to myself what it would be like to program without ambient authority (Lua/Fennel kind of hint at this in the way they make environments first-class in the language) but I’ve never actually tried it for anything nontrivial. Maybe an IRC bot doesn’t count as nontrivial, but it’s a start.

2 Likes

I’ve been re-reading this document (hopefully the most-current version), and have a few feedback notes:

  • p.3: “architecture of this paper is also also designed designed”
  • p.6: Indentation matters! The last line of the first example is not aligned.
  • p.7: The footnote should be refactored. I don’t know what [9] should refer to, and [11] is essentially explained in the body text at the top of the page.
  • p.11, footnote [13]: “money has been stolen in Etherium” should be “money has been stolen in Ethereum”
  • p.13 “the likellihood of unanticipated failures” should be “the likelihood of unanticipated failures”
1 Like

Thanks for the comments! We’re knee deep in prep for DWeb Camp prep/travel, so it might take a few days to integrate these changes.

1 Like

Here is the rest of my feedback from this re-reading pass…

  • p.25: Inconsistent indentation makes the code more difficult to read, especially since WISP is indentation sensitive.
  • p.30: You mention “Actormaps” but don’t really explain how they work. Seems to me you could refrain from mentioning them here (consistent with them no being pictured), and explain them (in more detail) in either “3.6. Turns are cheap transactions” or “3.7. Time-travel distributed debugging”.
  • p.31, footnote [17]: If you move this reference to the end of the sentence, it will still make sense but would prevent the orphan line at the page break.
  • p.32: “grant themselves powers which they did not originally have on restoration” should be “grant themselves powers on restoration which they did not originally have”.
  • p.34: In “CapTP: The Capability Transport Protocol (also known as CapTP)”, the parenthetical is redundant.
  • p.38: “we believed it was important to demonstrate why in the long run portable encrypted storage will provide.” will provide what?
  • p.39: “(also known as s-experessions or sexps),” should be “(also known as s-expressions or sexprs),”
1 Like

Thanks @dale.schumacher, incorporating your feedback!

Yeah unfortunately the copy-paste into Google docs hasn’t been kind to the code examples. The “official” page looks a lot better for this… it’s just the Google Docs versions that are messed up.

It may be better if we used a separate tool (hypothes.is?) that allowed for annotating, or just have people read the docs and submit feedback as issues/PRs at this point, since the repo is now live. Not sure.

1 Like