[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Objects, processes, and encapsulation



Hello Tom

Thought I'd add a footnote to your point about classic OOP weak 
encapsulation. This also relates to Meyer's criticism of "active" 
objects, raised by Marcel, who, like you, was sorely missed at CPA'01.

Recap
If I understood correctly, your point was that a classic object's state 
is vulnerable to a reflexive invocation (call back). Your example 
(#2.2.1) merged this problem with exposing the possibility of two objects 
each containing the other. One of your slides (from memory) captured just 
the call-back problem...

  Object1 has a variable 'x' and an interface ("public methods") 'setx', 
'getx',
  and 'foo'. Object2 does setx(42); foo(...); y = getx. You hope y = 42 
BUT foo 
  called a method 'bar' in Object3, which then (reflexively) called 
setx(53).

I ran this past a local s/w eng enthusiast and found him quite familiar 
with the problem, unfamiliar with occam, but keen on some agent model as 
a solution. Interestingly, he saw agents as a formalism only, and was 
quite happy they be implemented as processes. This seems to relate to 
things like 'skeletons' and "higher order' programming.


Meyer and active objects
In his door-stop tome, Meyer argues that you don't want an object to do 
just one thing, and illustrates the point with a printer object that can 
respond to a number of different messages. It has its own agenda but will 
do things for others as well. (I could think of better examples.)
  He obviously hasn't considered an interface comprising channels with an 
ALT behind them. We can easily build his printer. Doing your own thing, 
while still providing services, ain't a problem.
  Endowing occam with multiple inheritance (his other problem with active 
objects) is perhaps a bit harder. 


Why occam processes are still vulnerable
Unless I'm missing something, occam is only really protected by the 
semantics of ALT, which allows our active object to do just one thing at 
a time. So, Process2 sends a message to Process1 on channel foo, which 
causes a message to be sent to Process3 on channel bar, which in turn 
causes '53' to be sent back to Process1 on channel setx...which just 
might be received before the request on channel getx. Whoops.
  Adrian alerted us to the fact that ALT, as specified, introduces 
non-determinism. You offer it messages on two distinct channels, on two 
occasions, and it might trace differently each time. As implemented, it 
has a kind of priority, which resolves this.
  occam is a bit at odds with CSP, which either lets the process choose 
(non-deterministic (internal) choice), or the environment choose 
(external choice). Poor old ALT sometimes has to contend with an 
environment that refuses to choose, perhaps because it is composed of 
multiple interleaving processes.
  With CPA, we seem to be worse off. At least the classic objects would 
give the same 'y' value each time.


Better understanding the problem
Your illustration exposes another weakness in classic OOP - the patent 
failure to USE encapsulation. So-called "access methods" (get<> and 
set<>) defeat the aim, which is to hierarchically reduce the degree to 
which program steps can interact. What's the point of containing 'x' in 
some object 'y' and then directly manipulating x anyway. The whole idea 
is that you act only then on 'y'. Objects then just muddy the water.
  Wish I had a quid for each time I'd encountered this kind of crap. 
Sadly, I've seen the same on teaching material. (We won the Battle of 
Britain by forcing the best pilots to teach. The same principle used to 
apply in the old Guilds. It's a shame we don't apply it to programming.)

Cause of problem and a solution
The underlying problem is that, while we've laid out our channels in 
specifying our interface, we've said nothing about how they may be used. 
(Much the same may be said of methods in a classic object interface.) 
There's nothing preventing reflexive interaction.
  The server/client design rule prohibits exactly this kind of unhealthy 
behaviour. It infers how channels are used - the relation between 
objects, rather than their properties as individuals. Furthermore, the 
notion of 'service' allows the capture of precisely the kind of 
heterogeneous behaviour Meyer describes.
  It still gives protection when you allow pre-emptive service.
  Nothing can guarantee good design, but this goes as far, I think, as 
you can go to encourage it. It forces you to express relations, within 
simple intuitive abstraction, and allows compile-time authority over 
composition.


When I proposed integrating the CS design rule into a programming 
language at CPA '01, the only objection was that it was too restrictive 
(and perhaps too prescriptive). Maybe. Then maybe not. I think mostly 
such concern comes from confusion with data flow. Only cyclic _services_ 
are banned. Cyclic data flow presents no problem.


Sorry this is a bit heavy. It was a good conference. My head is still 
spinning.
  A good strong dose of endless, boring, pointless, departmental meetings 
will soon suck out all the joy again...

Ian
PS Loved the paper. Very provocative. Still find mobile 
processes/channels too complex an abstraction, but agree we need 
ADTs...somehow. We should meet and talk sometime.


Dr. Ian Robert East         School of Computing and Mathematical Sciences
ireast@xxxxxxxxxxxxx                            Oxford Brookes University
(44) 1865 483635                                           Oxford OX3 0BP

Consultation hours for 2001/2002 Term 1
Mon 09.00..13.00