White paper
UBF(A) spec
UBF(B) spec
UBF(C) spec

Quick start
Erlang servers
Java clients

Message Box
File server




UBF(B) - quick summary

UBF(B) has:

A type system
Strings are written enclosed in double quotes, thus:
A protocol description language
The protocol description language allows allows us to specific client server interaction in terms of a non-deterministic finite state machine.

The type system

The notation:
  • int() Means a UBF(A) integer.
  • string() Means a UBF(A) string.
  • constant() Means a UBF(A) constant.
  • bin() Means a UBF(A) binary data item.
  • X() Means an Object of type X

UBF(A) literals are written as follows:

  • "..." - denotes a UBF(A) string.
  • [a-z][a-zA-Z0-9_]* - denotes a UBF(A) constant.
  • [-][0-9]+ - denotes a UBF(A) integer.

Complex types are defined recursively:

{T1, T2, ..., Tn}
Is the tuple type if T1 .. Tn are types.

We say that {X1, X2, ..., Xn} is of type {T1, T2, ..., Tn} if X1 is of type T1, X2 is of type T2, ... and Xn is of type Tn.

Is the list type if T is a type.

We say that # Xn & Xn-1 & ... X2 & x1 is of type [T] if all Xi are of type T.

T1 | T2
Is the alternation type if T1 and T2 are types.

We say that X is of type T1 | T2 if X is of type T1 or if X is of type T2.

New types

New types are introduced in UBF(B) with the notation:

   +TYPE X() = Type


   +TYPE person() = {person, firstname(), lastname(), sex(), age()}.
   +TYPE firstname() = string(). 
   +TYPE lastname() = string().
   +TYPE age() = int().
   +TYPE sex() = male | female.
   +Type people() = [person()].

This type schema defines a number of different types. For example, it is easily seen that:

   'person' >p 
    # {p "jim" "smith" male 10} & 
    # {p "susan" "jones" female 14} & $
Is of type people().

Note that UBF(B) type is a language independent type schema.

language independent type schema are the basis of Contracts between clients are servers.




info()         = info;
description()  = description;
contract()     = contract;

bool()         = true | false;
nick()         = string();
oldnick()      = string();
newnick()      = string();
group()        = string();
logon()        = logon;
proceed()      = {ok, nick()} "A random nick is assigned";
listGroups()   = groups;
groups()       = [group()];
joinGroup()    = {join, group()} 
	         "You must join a group before you can send a message to it";
leaveGroup()   = {leave, group()};
ok()           = ok;
changeNick()   = {nick, nick()} "Change your nick in all groups";
msg()          = {msg, group(), string()} "send a message to a group";
msgEvent()     = {msg, nick(), group(), string()};
joinEvent()    = {joins, nick(), group()};
leaveEvent()   =  {leaves, nick(), group()};
changeNameEvent() = {changesName, oldnick(),newnick(), group()}.

%% I am assigned an initial (random) nick

+STATE start logon() => proceed() & active. 

+STATE active
   listGroups() => groups() & active;  
   joinGroup()  => ok() & active;
   leaveGroup() => ok() & active;
   changeNick() => bool() & active; 
   msg()        => bool() & active;   % false if you have not joined the group

   EVENT => msgEvent();        % A group sends me a message
   EVENT => joinEvent();       % Nick joins group
   EVENT => leaveEvent();     % Nick leaves group
   EVENT => changeNameEvent(). % Nick changes name

	info()        => string();
	description() => string();
	contract()    => term().