From markm@eros.cs.jhu.edu Mon Feb 25 02:22:36 2002 From: markm@eros.cs.jhu.edu (Mark Miller) Date: Sun, 24 Feb 2002 21:22:36 -0500 Subject: [e-cvs] cvs commit: e/doc Makefile Message-ID: <200202250222.g1P2Ma408811@eros.cs.jhu.edu> markm 02/02/24 21:22:36 Modified: doc Makefile Log: this is a test Revision Changes Path 1.43 +1 -1 e/doc/Makefile Index: Makefile =================================================================== RCS file: /cvs/e/doc/Makefile,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- Makefile 23 Dec 2001 21:43:23 -0000 1.42 +++ Makefile 25 Feb 2002 02:22:36 -0000 1.43 @@ -1,5 +1,5 @@ # This Makefile is hereby placed in the public domain. -# + # Makefile for $(TOP)/doc # Note that we now depend on Java JDK >= 1.2 From markm@eros.cs.jhu.edu Mon Feb 25 07:51:11 2002 From: markm@eros.cs.jhu.edu (Mark Miller) Date: Mon, 25 Feb 2002 02:51:11 -0500 Subject: [e-cvs] cvs commit: e/doc/Templates pink.dwt Message-ID: <200202250751.g1P7pBh28694@eros.cs.jhu.edu> markm 02/02/25 02:51:11 Modified: doc/Templates pink.dwt Log: finally checking in again Revision Changes Path 1.24 +2 -2 e/doc/Templates/pink.dwt Index: pink.dwt =================================================================== RCS file: /cvs/e/doc/Templates/pink.dwt,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- pink.dwt 15 Nov 2001 05:07:52 -0000 1.23 +++ pink.dwt 25 Feb 2002 07:51:11 -0000 1.24 @@ -97,8 +97,8 @@
-def CoveredCallOptionMaker(timer, # access to a real-world time service +# E sample + +def CoveredCallOptionMaker(timer, # access to a real-world time service escrowedStock, # reserves stock while offer is OPEN - escrowedMoney # intermediate money-transfer purse + escrowedMoney, # intermediate money-transfer purse # The 3 args above are from broker. The 4 below from options-writer stockSrc, # provides the stock offered for sale deadline :integer, # time until which the offer is OPEN moneyDest, # where the seller receives payment - exercisePrice :integer) # the price that must be paid for the stock -:any { + exercisePrice :integer # the price that must be paid for the stock +) :any { def numShares :integer := stockSrc getBalance() # how many shares are offered escrowedStock deposit(numShares, stockSrc) # escrow all the shares in stockSrc - def state := "OPEN" # one of OPEN, CLOSED, or CANCELLED + var state := "OPEN" # one of OPEN, CLOSED, or CANCELLED def cancel() { if (state == "OPEN") { @@ -280,7 +282,7 @@ } } timer after(deadline - timer now(), cancel) # after the deadline passes, call cancel() - + def CoveredCallOption { to printOn(out) { if (state == "OPEN") { @@ -295,11 +297,11 @@ to getNumShares() :any { numShares } to getExercisePrice() :any { exercisePrice } to getDeadline() :any { deadline } - + to exercise(moneySrc, stockDest) { - require(state == "OPEN", _{"not open"}) # throws "not open" if test fails - require(timer now() < deadline, _{"too late"}) - + require(state == "OPEN", thunk{"not open"}) # throws "not open" if test fails + require(timer now() < deadline, thunk{"too late"}) + escrowedMoney deposit(exercisePrice, moneySrc) # only if the call-writer can be properly paid do we proceed state := "CLOSED" @@ -396,12 +398,16 @@ object:
--def TitleCompanyMaker(precious, name) :any { - require(precious != null, _{"must provide an object"}) +# E sample + +def BrandMaker := <import:org.erights.e.elib.sealing.Brand> + +def TitleCompanyMaker(precious, name) :any { + require(precious != null, thunk{"must provide an object"}) def [sealer, unsealer] := BrandMaker pair(name) - def PurseMaker(myPrecious) :any { + def PurseMaker(var myPrecious) :any { def extract() :any { - require(myPrecious != null, _{"empty"}) + require(myPrecious != null, thunk{"empty"}) def result := myPrecious myPrecious := null result @@ -412,7 +418,7 @@ to sprout() :any { PurseMaker(null) } to getExtract() :any { sealer seal(extract) } to deposit(src) { - require(myPrecious == null, _{"full"}) + require(myPrecious == null, thunk{"full"}) myPrecious := unsealer unseal(src getExtract())() } to exercise(verb, args) :any { @@ -523,8 +529,8 @@1.45 +64 -41 e/doc/elib/capability/ode/ode-capabilities.html Index: ode-capabilities.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-capabilities.html,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- ode-capabilities.html 15 Nov 2001 05:08:01 -0000 1.44 +++ ode-capabilities.html 25 Feb 2002 15:11:09 -0000 1.45 @@ -194,15 +194,18 @@ such a pair. When the sealer is asked to seal an object it returns an envelope which can only be unsealed by the corresponding unsealer. +alt="Blue Ribbon Campaign" border="0"> +-
-? def [sealer, unsealer] := BrandMaker pair("MarkM") ++? def BrandMaker := <import:org.erights.e.elib.sealing.Brand> +# value: <import:org.erights.e.elib.sealing.Brand> + +? def [sealer, unsealer] := BrandMaker pair("MarkM") # value: [<MarkM sealer>, <MarkM unsealer>] - -? def envelope := sealer seal("Tuna") + +? def envelope := sealer seal("Tuna") # value: <sealed by MarkM> - + ? unsealer unseal(envelope) -# value: Tuna+# value: "Tuna"If the envelope is the can and the unsealer is the can-opener (specific to this brand of cans), then
Tunais the food. (The name-string @@ -239,12 +242,14 @@purses of the same currency, you candepositmoney into one from the other.-def MintMaker(name) :any { +# E sample + +def MintMaker(name) :any { def [sealer, unsealer] := BrandMaker pair(name) def mint { to printOn(out) { out print(`<$name's mint>`) } - - to makePurse(balance :(integer >= 0)) :any { #See Note below + + to makePurse(var balance :(integer >= 0)) :any { #See Note below def decr(amount :(0..balance)) { balance -= amount } @@ -253,7 +258,7 @@ to getBalance() :any { balance } to sprout() :any { mint makePurse(0) } to getDecr() :any { sealer seal(decr) } - + to deposit(amount :integer, src) { unsealer unseal(src getDecr())(amount) balance += amount @@ -265,13 +270,8 @@(The "name" variable and the "printOn" methods illustrate no security properties. They exist purely for debugging purposes.)
-Note: The proper form of the expression - "
-(integer >= 0)" depends on the version - of E. In E <= 0.8.9, this is written as "(_ >= 0)". - In E > 0.8.9 & E < 0.8.10, this is written as "(any - >= 0)". In E >= 0.8.10, this is written as "(integer - >= 0)", as shown above.This simple piece of code demonstrably has the following security properties +
This simple piece of code demonstrably has the following security properties +
-
- Only someone with the mint of a given currency can violate conservation of that currency.
@@ -283,16 +283,27 @@- A reported successful deposit can be trusted as much as one trusts the purse one is depositing into.
To understand this, let's walk through how Alice pays Bob $10. We skip - how we arrive at our initial conditions, where Alice and Bob each have - a main purse of the same currency, and Alice already has at least $10. -
-First, playing Alice, we would sprout a new purse from our main purse, +
To understand this, let's walk through how Alice pays Bob $10. First, + let's model our initial conditions, where Alice and Bob each have a main + purse of the same currency, and Alice already has at least $10.
+++? def CarolMint := MintMaker("Carol") +# value: <Carol's mint> + +? def AliceMainPurse := CarolMint makePurse(1000) +# value: <has 1000 Carol bucks> + +? def BobMainPurse := CarolMint makePurse(0) +# value: <has 0 Carol bucks>+Let's imagine that Carol (the mint owner) sends these purses as arguments + in messages to Alice and Bob respectively.
+First, playing Alice, we would sprout a new purse from our main purse, and then transfer $10 into it:
@@ -300,7 +311,7 @@ containing $10 as payment:? def paymentForBob := AliceMainPurse sprout() -# value: <has 0 MarkM bucks> +# value: <has 0 Carol bucks> ? paymentForBob deposit(10, AliceMainPurse)
-? bob foo(..., paymentForBob, ...)+bob foo(..., paymentForBob, ...)
(Although it may not be obvious, in the above figure the three rightward @@ -317,21 +328,33 @@ } }
This last
depositoperation is key. Its success assures - Bob that his main purse has been credited with $10. Under all other conditions - it must fail. Under all conditions, the integrity of the money - system must be conserved. All this despite the use of the payment parameter - which, since it was received from an untrusted source, may be any arbitrary - object. Thedepositmethod must verify that thesrc- purse is a purse of the same currency, and if so, that it has adequate - funds to cover the transfer. If so it must decrement thesrc- purse'sbalanceby this amount and increment its ownbalance- by that same amount. The problem? How can we allow thesrc- purse to be told to decrement itsbalanceby a sibling purse - (one of the same currency), but not allow a client of the purse, such - as Alice, to violate conservation of currency by making the same request? - Conversely, how can we prevent Alice from providing a bogus purse that - claims it has decremented itself, only to fool Bob's purse into incrementing + So playing Bob, we perform +++? BobMainPurse deposit(10, paymentForBob)+Our new balances are
+++? BobMainPurse getBalance() +# value: 10 + +? AliceMainPurse getBalance() +# value: 990+This last
depositoperation is key. Its success assures + Bob that his main purse has been credited with $10. Under all other conditions + it must fail. Under all conditions, the integrity of the money + system must be conserved. All this despite the use of the payment parameter + which, since it was received from an untrusted source, may be any arbitrary + object. Thedepositmethod must verify that thesrc+ purse is a purse of the same currency, and if so, that it has adequate + funds to cover the transfer. If so it must decrement thesrc+ purse'sbalanceby this amount and increment its ownbalance+ by that same amount. The problem? How can we allow thesrc+ purse to be told to decrement itsbalanceby a sibling purse + (one of the same currency), but not allow a client of the purse, such + as Alice, to violate conservation of currency by making the same request? + Conversely, how can we prevent Alice from providing a bogus purse that + claims it has decremented itself, only to fool Bob's purse into incrementing itself at no cost to Alice?In the
@@ -425,8 +448,8 @@depositmethod, the payment is bound to thesrcparameter and the following body is executed:1.20 +2 -2 e/doc/elib/capability/ode/ode-game.html Index: ode-game.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-game.html,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- ode-game.html 15 Nov 2001 05:08:01 -0000 1.19 +++ ode-game.html 25 Feb 2002 15:11:09 -0000 1.20 @@ -97,8 +97,8 @@ +alt="Blue Ribbon Campaign" border="0"> +1.37 +1 -1 e/doc/elib/capability/ode/ode-linear.html Index: ode-linear.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-linear.html,v retrieving revision 1.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- ode-linear.html 17 Apr 2001 23:08:28 -0000 1.36 +++ ode-linear.html 25 Feb 2002 15:11:09 -0000 1.37 @@ -1669,7 +1669,7 @@ +alt="Blue Ribbon Campaign" border="0"> +[Szabo97] Nick Szabo, "Formalizing and Securing Relationships on Public Networks", First Monday, vol - 2 no 9, updated copy at http://www.best.com/~szabo/formalize.html + 2 no 9, updated copy at http://szabo.best.vwh.net/formalize.html
[Tanenbaum86] Andrew S. Tanenbaum, Sape J. Mullender, Robbert van Renesse, "Using Sparse Capabilities in 1.39 +216 -182 e/doc/elib/capability/ode/ode-objects.html Index: ode-objects.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-objects.html,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- ode-objects.html 15 Nov 2001 05:08:01 -0000 1.38 +++ ode-objects.html 25 Feb 2002 15:11:09 -0000 1.39 @@ -47,84 +47,90 @@
- -Object computation can be understood as the sum of three elements [Goldberg76] + +
Object computation can be understood as the sum of three elements [Goldberg76] [Hewitt73]:
--Objects == Lambda Abstraction + Message Dispatch +
+-Objects == Lambda Abstraction + Message Dispatch + Local Side Effects
(footnote: The remaining feature often thought to be defining - of object-oriented programming is inheritance. Though we do not view inheritance - as as a fundamental ingredient of object computation, its widespread use - in object-oriented programming practice motivates its inclusion in E. - However, E's reconciliation of inheritance with capability security principles - [Miller99] is beyond the scope +
(footnote: The remaining feature often thought to be defining + of object-oriented programming is inheritance. Though we do not view inheritance + as as a fundamental ingredient of object computation, its widespread use + in object-oriented programming practice motivates its inclusion in E. + However, E's reconciliation of inheritance with capability security principles + [Miller99] is beyond the scope of this paper.)
Lambda Abstraction
-Lambda abstraction [Church41] - is a pure theory of nested function definition and application. In E notation, - conventional function definition and application should look familiar: -
-
-def factorial(n) :any { +Lambda abstraction [Church41] + is a pure theory of nested function definition and application. In E notation, + conventional function definition and application should look familiar: +
+
+- The only unfamiliar element is the use of "# E sample + +def factorial(n) :any { if (n <= 0) { 1 } else { n * factorial(n-1) } } - ++? factorial(3) # value: 6:any" - rather than an explicit return statement. Like Lisp and Smalltalk, E is - an expression language -- the value of a block of expressions is the value - of the last expression in that block. This value is filtered through the - optional returns type declaration. ":any" - allows any value to be returned. If no return type is declared, then null - is returned. (*** This detail comes too early. Must - move into a footnote or something.) -Nested function definition, familiar from all lexical lambda languages + The only unfamiliar element is the use of "
:any" + rather than an explicit return statement. Like Lisp and Smalltalk, E is + an expression language -- the value of a block of expressions is the value + of the last expression in that block. This value is filtered through the + optional returns type declaration. ":any" + allows any value to be returned. If no return type is declared, then null + is returned. (*** This detail comes too early. Must + move into a footnote or something.) +Nested function definition, familiar from all lexical lambda languages including ALGOL60, Scheme, and ML, should also look familiar:
--
-def adderCreator(x) :any { ++
+-# E sample + +def adderCreator(x) :any { def adder(y) :any { x + y } } - ++? def addThree := adderCreator(3) # value: <adder> - + ? addThree(5) # value: 8The call to
adderCreatorreturns a version - of theadderfunction that adds3to its argument. - Church originally thought about this as substitution -- return anadder- function in whichxhas been replaced by3. - Unfortunately, this simple perspective generalizes poorly. An alternative - perspective is to consider a function, such as that held in theaddThree- variable, to be a combination of a behavior -- the static code - for adder, and state -- the runtime bindings for its free - variables.xinadderis a free variable in - thatadderusesx, but the corresponding definition - ofxis inherited fromadder's creating context. - In the remainder of this paper, we will refer to such free state variables - as instance variables. -Such functions already have the most often cited attribute - of objects: they are a combination of encapsulated state together with - behavior that has exclusive access to that state. Ignoring for a moment - the message-name
foo, the Granovetter Diagram describes an - important aspect of the lambda calculus. Imagine that Alice, Bob, and - Carol are three functions. If, in the initial conditions, Alice contains - a binding for Bob and Carol, then Alice's behavior can give Bob access - to Carol. --
+The call to
adderCreatorreturns a version + of theadderfunction that adds3to its argument. + Church originally thought about this as substitution -- return anadder+ function in whichxhas been replaced by3. + Unfortunately, this simple perspective generalizes poorly. An alternative + perspective is to consider a function, such as that held in theaddThree+ variable, to be a combination of a behavior -- the static code + for adder, and state -- the runtime bindings for its free + variables.xinadderis a free variable in + thatadderusesx, but the corresponding definition + ofxis inherited fromadder's creating context. + In the remainder of this paper, we will refer to such free state variables + as instance variables. +Such functions already have the most often cited attribute + of objects: they are a combination of encapsulated state together with + behavior that has exclusive access to that state. Ignoring for a moment + the message-name
foo, the Granovetter Diagram describes an + important aspect of the lambda calculus. Imagine that Alice, Bob, and + Carol are three functions. If, in the initial conditions, Alice contains + a binding for Bob and Carol, then Alice's behavior can give Bob access + to Carol. ++
def ... { # enclosing context def bob := ... # instance variable bob somehow bound to Bob def carol := ... # instance variable carol somehow bound to Carol @@ -135,19 +141,21 @@ }Adding Message Dispatch
-The most visible difference between a function and an object is that - a function's behavior is written to satisfy just one kind of request, - and all calls on that function are forms of that one request. By contrast, - an object's behavior enables it to satisfy a variety of different requests - (each with a separate method). A request to an object (a message) - identifies which of these requests is being made. There is nothing fundamental - here; objects have been trivially built from functions, and vice-versa, - many times in the history of computer science. In E, behaviors-as-bundles-of-methods - and requests-as-messages are the more primitive notions, of which functions +
The most visible difference between a function and an object is that + a function's behavior is written to satisfy just one kind of request, + and all calls on that function are forms of that one request. By contrast, + an object's behavior enables it to satisfy a variety of different requests + (each with a separate method). A request to an object (a message) + identifies which of these requests is being made. There is nothing fundamental + here; objects have been trivially built from functions, and vice-versa, + many times in the history of computer science. In E, behaviors-as-bundles-of-methods + and requests-as-messages are the more primitive notions, of which functions are a degenerate case.
--
--def PointMaker(x,y) :any { ++
+# E sample + +def PointMaker(x,y) :any { def Point { to printOn(out) { out print(`<$x,$y>`) } to getX() :any { x } @@ -157,66 +165,67 @@ } } } - ++? def p := PointMaker(3,5) -# value: <3,5> - +# value: <3,5> + ? p getX() # value: 3 - + ? p + PointMaker(4,8) -# value: <7,13>+# value: <7,13>From a lambda-calculus perspective,
PointMakeris likeadderCreator- -- it is a lexically enclosing function that defines the variable bindings - used by the object it both defines and returns. From an object perspective, -PointMakeris simultaneously like a class and constructor - -- both defining the instance variables forPoints, and creating, - initializing, and returning individualPoints. We have found - such lambda-based object definition to be simpler, more expressive, and - more intuitive, than either of the common choices -- class-based and prototype-based - object definition. The lambda-based technique for defining objects dates - back at least to 1973 [Hewitt73], - so we find it distressing that the other two are often assumed to be the +From a lambda-calculus perspective,
-PointMakeris likeadderCreator+ -- it is a lexically enclosing function that defines the variable bindings + used by the object it both defines and returns. From an object perspective, +PointMakeris simultaneously like a class and constructor + -- both defining the instance variables forPoints, and creating, + initializing, and returning individualPoints. We have found + such lambda-based object definition to be simpler, more expressive, and + more intuitive, than either of the common choices -- class-based and prototype-based + object definition. The lambda-based technique for defining objects dates + back at least to 1973 [Hewitt73], + so we find it distressing that the other two are often assumed to be the only available choices.The returned
Points are clearly object-like rather than - function-like. EachPoint's behavior contains four methods - --printOn,getX,getY, andadd- -- and every request to aPointstarts by naming which of - these services is being requested. Now we see that thefoo- in the Granovetter Diagram is simply a message-name. Extending our earlier +The returned
-Points are clearly object-like rather than + function-like. EachPoint's behavior contains four methods + --printOn,getX,getY, andadd+ -- and every request to aPointstarts by naming which of + these services is being requested. Now we see that thefoo+ in the Granovetter Diagram is simply a message-name. Extending our earlier example, Alice's behavior would be:-
++
bob foo(..., carol, ...)Some shortcuts above need a brief explanation.
-+
-
-- +
- -
"
a + b" is merely syntactic shorthand for "a add(b)", and similarly for other expression operators.- +
- -
The command line interpreter prints a value by sending it the
printOnmessage.- +
- -
The string between back-quotes and containing $-prefixed expressions is a quasi-string. Like interpolated strings in Perl, it evaluates to a string by evaluating the nested expressions and printing them into the enclosing string.
- +
Finally, functions are simply one-method objects where the method is named "
run". The previousadderCreatoris therefor just syntactic shorthand for:-
++
-def adderCreator { to run(x) :any { def adder { @@ -228,68 +237,73 @@ }+
Adding Side Effects
-Two features of object programming implied by the Granovetter Diagram +
Two features of object programming implied by the Granovetter Diagram have been left out of computation as so far described.
-+
-
- -
First, the diagram implies that Bob is obtaining access to Carol, - but computation as so far described gives Bob no means for holding +
- +
-First, the diagram implies that Bob is obtaining access to Carol, + but computation as so far described gives Bob no means for holding on to this access.
- -
Second, we understand the diagram to say that Alice is giving Bob - access to Carol herself, not a copy of Carol [Deutsch99]. - However, in computation as has been described so far, Carol is indistinguishable - from a copy of Carol. We cannot distinguish between pass-by-reference-sharing - and pass-by-copy, but the Granovetter Diagram clearly intends to show - specifically pass-by-reference-sharing. Were computation adequately - described purely in terms of pass-by-copy, the Granovetter Diagram +
- +
Second, we understand the diagram to say that Alice is giving Bob + access to Carol herself, not a copy of Carol [Deutsch99]. + However, in computation as has been described so far, Carol is indistinguishable + from a copy of Carol. We cannot distinguish between pass-by-reference-sharing + and pass-by-copy, but the Granovetter Diagram clearly intends to show + specifically pass-by-reference-sharing. Were computation adequately + described purely in terms of pass-by-copy, the Granovetter Diagram would be unnecessary.
The introduction of side effects solves both of these problems.
-Starting with lambda calculus (or with lambda plus message dispatch), - there are many ways to add side effects. The approach used by E, Scheme, - ML and many other lambda languages is to introduce assignment.
-How does assignment make Carol potentially distinct from a duplicate +
Starting with lambda calculus (or with lambda plus message dispatch), + there are many ways to add side effects. The approach used by E, Scheme, + ML and many other lambda languages is to introduce assignment. In E, variables + are non-assignable (or "
+final") by default. + For a variable to be assignable, it must be declared with "var".How does assignment make Carol potentially distinct from a duplicate of Carol? Consider:
--
-def CounterMaker() :any { - def count := 0 ++
+-# E sample + +def CounterMaker() :any { + var count := 0 def Counter { to getCount() :any { count } to incr() { count += 1 } } } - ++? def carol := CounterMaker() -# value: <counter> - +# value: <Counter> + ? carol getCount() # value: 0 - + ? carol incr() ? carol getCount() # value: 1Two otherwise identical
Counters are distinct because they - have distinctcountvariables that increment separately. - All those who have access to the sameCounterare able to - see the side effects ofincrmessages sent by others who +Two otherwise identical
-Counters are distinct because they + have distinctcountvariables that increment separately. + All those who have access to the sameCounterare able to + see the side effects ofincrmessages sent by others who have access to this sameCounter.How does assignment enable Bob to retain access he has been given to - Carol? By assigning an incoming message-argument to an
instance +How does assignment enable Bob to retain access he has been given to + Carol? By assigning an incoming message-argument to an
-instance variable:-
++
def BobMaker() :any { - def carol := null + var carol := null def Bob { to foo(..., newCarol, ...) { carol := newCarol @@ -300,63 +314,83 @@Composites & Facets
-Technically, by introducing assignment, we have made each variable into - a distinct primitive variable-object. A user-defined object then contains - bindings from the names of these variables to these variable-objects. - The variable-objects in turn contain the bindings to the current values - of the variables. When the programmer writes a use-occurrence of the variable - in an expression, this causes the containing object to send a
-getValue- message to the variable-object to get its current value. When the programmer - writes an assignment, this causes the containing object to send asetValue- message to the variable-object.When a variable is only in the scope of one object, as in all the above - examples, we usually ignore this distinction, and speak as if the containing - object has bindings directly from the variable names to the current values +
Technically, by introducing assignment, we have made each assignable + variable into a distinct primitive variable-object, referred to as a
+Slot. + A user-defined object then contains bindings from the names of these variables + to these Slots. The Slots in turn contain the bindings to the current + values of the variables. When the programmer writes a use-occurrence of + the variable in an expression, this causes the containing object to send + agetValue()message to the Slot to get its current value. + When the programmer writes an assignment, this causes the containing object + to send asetValue(newValue)message to the Slot.When a variable is only in the scope of one object, as in all the above + examples, we usually ignore this distinction, and speak as if the containing + object has bindings directly from the variable names to the current values of these variables. But this shortcut does not work for code such as:
--
-def getterSetterPair(value) :any { - def getter() :any { value } - def setter(newValue) { value := newValue } - [getter, setter] ++
+-# E sample + +def incrDecrPair(var value) :any { + def incr { + to countUp() :any { value += 1 } + } + def decr { + to countDown() :any { value -= 1 } + } + [incr, decr] }+? def [i, d] := incrDecrPair(3) +# value: [<incr>, <decr>] + +? i countUp() +# value: 4 + +? i countUp() +# value: 5 + +? d countUp() +# problem: <NoSuchMethodException: <a decr> countUp/0> + +? d countDown() +# value: 4Each time
+getterSetterPairis called, it defines a newvalue- variable and returns a list of two functions, one that will get the value - of this variable and one that will set it. This is a trivial example of - a useful technique -- defining several objects in the same scope, each - providing different operations for manipulating a common state held in - that scope.Each time
incrDecrPairis called, it defines a newvalue+ variable and returns a list of two functions, one that will increment + and return the value of this variable and one that will decrement and + return it. This is a trivial example of a useful technique -- defining + several objects in the same scope, each providing different operations + for manipulating a common state held in that scope.-
On the left we see, diagrammed in explicit detail, the objects and relationships - resulting from a call to
getterSetterPair. On the right, - the triple is visualized as a single composite. Like an individual object, - a composite is a combination of state and behavior. Like an individual - object, the state consists of all of the variables within the composite. - The behavior consists of all of the code within the composite, but here +On the left we see, diagrammed in explicit detail, the objects and relationships + resulting from a call to
-incrDecrPair. On the right, the + triple is visualized as a single composite. Like an individual object, + a composite is a combination of state and behavior. Like an individual + object, the state consists of all of the variables within the composite. + The behavior consists of all of the code within the composite, but here we have an important difference.The behavior elicited by a message to the composite depends not just - on the message, but, obviously, on which object of the composite receives - the message. Objects on the surface of the composite -- objects which - may be referred to from outside the composite, like
getter- andsetter-- are facets of the composite. The variable-object, -value, need not be considered a facet since we can tell that +The behavior elicited by a message to the composite depends not just + on the message, but, obviously, on which object of the composite receives + the message. Objects on the surface of the composite -- objects which + may be referred to from outside the composite, like
-incr+ anddecr-- are facets of the composite. The variable-object, +value, need not be considered a facet since we can tell that no reference to it can escape from the composite.The aggregation of a network of objects into a composite is purely subjective - -- it allows us to hide detail when we wish. The technique works because - the possible interactions among composites obey the same rules as the - possible interactions among individual objects -- these rules are therefor +
The aggregation of a network of objects into a composite is purely subjective + -- it allows us to hide detail when we wish. The technique works because + the possible interactions among composites obey the same rules as the + possible interactions among individual objects -- these rules are therefor compositional.
The Dynamic Reference Graph
-When speaking of object computation, all too much emphasis is often placed - on the objects themselves. The fabric of an object system is the dynamic - reference graph. As suggested by the Granovetter Diagram, objects (or - composites) are the nodes of this graph and references are the arcs. Only - computation within the graph brings about changes to the topology - of the graph (the who refers to whom relationships), and it only - brings about those changes that are enabled by the graph's current topology. - To learn the perspective of the Granovetter Diagram is to see the dynamic +
When speaking of object computation, all too much emphasis is often placed + on the objects themselves. The fabric of an object system is the dynamic + reference graph. As suggested by the Granovetter Diagram, objects (or + composites) are the nodes of this graph and references are the arcs. Only + computation within the graph brings about changes to the topology + of the graph (the who refers to whom relationships), and it only + brings about those changes that are enabled by the graph's current topology. + To learn the perspective of the Granovetter Diagram is to see the dynamic reference graph as primary, and objects themselves as secondary [Kay99].
@@ -406,8 +440,8 @@ 1.26 +2 -2 e/doc/elib/capability/ode/ode-pki.html Index: ode-pki.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-pki.html,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- ode-pki.html 15 Nov 2001 05:08:01 -0000 1.25 +++ ode-pki.html 25 Feb 2002 15:11:09 -0000 1.26 @@ -155,8 +155,8 @@ +alt="Blue Ribbon Campaign" border="0"> +1.36 +6 -6 e/doc/elib/capability/ode/ode-protocol.html Index: ode-protocol.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-protocol.html,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- ode-protocol.html 15 Nov 2001 05:08:01 -0000 1.35 +++ ode-protocol.html 25 Feb 2002 15:11:09 -0000 1.36 @@ -186,15 +186,15 @@ into it: +alt="Blue Ribbon Campaign" border="0"> +
-? def paymentForBob := AliceMainPurse sprout() -# value: <has 0 MarkM bucks>+def paymentForBob := AliceMainPurse sprout() +value: <has 0 Carol bucks>This statement causes Alice's vat (VatA) to send a message to the mint's vat (VatM). The message includes the Swiss number of
AliceMainPurseand the operationsprout. VatM creates a new object as a result of the message and sends its Swiss number back to Alice.-? paymentForBob deposit(10, AliceMainPurse)+paymentForBob deposit(10, AliceMainPurse)VatA sends another message to VatM including the Swiss number of the newly created
paymentForBobpurse and thedeposit@@ -205,7 +205,7 @@ containing $10 as payment.
-? bob foo(..., paymentForBob, ...)+bob foo(..., paymentForBob, ...)VatA sends a message to Bob's vat (VatB) passing the Swiss number of the
bobobject and the operationfoo. The parameters @@ -280,8 +280,8 @@1.36 +3 -3 e/doc/elib/capability/ode/ode-references.html Index: ode-references.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-references.html,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- ode-references.html 15 Nov 2001 05:08:01 -0000 1.35 +++ ode-references.html 25 Feb 2002 15:11:09 -0000 1.36 @@ -163,7 +163,7 @@ +alt="Blue Ribbon Campaign" border="0"> +[Szabo97] Nick Szabo, "Formalizing and Securing Relationships on Public Networks", First Monday, vol - 2 no 9, updated copy at http://www.best.com/~szabo/formalize.html + 2 no 9, updated copy at http://szabo.best.vwh.net/formalize.html
[Tanenbaum86] Andrew S. Tanenbaum, Sape J. Mullender, Robbert van Renesse, "Using Sparse Capabilities in @@ -228,8 +228,8 @@
1.7 +1 -1 e/doc/elib/capability/ode/ode-submission.html Index: ode-submission.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-submission.html,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ode-submission.html 30 Apr 2001 20:36:05 -0000 1.6 +++ ode-submission.html 25 Feb 2002 15:11:09 -0000 1.7 @@ -1418,7 +1418,7 @@ University of Pennsylvania, 1999. http://www.cis.upenn.edu/~shap/EROS/thesis.ps +alt="Blue Ribbon Campaign" border="0"> +[Szabo97] Nick Szabo, Formalizing and Securing Relationships on Public Networks, - First Monday, vol 2 no 9, updated copy at http://www.best.com/~szabo/formalize.html + First Monday, vol 2 no 9, updated copy at http://szabo.best.vwh.net/formalize.html
[Tribble95] E. Dean Tribble, Mark S. Miller, Norm Hardy, Dave Krieger, "Joule: Distributed Application Foundations", http://www.agorics.com/joule.html, 1995.
1.21 +2 -2 e/doc/elib/capability/ode/ode-uber.html Index: ode-uber.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/ode-uber.html,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- ode-uber.html 15 Nov 2001 05:08:01 -0000 1.20 +++ ode-uber.html 25 Feb 2002 15:11:09 -0000 1.21 @@ -172,8 +172,8 @@1.6 +2 -2 e/doc/elib/capability/ode/overview.html Index: overview.html =================================================================== RCS file: /cvs/e/doc/elib/capability/ode/overview.html,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- overview.html 15 Nov 2001 05:08:01 -0000 1.5 +++ overview.html 25 Feb 2002 15:11:09 -0000 1.6 @@ -370,8 +370,8 @@ +alt="Blue Ribbon Campaign" border="0"> + +alt="Blue Ribbon Campaign" border="0"> +