Go to front page

 
 

The presentation of:
From safe concurrent processes to process-classes?
PLUSSING new code by ROLLING out and compile?

Øyvind Teig

CPA 2001 - Communicating Process Architectures
University of Bristol
UK
16-19. Sept. 2001
Presented 18. Sept. 2001, 12:00-12:30
A WoTUG Conference

Start presentation

Last updated: 10.09.2001 09:24

prevnext  - 5 - 10 - 13 - 20 - 25 - 31

1 :: Intro

  • I have found it increasingly hard to just let occam go
  • I feel enthusiasm for Object Orientation..
  • ..but also lack of enthusiasm for OO languages
  • Therefore, these ideas..
  • Is it possible to take safe concurrent processes (of occam)..
  • ..and lead them to become safe process-classes?
  • The paper introduces
    • "PLUSSING" = textually add new code
    • by "ROLLING" it out  = generating new sources
    • and re-compile..
prevtopnext 

2 :: Templates?
Implementation inheritance?
Pattern matching?

  • The paper suggests a methodology for object orientation
    • Somewhere between C++'s templates
    • Java's (and any other OO language's) implementation inheritance
    • and pattern matching
    • for final code insertion and compilation.
  • Occam 2 as a catalyst language turned up to be more suited than I at first thought
prevtopnext  

3 :: Aim and limitations of paper

  • The aim of the paper is to deliver ideas
  • The paper tries to "think aloud"
    • It is not part of any ongoing research
    • contains ideas only
    • collected by a software engineer working in industry
    • As such it may be considered "off piste"
      • ..dangerous skiing off the downhill marked and beaten track
  • Per definition
    • "object orientation" and
    • CSP/ occam
    • are looked upon as "sound" concepts
prevtopnext 

4 :: Wegner's taxonomy of object languages

(1) No object facilities - "Classical languages" (*1)
e.g. C and Pascal
(2) Object based -- system uses objects - "Encapsulation languages" (*1)
e.g. Modula-2
(3) Class based -- system uses objects that are defined by classes
e.g. Ada-8x
(4) Inheritance enabled -- system uses classes and inheritance
e.g. C++ without virtual methods
(5) Object-oriented -- system uses classes, inheritance and polymorphic (virtual) methods
e.g. Ada 95, Smalltalk, Java, Modula-3 & the original Simula
  • This paper will try to move occam towards the object-oriented (OO) mindset,
  • keep process-thinking along the line
  • Inheritance is added, and safe processes are kept

(*1): Bertrand Meyer, Book OOSC-2

prevtopnext 

5 :: The new term: process-classes

Processes (as in occam)
Objects are on land
  • You are yourself proper, a Homo Sapiens - no super process
  • No talking over your head - you see all that is going on
  • No talking through you - no super to pass difficult questions to
  • No aliasing error
  • Thread-safe by birth
Objects (as in OO)
Objects are floating around
  • You are an animal first, then Homo Sapiens - super object exists
  • Talking over your head: and super class may have own state
  • Talking through you - super to pass difficult questions to
  • Aliasing errors may occur
  • Not thread-safe by birth
  • Threads and objects not "orthogonal"
Process-classes (as in this paper)
Occam processes are kept, plus implementation-  and interface inheritance. Static.
Objects are floating, but attached to land
  • You are animal first, then Homo Sapiens - "compiled" super process
  • Talking through you - super process-class takes difficult questions
  • Are processes and process-classes "orthogonal"?
prevtopnext 

6 :: But is "process-class" possible?


  • Does the concept scale?
  • Or is it just some interesting syntax?
  • How are the cognitive properties?
    • ..compared to more standard OO?
prevtopnext 

7 :: Start of rationale
Process "method" interface in occam
is not very useful

PROC SetMethod (CHAN OF SetGet to, VAL INT Data)

  to ! set.NoRe; Data

:

PROC GetMethod (CHAN OF SetGet to, from, INT data)

  SEQ

    to ! get.Re

    from ? CASE get.End; data

:
  • May(?) add context switches
  • SetMethod and GetMethod are reusable components along another line..
  • ..for the SetGet protocol
  • Reusability is a context sensitive trait
prevtopnext 

