[cap-talk] Demonstrating Horton success case with logging

Mark Miller erights at gmail.com
Fri May 18 20:02:23 EDT 2007


Hi Jed,

I saw your request for a working Horton test case you could play with.
The following is an updoc script
(<http://www.erights.org/elang/tools/updoc.html>) that works in the
latest E release (0.9.1b). All the indented test cases should
therefore work as shown when typed at the rune command line. Please
give it a try. Thanks!

Everyone, thanks much for your comments. My connectivity from here
does indeed suck, but I'll be getting to all this shortly. Thanks
agains!

Best when read in a fixed width font.

----------------------- short-horton.updoc ---------------------
#!/usr/bin/env rune

A simple set of application objects, shown first interacting directly:

    ? def c {
    >     to hi(_) { println("hi") }}
    # value: <c>

    ? c.hi(c)
    # stdout: hi
    #

    ? def b {
    >     to foo(c) {
    >         c.hi(c)}}
    # value: <b>

    ? b.foo(c)
    # stdout: hi
    #

    ? def makeA(b,c) {
    >     return def a {
    >         to start() {
    >             b.foo(c)}}}
    # value: <makeA>

    ? def directA := makeA(b,c)
    # value: <a>

    ? directA.start()
    # stdout: hi
    #

The simplified Horton code from the paper, enhanced only to show the
Horton objects of the various parties logging some actions for
responsibility-tracking purposes:

    ? def makeQuoteln := <elang:interp.makeQuoteln>
    # value: <makeQuoteln>

    ? def makeProxy(beMe, whoBlame, stub, reportln) {
    >     def log := makeQuoteln(reportln,
    >                            `I ask ${whoBlame.getBrand()} to:`,
    >                            75)
    >     return def proxy {
    >         to getGuts() {                   # as P2           # 04
    >             return [whoBlame, stub]}                       # 05
    >         match [verb, [p2]] {             # as P1           # 02
    >             log(`$verb/1`)
    >             def [carolWho, s2] := p2.getGuts()             # 03
    >             def gs3 := s2.intro(whoBlame)                  # 06
    >             def p3Desc := ["t", gs3, carolWho]             # 12
    >             stub.deliver(verb, [p3Desc])}}}                # 13
    # value: <makeProxy>

    ? def wrap(s3, bobWho, beCarol) {          # as S2           # 10
    >     def provide(fillBox) {                                 # 22
    >         def fill := beCarol.unseal(fillBox)                # 23
    >         fill(s3)}                                          # 24
    >     return bobWho.seal(provide)}                           # 11
    # value: <wrap>

    ? def unwrap(gs3,carolWho,beBob){          # as S1           # 17
    >     def provide := beBob.unseal(gs3)                       # 18
    >     var s3slot := null                                     # 19
    >     def fill(s3) {s3slot := s3}                            # 25
    >     def fillBox := carolWho.seal(fill)                     # 20
    >     provide(fillBox)                                       # 21
    >     return s3slot}                                         # 26
    # value: <unwrap>

    ? def makeStub(beMe, whoBlame, targ, reportln) {
    >     def log := makeQuoteln(reportln,
    >                            `${whoBlame.getBrand()} asks me to:`,
    >                            75)
    >     return def stub {
    >         to intro(bobWho) {               # as S2           # 07
    >             log(`meet ${bobWho.getBrand()}`)
    >             def s3 := makeStub(beMe,bobWho,targ,reportln)  # 08
    >             return wrap(s3, bobWho, beMe)}                 # 09
    >         to deliver(verb, [p3Desc]) {     # as S1           # 14
    >             log(`$verb/1`)
    >             def [=="t", gs3, carolWho] := p3Desc           # 15
    >             def s3 := unwrap(gs3, carolWho, beMe)          # 16
    >             def p3 := makeProxy(beMe,carolWho,s3,reportln) # 27
    >             E.call(targ, verb, [p3])}}}                    # 28
    # value: <makeStub>

Code to help establish initial Horton connectivity:

    ? def makeBrand := <elib:sealing.makeBrand>

    ? def makePrincipal(label :String) {
    >     def reportln := makeQuoteln(println, `$label said:`, 77)
    >     def [whoMe,beMe] := makeBrand(label)
    >     return def principal {
    >         to __printOn(out :TextWriter) {out.print(label)}
    >         to who() {return whoMe}
    >         to encodeFor(targ, whoBlame) {
    >             def stub := makeStub(beMe, whoBlame, targ, reportln)
    >             return wrap(stub, whoBlame, beMe)}
    >         to decodeFrom(gift, whoBlame) {
    >             def stub := unwrap(gift, whoBlame, beMe)
    >             return makeProxy(beMe, whoBlame, stub, reportln)}}}
    # value: <makePrincipal>

The players:

    ? def alice := makePrincipal("Alice")
    # value: Alice

    ? def bob := makePrincipal("Bob")
    # value: Bob

    ? def carol := makePrincipal("Carol")
    # value: Carol

Initial connectiivity:

    ? def gs1 := bob.encodeFor(b, alice.who())

    ? def gs2 := carol.encodeFor(c, alice.who())

    ? def p1  := alice.decodeFrom(gs1, bob.who())
    ? def p2  := alice.decodeFrom(gs2, carol.who())
    ? def a := makeA(p1,p2)

Here's what Who's sound like:

    ? a.start()
    # stdout: Alice said:
    #         > I ask Bob to:
    #         > > foo/1
    #         Carol said:
    #         > Alice asks me to:
    #         > > meet Bob
    #         Bob said:
    #         > Alice asks me to:
    #         > > foo/1
    #         Bob said:
    #         > I ask Carol to:
    #         > > hi/1
    #         Carol said:
    #         > Bob asks me to:
    #         > > meet Carol
    #         Carol said:
    #         > Bob asks me to:
    #         > > hi/1
    #         hi
    #


More information about the cap-talk mailing list