%\documentstyle[12pt]{article}
\documentstyle{article}
%\documentstyle[proc]{article}
\pagestyle{headings}

\begin{document}
\bibliographystyle{alpha}

\title{Formulations and Implications\\ of the Law of Demeter}
\author{Karl J. Lieberherr, Ian Holland\\
Northeastern University, College of Computer Science\\
Cullinane Hall, 360 Huntington Ave., Boston MA 02115}

\maketitle
%\input /fiona/csfaculty/wand/tex/time.tex 
%\centerline{Texed at \thetime\ \today}
\centerline{Copyright \copyright 1988 Karl Lieberherr}
\input common.tex

\begin{abstract}
Our publication of the Law of Demeter in IEEE Computer, June 88, and 
in the CLOS mailing list has resulted in a wealth of feedback which
has prompted us to write more explicitly about formulations
and consequences of the Law.
\end{abstract}


\section{Introduction}
The Law of Demeter has been introduced in \cite{LHLR:law-paper} for message
passing object-oriented languages.
The motivation for the Law and its intent are  given in that paper.
The purpose of this paper is to introduce several generalizations
and reformulations of the Law which preserve its spirit and make
it useful for many object-oriented languages.
We also discuss some implications of the Law in further detail.

\section{Alternatives}
There are two kinds of alternatives which are independent:
The first kind  of alternatives takes either an ``object'' point of view
or a ``type'' point of view. The ``type'' point of view has two sub categories,
called ``pure type'' and ``associated classes''.
The second kind of alternatives relates to the object-oriented language
technology for which the Law is formulated.
We distinguish between ``message passing'' and ``generic function''
terminology.
% Therefore we introduce $3*2=6$ different formulations of the Law.

\subsection{Object and type alternatives}

In the first set of alternatives we distinguish between
an ``object'' and a ``type'' version of the Law.
\subsubsection{Object alternative}

This is the conceptual version of the Law which is easy to remember and to
explain. 

\begin{formulation}
%We choose ``message passing'' (defined later) for
%the remaining choice:

Inside a method M attached to class C we can only send messages to
the following objects:
\begin{itemize}
\item
  an argument object of M, including the self object, or
\item
  an instance variable object of C
\end{itemize}
(Objects created by the method, or by methods which
it calls, and objects in global 
variables are viewed as being passed by arguments of M.)
\end{formulation}
By an argument object we mean an object passed by an argument. By an
instance variable object we mean the object stored in an instance variable.

We should strive to follow this version of the Law although it
is difficult to enforce at compile-time for 
even very restricted object-oriented languages. It requires an
analysis of aliases at compile-time.

Consider
\bv
;A = <x> B.
(defmethod (A :alias) (t)
  (send self ':set-x (send t ':x)))