8 :: Sub-classing through occam
process layering is not practical

  • One process outside of another, which takes over some of the "inner process" functionality
  • This is "sub-classing" through process layering
  • It is not very flexible, since every "function" (tag of the protocol)
    • must be re-implemented
    • and the messages either passed to the super-process and its reply handled,
    • or handled differently locally
  • There is no way whereby a super process will take over the messages not handled by the layering process
  • In other words, so called implementation inheritance is not directly supported
  • ..even if we can program it
  • We cannot in occam state that a "house is a building" easily
prevtopnext

9 :: Polymorphism through occam
anonymous communication scheme is nice

  • In occam we can send the message Bark over a CHANnel
  • A process has no idea who receives the message, it could be a Beagle or a Terrier process
  • Occam communicates over named channels with anonymous processes
  • The dog owner (client) could in fact query Dog which type of Dog it is
    • run-time type inspection
  • So, occam does have a system for polymorphism, even if it is not method naming polymorphism
  • Plugging and unplugging is more difficult in occam than in standard OO languages
  • Maybe this has to do with how occam processes are stopped
  • After a process has been stopped, another user could legally try to communicate with it
    • We do not have a way to differentiate between
      normal waiting forever and pathological waiting forever
  • None of the problems mentioned above have been solved with the suggested solution
prevtopnext 

10 :: Concurrent OO and "inheritance anomaly"

  • If we wanted to inherit ALT, then a problem "more severe than violation of class encapsulation in sequential language" could fast surface
  • Inheritance anomaly = synchronization error in "parallel OO"
  • Meseguer solves the problem by rewriting synchronisation parts in such a way that the synchronisation code actually falls out of the formulae
  • With no synchronisation, there is no inheritance anomaly either
  • Bertrand Meyer (OOSC-2 p981) points out that this is a problem
    • not because of inheritance in itself
    • but because synchronization constraints are defined separately
    • from the routines themselves
  • The occam inheritance model we define here will make possible "inheritance" of synchronization
  • since the solution is within the present occam process model
  • I see no reason why inheritance anomaly should appear
  • What I suggest below - is it really inheritance?
  • If not, what is it?
prevtopnext 

11 :: White-box and black-box reuse

Open at compile-time, closed at run-time

All included:

White-box reuse

  • "Implementation inheritance"

Black-box reuse

  • "Interface programming"
  • Standard occam 2 CHANnel interface contract

Interface inheritance

  • Also included
prevtopnext 

12 :: Start of code examples
The PLUSSING and ROLLING operators # and @

  • "PLUSSING" = textually add new code
  • by "ROLLING" it out  = generating new sources
  • and re-compile..
Basic - and with "operators" Flow etc. Processes PROTOCOL Conditional
IF

ALT 

PAR

SEQ
IF#

ALT# 

PAR# 

SEQ#
IF@

ALT@ 

PAR@ 

SEQ@
TRUE

FALSE

FALSE & SKIP

TRUE & SKIP
SKIP

STOP
CASE
CASE

ELSE
  • I have taken the term PLUSSING from Walt Disney
  • "Many of the statues then undergo a 'plussing' process, consisting of detailing the sculptures with special materials."

What we try to do here is the "plussing process" of "PLUSSING" code to an existing process

prevtopnext 

13 :: Inherit process with plug-in of blocks

PROC Buffer (CHAN OF INT in, out) PLUSSING (TRUE)

  INT data:

  WHILE TRUE

    SEQ

      in ? data

      IF

        data <> 0

          out ! data

        TRUE# -- Plussing operator on TRUE

          SEQ

            in ? data  -- Default is to read a second time..

            out ! data -- .. and send whatever we then get

:

PROC BufferChild() ROLLING Buffer

  TRUE@ -- Rolling operator on corresponding TRUE

    out ! data -- Don't read a second time

:

PROC Buffers (CHAN OF INT in, out)

  CHAN OF INT local:

  PAR

    Buffer      (in, local)

    BufferChild (local, out)

:
prevtopnext 

14 :: Inherit process with plug-in of synchronisation

PROC ALTer ([]CHAN OF INT in, out) PLUSSING (ALT)

  INT data:

  SEQ

    data := 0

    WHILE TRUE

      ALT

        ALT i = 0 FOR SIZE in

          in[i] ? data

            INT result:

            SEQ

              -- Process something

              out[i] ! result

        ALT#

          FALSE & SKIP

            SKIP

:

PROC ALTerChild (CHAN OF INT inspect.out, 

  CHAN OF BOOL inspect) ROLLING ALTer



  BOOL now:

  ALT@

    inspect ? now

      inspect.out ! data

