ERights Home history / joule 
No Previous Sibling On to: The Bouncer: Proving Properties of Instruction-Level Programs

Joule Quick Reference 1.0


From http://www.agorics.com/Library/Joule/quickref.html:


This document provides reference information for the existing Joule implementation.

1. Basic Concepts


Joule embodies a new computational model for building distributed systems. A running Joule system consists of many servers concurrently and asynchronously sending messages to each other. Picture a Joule computation not as a sequence of instructions ordered in time, but as a dataflow diagram spread out in space; focus not on what happens when, but on what is connected to what else.

Every object in a Joule system, from complex databases and bank accounts down to simple arrays and numbers, is a server. To get a server to do work (that is, to make use of its service), you send a message to it. (For example, you could send a get: message to an array server to obtain one of its elements.)

Joule channels provide the "message plumbing" that interconnects servers into complex systems; they are unidirectional pipelines through which messages are conveyed. A channel is (of course) itself a server, with two facets: an acceptor and a distributor. (A server's facets represent subsets of its behavior.) Messages sent to the acceptor are carried through the channel to be delivered eventually to other servers. Messages sent to the distributor control to which other servers the channel delivers its messages.

When a channel is forwarded to (i.e., delivers to) only a single server, messages to the acceptor of the channel act just like messages sent directly to the server. Thus, channels are transparent to message sending. This is the typical case because it is used to get results back from requests.

All servers to which a channel forwards are guaranteed to receive all messages (ever) sent to the channel's acceptor. Again, the important thing is not when things happen, but how things are connected.

When executing, a server can refer only to servers that it already knows, that it creates, or that are handed to it by other servers. It can send messages to these servers, pass these servers as arguments in such messages, create new servers, and change which servers it remembers.


2. Techniques and Idioms

2.1 Message Sending


Sending a message, the core activity in a Joule program, takes the form

· <RECEIVER> <MESSAGE> 
. Typically, the message contains an operation and arguments. By convention, for operations that produce a value, the last argument is a distributor which will be forwarded to that value. For example:
· account withdraw: amount result> 

2.2 Server-Creating Procedure


When multiple instances of a server are needed, nest the server definition inside a procedure for creating instances of that server. The procedure accepts values for initializing the instance. Its result port must be forwarded to the nested server. For example:
Server makeFund :: balance fund> 
    ·fund>  ->  theFund 
    Server theFund 
       var myBalance = balance
       ... 
    endServer
    ...  
endServer
 


2.3 Looping via Recursion


An efficient looping mechanism involves a function that calls itself with different arguments. When you use recursion in this way, the stack does not need to duplicate state for each iteration. For example:

Reveal the new total after interest on the given principal accumulates at the given rate for the given units of time.
Server accInterest :: principal units rate 
total> 

    If units > 0 
       Def sofar = principal * rate + 1 
       The recursion occurs in the line below. 
       · accInterest :: sofar (units   1) rate total> 
    else 
       · total> -> principal 
    endIf
endServer

 

3. Selected Terms



module The basic unit of Joule code that can be loaded into a system.
   export A server explicitly exported by a module, making it accessible to any importing module.
   import A module that supplies facilities required by the current module; or, a server supplied by an imported module.


server An object in a Joule program, so named because it supplies services to other servers.
   composite Applies to a server whose behavior is provided by Joule code. Such a server builds upon the services of more primitive servers.
   primitive Applies to a server that is built into the Joule implementation, such as a number, or that is supplied externally.
   facet Access to a subset of the server's methods, called the facet's behavior. All facets of a server share the server's state, so messages to different facets of the same server are serialized.
   instance variable A variable that holds a piece of the server's state. All state in Joule is held in this way.
   method A block of code defining the action that a server takes in response to a message.
   methodical Applies to a facet that provides a fixed set of services, which it will perform separately in response to specific messages. This is the usual type of facet, and is like an object in a traditional object-oriented language.
   non-methodical Applies to a facet that provides a single generic service in response to any message, regardless of the particulars of the message, such as transparently forwarding the message.
   port A reference to a server facet. Messages sent to a port are ultimately delivered to the corresponding facet.
   procedural server A methodical server that provides a single service, in response to a '::' message.
   signature The set of operations supported by a server facet,defining its contract with clients.


message The object sent by one server when communicating with another server. A message is typically an envelope,containing an operation and arguments.
   activation The reception of a message by a server and the ensuing computation in response to that message.
   argument The value supplied for an operation parameter.
   envelope A server that acts as a sealed container for an operation and a set of arguments.
   operation A sealer/unsealer pair, typically corresponding to the name of a method.
   reveal To communicate the result of a computation. The result is typically revealed to the result distributor. Used instead of "return" because "reveal" does not mislead by implying a return of control to the message sender.
   sealer The operation facet that seals arguments into a newly created Envelope. The Envelope created by a sealer can be opened only by the unsealer of the same operation.
   unsealer The operation facet that unseals an envelope to extract its arguments.


channel A message pipeline that starts at an acceptor and ends at a distributor. A channel is transparent: senders cannot distinguish between sending through a channel to a server and sending directly to that server.
   acceptor The channel facet that accepts messages for delivery through the channel. Each such message is forwarded to all servers to which the channel is ever forwarded. Thus, sending messages to the acceptor and forwarding the channel with the distributor can be performed in any order.
   distributor The channel facet that controls delivery of messages. Sending a forward (--> server) message to a distributor causes the channel to deliver to server all messages, past and future, sent to the acceptor of the channel.
   forward To direct a message or a distributor to a receiver. Thus, forward has two distinct meanings, comparable to forwarding a single letter versus forwarding a mailbox.


4. Language Constructs



Production Production Definition
module Module Identifier
{import | export}*
block
endModule
import importModule {Identifier},+
export export {Identifier},+
block {form}*
form send | define | scoping | signal |
server | type | branch | loop
send · simpleExpr {opExpr};+
define Def {param | param = nestExpr},+
|
Define {param | param = nestExpr},*
    block
endDefine
scoping Expose {Identifier},*
   block
endExpose
signal Signal nestExpr
branch If nestExpr
   block
{orIf nestExpr
   block}*
{elseIf nestExpr
   block
{orIf nestExpr
    block}* }*
{else
   block}?
endIf
|
Switch nestExpr
   {case pattern 
   {or pattern}*> 
      block}* 
   {otherwise param 
      block}?
endSwitch
server Server param {method}?
   {var}* 
   ops 
   {facet}*
endServer
var var {param | param = nestExpr},+
   block
ops {implements Identifier}?
{{op | do} method}*
{otherwise param
   block}?
method pattern
   block 
   {change 
   block}*
change
   to Identifier {opExpr};+ 
   | set {Identifier = nestExpr},+
facet facet param ops
type Type param
   {super Identifier}? 
   {{op | do} pattern 
   block 
   {to Identifier {opExpr};+ 
   block}*}*
endType
loop ForAll param {f param}?
   block
endForAll
opExpr simpleExpr |
simpleExpr Operator opExpr
simpleExpr Identifier | Literal |
envelope | '(' nestExpr ')'
nestExpr simpleExpr | simpleExpr opExpr
envelope {Operator | Label} {opExpr}*
pattern {Operator | Label} {param}*
param Identifier

4.1 Reserved Words


Assert, case, Def, Define, do, else, elseIf, endDefine, endExpose, endForAll, endIf, endModule, endServer, endSwitch, endType, export, Expose, facet, ForAll, If, implements, importModule, Module, op, orIf, otherwise, Server, set, Signal, super, Switch, to, Type, var

5. Example

Module FundImpl
 
export FundType, makeFund 


    Type FundType 
         super Basic 
         op balance: balance> 
         op withdraw: amount flag> 
         op deposit: amount flag> 
    endType 

    Server makeFund :: fund>
       . fund> -> theFund 
       Server theFund 
          var myBalance = 0 
          implements FundType 
          op balance: balance> 
             . balance> -> myBalance 
          op withdraw: amount flag> 
             Def newBalance 
             If amount > myBalance
                 . newBalance> -> myBalance
                 . flag> -> false 
             orIf amount 0
                 . newBalance> -> myBalance 
                 . flag> ->false 
             else 
                 . newBalance> -> 
                        myBalance - amount 
                 . flag> -> true 
             endIf 
             set myBalance = newBalance 
           op deposit: amount flag> 
             Def newBalance 
             If amount 0 
                 . newBalance> -> myBalance 
                 . flag> -> false 
             else 
                 . newBalance> -> 
                         myBalance + amount 
                 . flag> -> true 
             endIf 
             set myBalance = newBalance 
        endServer 
      endServer 
endModule 



 

 
Unless stated otherwise, all text on this page which is either unattributed or by Mark S. Miller is hereby placed in the public domain.
ERights Home history / joule 
No Previous Sibling On to: The Bouncer: Proving Properties of Instruction-Level Programs
Download    FAQ    API    Mail Archive    Donate

report bug (including invalid html)

Golden Key Campaign Blue Ribbon Campaign