;T = <x> B.
(defmethod (T :m2) (a)
  (send (send a ':x) ':m3))
\end{verbatim}

Is this in good style? It depends on the context. 

The following is o.k.
\bv
(send iA ':alias iT)
(send iT ':m2 iA)
\end{verbatim}

But \verb?(send iT ':m2 iA)? by itself violates the Law.
Maybe a better name for the ``object'' version would be ``run-time'' version.
Theoretical results related to the complexity of checking
the object version of the Law are given in \cite{oppen:rec-data-80}.

The formulation of the Law has to be analyzed carefully. For example,
consider a method M attached to class C. What is the difference between:
an instance variable value of C and an immediate part of self?
Which formulation should we use in the formulations of the Law?
We have decided to use the formulation using instance variables.
The motivation is as follows: Consider the method

\bv
(defmethod (construction :walk)()
  (loop for e in (send self ':child)
    do (send e ':walk)))
\end{verbatim}

Here we send a message to a subpart of self, but we don't send a message
to an instance variable object of construction. Therefore this method
violates the Law. Why is this method considered dangerous? This method
which is attached to construction makes assumptions about the
subclasses of construction. It assumes that there is a method
{\sf child} which returns a list and each element in that list
should be responsive to a method {\sf walk}.
This should only be done if it is
well justified and should be very well documented.
The above method can be written in good style as follows:
\bv
(defmethod (construction :walk)() 
  (loop for e in (send self ':child) 
    do (send self ':aux-walk e))) 

(defmethod (construction :aux-walk) (part)
  (send part ':walk))
\end{verbatim} 

\subsubsection{Type alternatives}
The type version of the Law is compile-time enforceable for useful subsets
of the underlying object-oriented languages. The type version can be
stated in terms of classes which is less stringent and in terms
of associated classes which is more restrictive and the most useful
formulation. 

\begin{itemize}
\item pure type
\begin{formulation}
%We choose ``generic function'' (defined later) for
%the remaining choice.

In all function calls inside a method M all method selection arguments
must belong to one of the following classes:
\begin{itemize}
\item
argument classes of M
\item
instance variable classes of method selection argument classes of M.
\end{itemize}
A {\em method selection argument} is an argument which is used
for identifying the applicable methods. 
\end{formulation}

Method selection arguments
are discussed further below.
This pure type formulation of the Law is easy to remember and
does not require Demeter specific terminology. However, it is much less
stringent than the object version and allows many more methods
to be in ``good style'' than the object version. The problem comes from
inheritance, e.g. it allows also instances of proper subclasses
of the argument classes to be passed in method selection
arguments of generic function calls. This reduces modularity.

The formulation 
`` ... all method selection arguments must belong to one ...''
is important. We cannot replace it by
`` ... all method selection arguments must be instances of one ...''
because of abstract classes.

\item associated classes
\begin{formulation}
%We choose ``generic function'' (defined later) for
%the remaining choice.

In all function calls inside a method M all 
method selection arguments must be instances of a class associated
with one of the following classes:
\begin{itemize}
\item
argument classes of M
\item
instance variable classes of method selection argument classes of M.
\end{itemize}
\end{formulation}
This version of the Law is the original version and comes close
to the conceptually ideal object version while being compile-time
checkable for useful classes of object-oriented programs.
\end{itemize}

\subsection{Message passing and generic function alternatives}

In the second set of independent alternatives we
discuss message passing versus generic function call formulations.

\subsubsection{Message passing alternative}
\begin{formulation}
%We choose ``type(associated classes)'' for
%the remaining choice.

In any method M attached to class C send only messages to 
instances of a class associated with one of the following
classes:
\begin{itemize}
\item argument classes of M (which includes C)
\item the instance variable classes of C.
\end{itemize}
\end{formulation}
\subsubsection{Generic function alternative}

In the message passing framework we think of a method as attached to one
class. In the generic function generalization it is natural to think
of methods as being attached to several classes.

The idea of \oop\ is that we can attach functionality to classes.
These routines (functions or procedures,
which are called methods
in several object-oriented
systems) are an integral
part of the class and can access the parts of an object of that class 
in an easier way than other functions. These functions are part of the
semantics of the class.  

Attaching a routine to a class is like giving the routine
the right to access, at a primitive level, the instance variables.  One
could achieve the same result by attaching the routine to any other class,
but accessing the required information would be less convenient.
Attaching a routine to a class in some sense reveals the 
details of the class to the function.  
Our law just re-affirms this notion and restricts the extent of the
revealed details.

In message passing languages where a method is
attached only to one class, we restrict
the message sending essentially to instance variables types of that class.
The arguments to the method act in support of the method BUT since
the method is not attached to the classes of the arguments, the method
is not an integral part of the semantics of those argument classes.
Therefore
the function had no right to access the details of the arguments 
{\em at a primitive level}.
There is a real difference between the first argument to which
a message is sent 
and the remaining arguments which act as support information.

With generic function call languages which allow several arguments
to select a method (e.g. CLOS) this is different.
There is potentially a case analysis of all
argument types to decide which method is being invoked;i.e., the function
is attached to many classes.  If a function is attached to many classes
then it is a part of the semantics of each {\em and} should be allowed 
to send messages
to instance variable types of all the classes to which it is attached.   
Any remaining
arguments are treated in the same way as the second and following
arguments in message passing languages.
We must still distinguish between the two roles played by the arguments:
the method selection role and the supporting role.

Therefore the Law for generic function call languages with several
method selection arguments, allows the programmer of
a method to look directly at the instance variables of several classes.
We have to compensate for this by restricting more than the first
argument in a generic function call:
We require that
all function calls inside a method M must have a restricted set
of objects in all their method selection arguments.

An important idea behind the Law
is that the user has only to think about the classes
of the method selection arguments and the classes of the
immediate subparts of those argument classes when reading a method.
Consider the following example:
\bv
METHOD f (a : A, b : B) : C.

... (g a (h b)) ...
\end{verbatim}
Let's assume that g has two method selection arguments. The Law requires
that the return type of h is restricted. The reason is that we only
want to think about certain classes when figuring out which method
h will activate. 

Furthermore, we want to restrict the effect of class changes.
Assume that the return type of h is Q which is a subsubpart type of A.
If Q changes, we might have to modify f since now a completely
different method might be selected.
If a class changes, we only want to change methods attached to that class.
The Law achieves this by restricting the 
types of the method selection arguments.

\begin{formulation}
%We choose ``type(associated classes)'' for
%the remaining choice.

In all function calls inside a method M all method selection arguments
must be
instances of classes which
are associated with one of the following classes
\begin{itemize}
\item argument classes of M 
\item instance variable classes of method selection argument classes of M.
\end{itemize}
          (Objects created by the method, or by methods which it calls,
          and objects in global
          variables are considered as arguments.
          A method selection argument is an argument which is used
          for identifying the applicable methods.)
\end{formulation}
The message passing version and the generic function call 
version are closely related: Only the first argument is a method
selection argument in the message passing version.


\section{Overloading and dynamic method selection}

Dynamic method selection with respect to an argument of a generic
function means that the arguments class is used at run-time to
determine a method to call.

Let o1 (o2) be of type T1 (T2), where T1 (T2) is a class with T1'=\{T1\}
(T2'=\{T2\}). This implies that T1 and T2 are construction, repetition or
terminal classes. In this case, (send o1 ':m) and (send o2 ':m)
can be compiled into the call of two specific methods. There is no need
for dynamic method selection for the types of o1 and o2 at run-time.
We say that message name m is overloaded. We can determine at compile-time
which method should be called.

Now, assume that T1 is a class with T1' different from 
\{T1\}, i.e., T1 is an alternation
class with more than one alternative. In this case we need dynamic method
selection
at run-time to determine which method (send o1 ':m)
should execute.

Both for overloading and dynamic method selection several
arguments might be used to determine the effective method.
These possibilities are orthogonal to each other. How do they influence
the form of the Law of Demeter? It is the dynamic method selection
which has an influence on the Law.
The overloaded functions per se don't have special priviledges
regarding access to the instance variables; they are not
``attached'' to the classes of the arguments which influence
the overloading.

E.g., in C++, we have overloading
using several arguments but dynamic method selection
only for the first argument.
Therefore, the C++ formulation uses the message passing
formulation.

\paragraph{A brief comparison between CLOS and C++.}
There is certainly a huge difference between CLOS and
C++ but with respect to the Law, CLOS and C++ are not that far apart:

{\em In C++ also all arguments are used to determine which method (called 
a member function) to execute.}

The difference is that in C++ the argument types (after the first) are 
used to determine the member function at compile-time. I.e., C++ uses
static method selection for the second and following arguments.  
The first argument in a method of a derived class
is used for dynamic method selection.

In other words:
CLOS supports dynamic method selection on all required arguments, while
C++ supports dynamic method selection only on the first argument.
Both C++ and CLOS support function overloading on all required arguments.

For C++ the message passing formulation of the Law is appropriate.
We view the compile-time method selection of C++ due to overloading
as syntactic sugar. We could always rename the methods by prefixing
their names with argument types to avoid the need of overloading.
But CLOS is inherently more powerful: it does true dynamic method
selection 
on all the method selection arguments.
Therefore we need for CLOS the generalization of the Law as proposed
in the section on ``Formulation for existing languages''..


\section{The Law in mixed paradigm languages}

In languages which support both the action-oriented and the object-oriented
paradigm we have the coexistence of function or procedure calls with
message sendings or generic function calls. We can view a regular
function or procedure as a degenerate generic function with 0 method
selection arguments. Therefore the Law of Demeter does not restrict
the regular function or procedure calls inside a method.

Outside methods we disallow generic function calls, i.e., a regular
function or procedure may not contain generic function calls.

For mixed paradigm languages it makes sense to distinguish between 
types and classes. The types include:
\begin{itemize}
\item
the types of the action-oriented base language
such as character, integer, real and other types
\item the classes of the object-oriented extension.
\end{itemize}

In CLOS many but not all Common Lisp types are classes and all
classes are types.

\section{Nesting of generic function calls}

The Law of Demeter has implications for the nesting of function
calls. To discuss those implications, we classify  functions as follows:

\begin{definition}
\begin{itemize}
\item
A accessor function returns an object which exists before the
function was called.
\item
A constructor function returns an object which did not exist before
the function was called.
\end{itemize}
\end{definition}

The Law allows the nesting of constructor functions, as well as
the nesting of non-generic functions. 
A generic function does not necessarily have to contain
an explicit 'make-instance' call (or its equivalent) to cause the
creation of a new object.  If the generic function has within it
a call to a function which returns {\em a newly created object} then this
too is considered a creation of an object within the generic function.

However, the Law prohibits functional composition of accessor functions
which don't return instance variable objects.
Indeed, the Law of Demeter,
prohibits functional composition of list processing functions.
For example, the Law of Demeter 
says that the following code is in "poor" style:
(We use the CLOS notation in this section.)

\bv
; Number-List ~ {Number}.
        (defmethod third ((x Number-List))
          (car (cdr (cdr x))))
\end{verbatim}
We view this in bad style for two reasons: Apparently, we know that
the list has at least three elements. Therefore we should define it
as a construction class:
\bv
; New = <p1>, <p2>, <third> Number <rest> Number-List.
\end{verbatim}
Then selecting the third element is much easier (more intuitive and
less error prone).

The second reason is that it is not good to ``dig'' into structures.
We choose another example to demonstrate this point:

\bv
;P0 = <p1> P1.
;P1 = <p2> P2.
;P2 = <p3> P3.
(defmethod get-p3 ((x P0))
  (p3 (p2 (p1 x))))
\end{verbatim}
A better solution is:
\bv
(defmethod get-p3 ((x P0))
  (get-p3 (p1 x))
(defmethod get-p3 ((x P1))
  (p3 (p2 x)))
\end{verbatim}
If we update class {\sf P1} (say instead of p2 we have two other instance
variables), we have to modify in the first case
the triply nested method {\sf get-p3}
attached to class {\sf P0} (although
{\sf P0} did not change). 
In the second case, we only have to update the method attached to {\sf P1}.

In the Number-List example we could not make the same point
since cdr returns again an Number-List. We view this as a coincidence.
The compile-time checkable version of the Law of Demeter allows
the  nesting of accessor functions, if their return type is not
a ``new'' type, that is if it is an instance variable or an argument
type.

We give two more examples which use nesting of constructor functions.
The following nesting is in good style:
\bv
        (defmethod good-style ((x float) (y float)) 
          (+ (sqrt (- x y)) y))
\end{verbatim}

since the functions +, -, and sqrt are all constructor functions.
The result of applying the built-in generic function - is an argument
to the sqrt generic function, as is the result of sqrt to +.
The result of applying - and sqrt
is generated within the function body itself.

In other words,
the application of the '-' to the x and y causes the creation of a new
instance of the float class which is initialized to a value representing
'x - y'. So calling '-' is just the same as creating a new object  and
giving the instance variables of that object some initial values depending
on the arguments and some procedural processing.  Thus the argument to the
sqrt function is again valid.

        As a less trivial example, consider the following. In Unix, the
pipe construct has the semantics of functional composition. Thus, to
format a troff document and send it to the line printer the following
command line is used:

\bv
troff <switches> <filename> | lpr -P<printer>
\end{verbatim}
Using functional composition in Lisp/CLOS, we have:
\bv
(defmethod output-document 
    ((switches string) 
     (filename pathname) 
     (printer string))
  (lpr printer (troff switches filename)))
(defmethod lpr 
    ((printer string) 
     (document stream))
  <<code to send document to the printer>> )

(defmethod troff 
  ((switches string) 
   (filename pathname))
  <<code to do troff, 
    might be in Lisp or a call to Unix>>)
\end{verbatim}

The method output-document is in good style since troff is a constructor
function which returns a new stream object.

%       The functional programming style is a useful and powerful one,
%though, as with all programming styles, it has its limitations. One of
%the advantages of CLOS is that it makes a combination of functional
%and object-oriented styles possible, allowing side effect producing
%operations to be limited in extent, which, in turn, makes proofs of
%correctness easier. By eliminating functional composition for generic
%functions, the Law of Demeter puts unnecessary restrictions on the
%programmer.
It is important to note that we haven't ``thrown out the baby with the
bathwater'' with this interpretation of ``object creation''.  
A generic function has the authority to make decisions and operate
in ways which are DEPENDENT on the 'valid' method selection objects
(argument objects and slot values of method selection arguments) and their
types, but IS NOT ALLOWED to be dependent on the sub-parts of those objects.
The deep structures of the objects are hidden from the generic function.
This is a real and
important restriction on the programmer.
\section{Interface of a function}

Let's assume we have a (non-generic) function 
{\sf op-res} which takes as 
first argument an operator of type

\bv
  Operator : AddSym | MulSym.
\end{verbatim}

plus two other arguments which are numbers.
Function {\sf op-res} returns the value of applying the operator to the
two numbers.  We have provided this function to our users and 
given them the interface for the function.

Some time later, we decide to make the function generic in its first
argument. Should we inform the users about this change? (By the way,
in CLOS we are forced to make the function generic in all three arguments since
all three are required.) The users might have used this function {\sf op-res}
inside other methods and if we make now the first argument generic
the user's code might suddenly violate the Law. Why should the user
know about the fact that the first argument is generic now? The reason
is extensibility! The user has now an easy way to extend the {\sf op-res}
function to other types and that is very useful knowledge for the
future modification of the user's program. 

When the function is generic in its first argument, its implementation must
look like: (pardon the new Flavors notation; this discussion is relevant
not only to CLOS but also to generic function
systems with only one dynamic method-selection argument (such as new Flavors)):
\bv
  (defmethod (AddSym op-res) (e1 e2) ... )
  (defmethod (MulSym op-res) (e1 e2) ... )
\end{verbatim}
If the user wants to extend the domain of {\sf op-res}, he/she just adds
another method. If the function is not generic, this won't work.

{\em Therefore, we view the number of method selection arguments of a function
as part of the interface of that function along with the typing information
and a formal or informal specification.}

HERE WE CLASH WITH THE VIEW OF THE CLOS INVENTORS. They view the syntactic
non-distinction as a contribution of CLOS, while we view the fact that
we can have several method selection arguments as one (among many) contributions
of CLOS. 

What about the violation of the Law when we go from non-generic to
generic? Lets consider the following classes:
\bv
  A = <x> Compound.
  Compound = "(" <op> Operator <args> List(PrefixExp) ")".
\end{verbatim}
Consider the method:
\bv
  (defmethod (A bad-style) (e1 e2) (op-res (op x) e1 e2))
\end{verbatim}
which is identical before and after the transition from non-generic to generic.

Why is method "bad-style" in bad-style after the transition? 
Since it is attached to class {\sf A} AND 
since it contains a dependency on the subparts of the {\sf Compound} class.
If {\sf Compound} changes to

\bv
  Compound = "(" <additive-op> Operator <args> List(PrefixExp) ")".
\end{verbatim}

we have to modify the semantics of class {\sf A}, 
although class {\sf A} did not change:

\bv
  (defmethod (A :bad-style) (e1 e2) (op-res (additive-op x) e1 e2))
\end{verbatim}

This violates the principle of modularity.
Why is "bad-style" in good-style before the transition? 
It is the prerogative of the Law that
it can accept certain constructs which are in bad shape. We want to
have a Law without exceptions which is easy to remember and to follow.
We don't want to restrict non generic function  calls since 
we don't want to upset the Lisp or C programmers. 

\section{Formulations for existing languages}

We give the formulation of some of the Law of Demeter 
versions in a few object-oriented languages.
Each formulation adapts the Law to the terminology of the particular language.
\begin{itemize}
\item
Smalltalk-80:
object/ type,
message passing.

\bv
----- LAW OF DEMETER (Smalltalk-80, object version) ----
In all message expressions inside a method M 
the receiver must be one of the following objects:
  - an argument object of M including objects in 
      pseudo variables "self" and "super" or
  - an instance variable object of the class to which M
      is attached.
(Objects created by the method, or by methods which it calls,
and objects in global 
variables are viewed as being passed by arguments.)
--------------------------------------------------------
\end{verbatim}

\item
C++:
type, 
message passing.

C++ allows overloading of function names
with respect to several arguments.
But run-time implicit case analysis is done only with the first argument.
\bv
----- LAW OF DEMETER (C++, type version) -------------
Every member or friend function M of a 
class C is only allowed to call member
or friend functions of the following classes:
  - The argument classes of M (including C),
  - The data member classes of C,
  - The classes of objects created by M (directly, 
      by calling a constructor function or indirectly, 
      by calling a function which will call 
      eventually a constructor function)
  - The classes of global objects.
----------------------------------------------------------
\end{verbatim}

\item
CLOS:
object/ type,
generic function.

\bv
----- LAW OF DEMETER (CLOS, object version) -------------
All function calls inside a method M must use only the 
following objects as method selection arguments:
- M's argument objects or
- slot values of method selection argument classes of M.
(Objects created by the method, or by functions which
it calls, and objects in global variables are viewed as 
being passed by arguments.
A method selection argument is an argument which is used
for identifying the applicable methods.)
----------------------------------------------------------
\end{verbatim}
Note that this formulation implies that the only legal use of
function slot-value is on method selection arguments.

\bv
----- LAW OF DEMETER (CLOS, pure type version) -----------
In all function calls inside a method M all method 
selection argument objects must belong to one of the 
following classes:
  - argument classes of M
  - slot classes of method selection argument classes of M.
----------------------------------------------------------
\end{verbatim}
\item
Old Flavors:
object/ type,
message passing.
\bv
----- LAW OF DEMETER (Old Flavors, object version) -----
In any method M attached to class C send only messages 
to the following objects:
  - M's argument objects
  - the instance variable objects of C.
(Objects created by the method, or by methods or functions
which it calls, and objects in global 
variables are considered as arguments of M.)
--------------------------------------------------------
\end{verbatim}
\bv
----- LAW OF DEMETER (Old Flavors, associated classes) ---
In any method M attached to class C send only messages
to instances of classes associated with the following classes
  - argument classes of M
  - instance variable classes of C.
(Objects created by the method, or by methods or functions
which it calls, and objects in global
variables are considered as arguments of M.)
----------------------------------------------------------
\end{verbatim}


\item
New Flavors:
object/ type,
generic function.

\item
Eiffel:
object/ type,
generic function.

\bv
----- LAW OF DEMETER (Eiffel, object version) -----------
In all calls of routines inside a routine M 
the entity object must be one of the following objects:
  - an argument object of M
  - an attribute object of the class in which M is defined.
---------------------------------------------------------
\end{verbatim}
\end{itemize}

These formulations can be altered in the following ways:
\begin{itemize}
\item Use nested universal quantifiers. For all classes C, and for all methods M attached to C, ...

\item Use ``let'' phrases. Let C be any class, let M be any method attached to C,
let E be any message expression ...
\end{itemize}
\section{Questions and answers}

\begin{itemize}
\item
Question: The Law violates information hiding since to follow the Law you
  have to know the "instance variable objects". You are not supposed
  to know whether a value returned by a message is an instance variable
  object or a value computed from instance variables.

Answer: The concept of "instance variable object" used in the Law 
  is a semantic one. An instance variable object is either stored
  as immediate subpart of the object or computed as a new object
  and returned by some message.
  
Remark: it is possible that some methods of a message return a
newly created object and others a new object.

\item
Question: How is the Law related to information hiding?
Answer: The Law selectively hides the protocol of a class in certain classes.
  Consider the following implication of the Law: (we need two definitions first)

  Definition: Class B is called a preferred supplier of class A if 
  B is a part class of A or
  B has a method which uses an argument of class A or
  A inherits from B or
  B creates an object of class A or
  B has a method which uses a global variable which is of class A.
  Every class is a preferred supplier of itself.

  Definition: The protocol of a class is the set of messages the class
  knows about.

  Implication of Law of Demeter: (selective information hiding)
  The protocol of a class C can only be used in methods of preferred clients
  of C.

\item
Question: How does the Law limit the effects of modifications?
Answer:

  Fact: If the protocol of class B changes 
  at most the preferred clients of class B need to be modified.

  Fact: If the immediate parts of class A change,
  at most the methods of A and its subclasses need to be modified.

  Fact: If the immediate parts of class A change, and the strong Law
  is followed, 
  at most the methods of A need to be modified.

  For a compiled system such as C++: Fact: If the Law is followed and 
  if class B is recompiled then at most the preferred
  clients of B need to be recompiled.


\item
Question: What is "associated" about?
Answer: Use the following more permissive type version of the Law:

\bv
  For all classes C, and for all methods M 
  attached to C, all
  objects to which M sends a message must belong
  to the following classes:

  The argument classes of M (including C).
  The instance variable classes of C.
  Classes of objects created by M, 
    or by messages which M sends.
  Classes of global objects.
\end{verbatim}

\item
Question: When is it justified to break the Law.
Answer: When you have a stable class organization, it makes sense to use
  the protocol of a class in other classes than preferred 
  client classes. These uses
  have to be well documented.

  Example:

\bv
  (defmethod (construction :walk) ()
    (loop for e in (send self ':child) do
      (send e ':walk)))
\end{verbatim}
  We assume that class construction does not have any instance variables,
  that the e's are not newly created objects and that there are no globals.
  Since :walk does not have any arguments, and since e can belong
  to a class different than construction, we have a violation of the Law.

  We can conform to the Law, however, by:

\bv
  (defmethod (construction :walk) ()
    (loop for e in (send self ':child) do
      (send self ':walk-auxiliary e)))

  (defmethod (construction :walk-auxiliary) ; could be inline
      (e :type universal)
    (send e ':walk))
\end{verbatim}

  Here we have effectively documented the dependency of method walk
  on class universal.

\item
Question: In C++ it is possible to explicitly call member functions of
other classes. How does this affect the Law?

\begin{example}
\bv
typedef void* ent;
class slist {
  private:
    slink* last;
  public:
    int insert(ent a); 
    int append(ent a);
    ent get();
    void clear();
    slist();
    slist(ent a);
    ~slist();
};
struct name {
  char* string;
};
struct nlist : slist {
  void insert(name* a) {slist::insert(a);}
  void append(name* a) {slist::append(a);}
  name* get()          {return (name*)slist::get();}
  nlist()              {}
  nlist(name* a) : (a) {}
// from page 207 Stroustrup
};
\end{verbatim}

Here we call member function insert of slist. This is a special feature
of C++. The Law of Demeter does not allow us 


\end{example}


\end{itemize}

\section{Clients, suppliers and dependencies}

Precondition: compile-time enforcing.

1. strong typing with explicit type declarations (C++) 

2. strong typing with type hierarchy and signatures of methods 
   described by Demeter type notation.
   The type of every statement or expression can be inferred at compile-time
   through type inferencing. (Lisp Flavors, Smalltalk)

Goal of Law of Demeter: organize and reduce dependencies
between classes.

Approximations: Each method can only send messages to a ``limited'' set
of objects.

Each method is ``dependent'' on a ``limited'' set of objects.
(organize dependencies)

Each method ``collaborates'' with a limited set of objects.
(organize collaborations)


We adopt the client/supplier terminology from \cite{meyer:book-88}.

\begin{definition}
The protocol of a class C is the set of messages that can be sent
to C and its instances.
\end{definition}

\begin{definition}
Method M is a client of class B and B is a supplier of method M,
if an object of class B is sent a message in method M.

or if an instance of a class in associated(B) is sent a message in method M.

?? not precise enough ??
note: more restrictive than Meyers. Passing and never sending a message
does not count for client.
\end{definition}

Next we define a special kind of clients and suppliers.

\begin{definition}
Class B is called a preferred supplier of method M (attached to class C) if
class B is a supplier of method M and one of the following conditions holds:
  B is an instance variable class of C or
    B is an argument class of M, including C or

do not need: C inherits from B or

        B is a class of objects created in M
          B is a class of a global variable used in M.

%Include: have to send a message??
\end{definition}

\begin{definition}
Method M is called a preferred client of B if and only if
class B is a preferred supplier of method M.
\end{definition}

\begin{example}
In the following 4 examples,
class B is a preferred supplier of method M and M is a preferred client of B.

\bv
METHOD M (<self> Y <s> B ...)

// A = <s> B ...
METHOD M (<self> A ...)

METHOD M (<self> A ...)
  { ... f(s) ... }

// s is of type B, global to M
METHOD M (<self> A ...)
  { ... f(s) ... }
\end{verbatim}

\end{example}


\begin{fact}
Class B is a preferred supplier of method M attached to B.
Method M attached to class B is a preferred client of class B.
\end{fact}

Law of Demeter (type version):
In all classes C and in all methods M attached to C, use only the protocol of
the preferred suppliers of M.

\begin{fact}
Reformulation 1 of Law of Demeter (selective information hiding):
Only a preferred client method M of class B is allowed 
to use the protocol of class B.
\end{fact}

\begin{fact}
Reformulation 2 of Law of Demeter (selective information hiding):
The protocol of a class B can only be used in preferred clients of B.
\end{fact}

\begin{definition}
A method M is dependent on class C, if M uses a method attached to C.

What does uses mean? Need compile-time checking.
\end{definition}


\begin{fact}
Reformulation 3 of Law of Demeter (selective information hiding):
Only a preferred client method M of class B is allowed 
to be dependent on class B.
\end{fact}


This can be viewed as an equivalent formulation of the type version
of the Law which does not use associated. 

%\begin{definition}
%Class A is dependent on class B if A uses B's protocol.
%\end{definition}

\begin{fact}
Method M is dependent on B if and only if M is a client of B.

Depends on definition of dependent.
\end{fact}

%If A is a client of B then A is not necessarily dependent on B since
%no method of A might use A's protocol. (An object of type A might
%be passed as second argument and never sent a message.)

%The Law reduces the dependency between classes since only a preferred
%client class of a class B is allowed to use the protocol of B.
%Using the dependency concept, we can give the following equivalent
%formulation of the Law:

%\begin{fact}
%Only a preferred client class of B is allowed to be dependent
%on B.
%\end{fact}

%Yet another definition:
%\begin{fact}
%In any method M attached to class C use only the protocol
%of classes of which C is a preferred client.
%\end{fact}

Yet another reformulation:
\begin{fact}
In any method M use only the protocol
of preferred suppliers of M.
\end{fact}

The current definition of preferred client and supplier does not
deal with associated classes.
%Refined definition:
%
%\begin{definition}
%A is a preferred client of class B if B sends a message to an instance 
%The preferred clients A of class B are the classes which
%send a message
%to an instance of the classes associated with the following classes:
%  instance variable classes of B or
%  argument classes of methods of B or
%  classes from which B inherits or
%  classes which create
%
%A inherits from B or
%       B creates an object of class A or
%         B has a method which uses a global variable which is of class A.
%           Every class is a preferred client and a 
%           preferred supplier of itself.
%\end{definition}

\section{Black boxes}

A black box is a message which takes inputs and returns outputs.

\bv
;;; C = .
(defmethod (C :m) (p :type Complex)
  (send (send p ':imaginary-part) ':square))
\end{verbatim}

In this example, imaginary-part is a message which takes as input
a Complex number and returns as output the imaginary part which
belongs to class Real. This
is a violation of the Law since class C is not allowed to
use the protocol of class Real. Observe that C is not a preferred
client of Real. C is a preferred client of class Complex only.

Violations of the Law are justified as long as the following
conditions are satisfied:

\begin{itemize}
\item
Classes which are stable can expose their structure. In the above example,
class Complex has been studied for centuries and the imaginary
part of a complex number is a stable concept.

\item
The dependencies are clearly documented. In the above example, we have to
document that
Class C depends on Real since C uses the protocol of Real.

\item
We are willing to keep messages upward compatible.
Consider:
\bv
(defmethod (C :M) (p)
  (send (send p ':F1) ':F2 self))
\end{verbatim}
If we are willing to keep F1 so that it will always return an object which
responds to F2.
\item
Efficiency: To gain efficiency we might want to violate the Law.
Consider the problem of multiplying a matrix by a vector.

Vector(n) = <elements> Array(n, Number).
Matrix(m,n) = <elements> List(Vector).


\end{itemize}

If we rewrite the above example in good style we get:


\bv
;;; C = .
(defmethod (C :m) (p :type Complex)
  (send p ':square-imaginary-part))

;;; Complex = <real-part> Real <imaginary-part> Real.
(defmethod (Complex ':square-imaginary-part)()
  (send (send self imaginary-part) ':square)
\end{verbatim}

or

\bv
;;; C = .
(defmethod (C :m) (p :type Complex)
  (send self ':square-argument (send p ':imaginary-part))

(defmethod (C :square-argument) (p-real :type Real)
  (send p-real ':square))
\end{verbatim}

Both solutions are not satisfactory: The first one makes class Complex
too ``heavy'' in that it defines an unnatural method for the class.
The second one makes class C too ``heavy''.
Therefore it is justified to violate the Law and expose the structure
of class Complex.

It is important to notice that stable classes are more the exception
than the rule. Each application needs its own classes and these classes
tend to evolve as the application evolves. Therefore the Law
of Demeter is important.

Each black box introduces a constraint for the programmer in that 
the black boxes have to be maintained in an upward compatible way.
With many black boxes around, the programmer gets forced to
write the software in inappropriate ways when changes have
to be made. With a minimal number of black boxes, the programmer
has much more freedom to keep the software optimally tuned to the
current needs of the application.

\begin{center}
{\bf{Acknowledgements}
}
\end{center}

Members of the CLOS community (Daniel Bobrow, Richard Gabriel,
Jim Kempf, Alan Snyder, Gregor Kiczales, Lanning etc.) have participated
in the debate and formulation of
the CLOS version of the Law and prompted
us to write this paper.
Jim Kempf did contribute two examples.

Carl Woolf was initially proposing to view the object version
of the Law as the one to follow
conceptually and he did help us in wording the formulations.

Arthur Riel provided moral support and helped us with the formulations
and implications of the Law.
\bibliography{/fiona/csfaculty/lieber/papers/new-obj/bibliography/biblio}
\tableofcontents

\end{document}