:

CHAN OF INT  a,b,c:

CHAN OF BOOL d:

PAR

  AProducer  (..)

  ALTerChild (a,b,c,d)

  AConsumer  (..)
prevtopnext 

15 :: Inherit process with plug-in of data

PROC TIMEOUTer2 ([]CHAN OF INT in, 

  []CHAN OF INT out) PLUSSING (FALSE&SKIP)



  INT data:

  SEQ

    data := 0

    WHILE TRUE

      ALT

        ALT i = 0 FOR SIZE in

          in[i] ? data

            INT result:

            SEQ

              -- Process

              out[i] ! result

        FALSE# & SKIP# -- For sub process-class 

          SKIP

:

PROC TIMEOUTer2Child (CHAN OF INT inspect.out)

  ROLLING TIMEOUTer2 



  INITIAL

    TIMER clock: -- Assume PROC.. 

    INT time:    -- ..global scope

    SEQ

      clock ? time

      time := time PLUS 1000

  FALSE@ & SKIP@

    clock ? AFTER time

      SEQ

        inspect.out ! data

        time := time PLUS 1000

:
prevtopnext 

16 :: Inherit interface with plug-in of new protocol

PROTOCOL SetGet PLUSSING (CASE)

  CASE#

    set.NoRe; INT -- Tag=0 (input)

    get.Re        -- Tag=1 (input)

    get.End;  INT -- Tag=2 (output)

:

PROTOCOL SetGetChild ROLLING SetGet

  CASE@

    get.Re;   INT -- Tag=1 (input)  Overridden

    mask.Re;  INT -- Tag=3 (input)  New

    mask.End; INT -- Tag=4 (output) New

    kill.NoRe     -- Tag=5 (input)  New

: 
prevtopnext 

17 :: Inherit process with plug-in of new protocol handling

PROC PROTer ([]CHAN OF SetGet in, out) PLUSSING (CASE)

  INT data:

  BOOL running:

  SEQ

    data := 0

    running := TRUE

    WHILE running

      ALT i = 0 FOR SIZE in

        in[i] ? CASE#

          set.NoRe; data

            SKIP

          get.Re

            out[i] ! get.End; data

:

PROC PROTerChild ([]CHAN OF SetGetChild in) ROLLING PROTer 

  -- Only input channel redefined

  CASE@    

    INT extra:

    get.Re; extra -- Redefined

      out[i] ! get.End; data + extra

    kill.NoRe -- New

      running := FALSE

:

CHAN OF SetGetChild a:

CHAN OF SetGetChild b: -- Could also have been PROTOCOL SetGet

PAR

  AProducer   (..) 

  PROTerChild (a,b)

  AConsumer   (..) 
prevtopnext 

18 :: Inherit and inherit again: nesting

PROC PROTerChild ([]CHAN OF SetGetChild in, out) PLUSSING (CASE) ROLLING PROTer 

  -- Super is PROTer

  CASE@#    

    INT extra:

    get.Re; extra

      out[i] ! get.End; data + extra

    kill.NoRe

      running := FALSE

:

PROC PROTerChildChild() ROLLING PROTerChild

  CASE@    

    kill.NoRe

      running := BOOL (data)

:
prevtopnext 

19 :: PLUSSING # nested inside ROLLING @

  • PROTerChild designer has decided that only protocol tag
  • .. mask.Re processing may be redefined,
  • .. not get.Re code:
PROC PROTerChild ([]CHAN OF SetGetChild in, out) PLUSSING (SEQ) ROLLING PROTer 

  -- Super is PROTer

  CASE@

    INT extra: 

    get.Re; extra

      out[i] ! get.End; data + extra

    INT mask:

    mask.Re; mask -- New

      SEQ# 

        data := data BITAND mask

        out ! mask.End; data

    kill.NoRe

      running := FALSE    

:

PROC PROTerChildChild() ROLLING PROTerChild

  SEQ@    

    data := data BITOR mask 

    out ! mask.End; data

:
prevtopnext 

20 :: Start of discussion
Dynamic vs. static linking

  • Do we have dynamic or static linking?
  • OO = methods "bound late"= run-time binding
  • Named channels of occam are "connected late"
  • PLUSSING and ROLLING of code could be run-time or not
  • The" dynamic" concept of standard OO is challenged
prevtopnext 

21 :: No garbage collection (GC)

[none]
occam 2 is "compile-time" linked = no GC
[?]
  • This occam is also "compile-time" linked = no GC
  • This occam could be run-time compiled-&-linked = no GC (!?)
prevtopnext 

22 :: Unnamed blocks - worth anything?

  • The PLUSSING block has no name and no explicit interface "parameter list"
  • So, is this worth anything?
  • I don't think that the lack of an explicit name and interface hinders usefulness.. provided..
    • ..To turn it upside down
      • The suggested scheme is no excuse for bad interface descriptions
    • It would enforce interface descriptions
      • Like a folding editor needs fold crease headings
      • Does PLUSSING need a graphical tool?
prevtopnext 

23 :: Limitations of scope of this paper

  • This paper only discusses inheritance in concurrent PROCesses started with PAR
  • How about
    • PROCesses started with SEQ?
      • Occam does not have a taxonomy to differentiate between
        • "concurrent" and
        • "sequential"
        • PROC
    • FUNCTIONs?
prevtopnext 

24 :: Still no generic buffers

  • With the methodology suggested
    • I have found no way to make generic buffers or multiplexers which would handle any PROTOCOL
    • This is a basic feature not present in occam
    • I have missed it (but solved it in a way)
prevtopnext 

25 :: Dynamic loading?

Some other ideas, again:

  • Perhaps it would be possible to send off a process-class
    • as a zipped encrypted source file
    • and have the compiler compile against this "source"
  • This could perhaps be done by a Just In Time (JIT) compiler
    • perhaps making it possible to load sub third-party process-classes
    • over the net

If source files "is it", maybe this PLUSSING scheme just could work?

prevtopnext 

26 :: Explicit and implicit PLUSSING

  • Implicit PLUSSING = no explicit  PLUSSING operator in the super class
  • With the simple syntax as occam 2, such a scheme could be possible
  • There is no problem in understanding that
    • a glove
      • not a sock
        • fits onto a hand
    • even if we can
      • put a hand
        • inside a sock
    • No foot in glove!
hand_foot.gif (496 bytes)

 

  • Put under the regime of a graphical tool implicit PLUSSING could be even more viable
prevtopnext 

27 :: Closures, an inspiration

  • Parameterised block of Ruby and Smalltalk and functional programming languages
  • should perhaps be looked upon in this context
  • They are highly dynamic concepts
    • where a local block of code may be sent over as a parameter
    • and  then converted back to a block of code
    • and then run within the callee's context
  • This paper was much inspired by the concept of closures
  • Actually, an article about Ruby in Dr.Dobb's Journal started it all!
prevtopnext 

28 :: Names of child process-classes

  • With occam 2's weak module concept
  • it supports only the #USE separate compilation into a "flat namespace"
  • (better in occam 3)
  • it would be allowed to write:
PROC PROTer() ROLLING PROTer
  • Probably not much worth?
prevtopnext 

29 :: No occam CLASS

  • Barrett outlined an occam CLASS concept
  • as a means of grouping together different kind of objects like
    • CHANnels
    • variables
    • PROCesses
  • A CLASS could be used within any TYPE definition
  • No inheritance mechanism was described
  • Later, with the occam 3 draft Barrett did not include CLASS
    • unknown for what reason
  • This paper has avoided any such CLASS definition
  • by piggy-backing on occam 2's PROCess
prevtopnext 

30 :: In need of a taxonomy

  • OO and process-classes
    • Comparing apples and bananas?
  • We need a taxonomy of concurrent processes first
    • and for concurrent "OO" processes next
  • Is there one?
prevtop - 1 - 5 - 10 - 13 - 20 - 25

31 :: Conclusion:
"PLUSSING new code by ROLLING out and compile"

  • Making block structures of the
    • super process-class code or
    • super protocol description
    • pluggable
  • seems like a scheme which may work to facilitate reuse by way of inheritance
  • Since the occam/CSP process model was the basis - and the result
    • there is no process-class which may be used by several thread classes in an unsafe way
  • All instances of any process-class live within their own thread
    • with no possibility of conflicts caused by erroneous type of encapsulation
  • The result is a
    1. concurrent
    2. aliasing-error free
    3. static (compile-time built)
    4. object-oriented (-like?) language
  • so far only sketched to this point - with more answers left than questions posed