SlideShare a Scribd company logo
FROM MECHANISM TO METHOD 
Substitutability 
IF I WERE TO SAY that C++ is a language with a large number 
of features, it is unlikely that I would be in much danger of 
igniting a flame war. Where fact gives way to opinion—and 
sometimes to the holiest and most heated of wars—is in the 
recommendation of how to work with these features. What is their 
purpose? What concepts do they express? In short, what methods 
give sense to the mechanisms, elevating the programmer's view 
of the language from a shopping list of features to recipes that 
marshal features into designs? Sure, programmers need knowledge 
of syntax and semantics to make any headway with the language, 
but this learning curve quickly levels out to a plateau with the sheer 
face of design rising above it. 
Idioms offer a steady and complementary companion route— 
patterns that capture an understanding of problem and solution 
married together at the level of the language.1,2 Idioms establish 
a vocabulary for communicating and formulating design, where 
"design is the activity of aligning the structure of the application 
analysis with the available structures of the solution domain."3 
On the other hand, while practices based on accepted wisdom 
generate comfortable habits that generally simplify day-to-day de-velopment, 
this is no reason to be complacent. Occasionally re-visiting 
old maxims can reveal other useful insights that were 
hiding in the shadows.4 
IS-A IS NOT ENOUGH Attractive as the idea first seems, the Eng-lish 
language does not offer consistently useful guidance for the 
analysis of problems and the statement of software structure. 
Excitement about nouns as objects and verbs as methods often 
wears off when the nouning of verbs and verbing of nouns is rec-ognized 
as common usage. 
So it is with the common good practice recommendation 
guiding the use of public inheritance: that it should model an is-a 
relationship rather than ad hoc code reuse. For example, a save 
dialog is a dialog box and a list is a sequence, whereas a bounded 
list is not an unbounded list and vice versa. The view is that 
reuse-(over)driven approaches lead to the kind of spaghetti in-heritance 
hierarchies that give inheritance a bad name, and the 
is-a approach constrains inheritance hierarchies to more closely 
model expected classifications. 
Kevlin Henney is an 
independent con-sultant 
and trainer 
based in the UK. He 
may be contacted at 
kevlin@curbralan.com. 
However, like all analogies, it has a breaking point beyond 
which rhyme and reason denatures to protracted theological de-bate 
around the coffee machine. For instance, Rex is a dog, and 
although his owner might regard him in a class of his own, it is 
more likely that developers would view this as an instance-of re-lationship. 
Preferring is-a-kind-of to is-a steers us clear of many 
of the vagaries of natural language, but not so clear that it clari-fies 
how state models are inherited or how a virtual function 
should be overridden. For example, can a function that in the base 
class is guaranteed to accommodate null pointer arguments and 
never return a null pointer be sensibly overridden to accept only 
non-null arguments and return null pointers? The linguistic view 
does not provide a useful map through such territory. 
Liskov Substitution Principle The Liskov Substitution Principle 
(LSP)1,5 is often cited as giving more detailed guidance on the use 
of inheritance. It makes a clear separation between type— 
described in terms of the behavior of operations—and class—the 
realization of the behavior in programmatic detail. LSP then es-tablishes 
the criteria for subtyping relationships in terms of con-formant 
behavior5: 
A type hierarchy is composed of subtypes and supertypes. 
The intuitive idea of a subtype is one whose objects provide 
all the behavior of objects of another type (the supertype) plus 
something extra. What is wanted here is something like the 
following substitution property: If for each object o1 of type S 
there is an object o2 of type T such that for all programs P de-fined 
in terms of T, the behavior of P is unchanged when o1 
is substituted for o2, then S is a subtype of T. 
So, in answer to the previous question: No, a function cannot sen-sibly 
be overridden to strengthen the requirements on its arguments 
and weaken the requirements on its return type. This same rec-ommendation 
can be found echoed in Design by Contract.6 
Polymorphic Polymorphism LSP is normally presented as an in-heritance 
guideline, but taking a step back we can see that it need 
not be so narrow: It is a relationship about types, not implemen- 
28 May 2000
29 
tations—i.e., subtyping, not subclassing. LSP relies on polymor-phism; 
the concept of structural relationships, such as public in-heritance, 
need not enter into it. 
C++ developers have “inherited” from other OO languages 
and literature the notion that polymorphism concerns only in-heritance 
and virtual functions. Deserving of its name, polymor-phism 
manifests itself in many forms (see Table 1). This 
classification7 gives us a broader and more liberated view of type 
relationships. Constraining C++ solely to OO usage ignores its 
other strengths and denies its multiparadigm nature. 
TYPES OF SUBSTITUTABILITY Substitutability is the property that 
different elements have if they are grouped—and then treated— 
in terms of their commonality; variations that are not relevant to 
their use are not a part of this abstraction, or rather they do not 
dominate.3 Building on the previous discussion allows us to think 
outside the box, giving a broader view of substitutability grounded 
in C++'s mechanisms (see Table 2). 
The substitutability types are neither perfect peers nor perfectly 
hierarchical; they overlap and build on each other. Nonetheless 
they offer a useful way to understand and reason about features. 
There is a close correspondence between these substitutability types 
and the polymorphism categories described in Table 1. 
Conversions Conversions may be implicit or explicit, which places 
them under the control of the compiler or developer, respec-tively. 
Whether a conversion should be implicit or explicit is a mat-ter 
of taste, safety, and requirement. Widening conversions—from 
a specific to a general type—are always safe and can be implicit 
without offending sensibilities or the compiler, e.g., int to double 
or derived to base. Narrowing conversions—from a general to a 
specific type—are not guaranteed to be safe and should be explicit. 
One would hope that narrowing conversions would be re-quired 
to be explicit, but this is not always the case, e.g., double to 
int. Even though the compiler does not require it, one might ar-gue 
that taste does. Where possible, narrowing conversions should 
be checked, e.g., the use of dynamic_cast to go from base to derived. 
Developers need to consider the interoperability of new and 
existing types. Particularly for value types—i.e., for fine-grained 
objects such as strings, which express quantities, rather than 
persistent or strongly behavioral objects—the use of conver-sions 
to and from other types makes more sense than the use of 
inheritance relationships. 
A single argument constructor is also, by default, a converting 
constructor. Where a type may be safely, sensibly, and easily used 
in place of another type, an implicit conversion into that type ei-ther 
by a converting constructor or a user-defined conversion 
(UDC) operator may be justified, e.g., use of const char * in many 
places that a string may be used: 
class string 
{ 
public: 
string(const char *); 
... 
}; 
class file 
{ 
public: 
explicit file(const string &); 
... 
}; 
... 
const char *const log_name = getenv(“LOGFILENAME”); 
file log(log_name ? log_name : “default.log”); 
Otherwise—and this applies especially to UDCs—single argu-ment 
constructors should be declared explicit and UDCs left un-written, 
e.g., a string may not be sensibly used in most of the 
places a file object is expected, nor may a string always be used safely 
where a const char * is expected: 
class string 
{ 
public: 
... 
operator const char *( ) const; // questionable 
... 
}; 
string operator+(const string &, const string &); 
... 
const string log_suffix = “.log”; 
const char *const log_name = getenv(“LOGBASENAME”) + log_suffix; 
file log(log_name); 
Overloading Overloading is based on the idea that a common 
name implies a common purpose, which frees programmers from 
indulging in their own name-mangling to differentiate similar 
functions (this is the job of the compiler). Overloading works 
C++ Report ∫ http://www.creport.com 
Table 2. Different kinds of substitutability in C++. 
Substitutability Mechanisms 
Conversions Implicit and explicit conversions 
Overloading Overloaded functions and operators, 
often in combination with conversions 
Derivation Inheritance 
Mutability Qualification (typically const) and the 
use of conversions, overloading, and derivation 
Genericity Templates and the use of conversions, 
overloading, derivation, and mutability 
Table 1. Different kinds of polymorphism. 
Polymorphism Description 
Inclusion Conventional OO model of polymorphism, 
i.e., virtual functions 
Parametric Based on provision or deduction of extra type 
information that determines the types used in 
a function, i.e., templates 
Overloading Based on the use of the same name denoting 
different functions, with selection based on the 
context of use, i.e., argument number and type 
Coercion Based on the conversion of an object of one 
type to an object of another type based on its 
context of use
FROM MECHANISM TO METHOD 
closely with—and sometimes against—conversions. Developers 
are cautioned to keep any eye open for any such interference. 
30 
Operators provide a predefined set of names and definitions, and 
therefore expectations: Overloading operator-> suggests the smart 
pointer idiom, and overloading operator( ) suggests the function ob-ject 
idiom. Although compilers do not run through code checking it 
for stylistic content (e.g., use of meaningful variable names, sensible 
use of overloading, and conformant use of inheritance) these con-ventions 
derive from the language itself to establish a common frame 
for working with the language “when in doubt, do as the ints do.”8 
Extension through overloading forms an important part of oper-ator 
overloading–based substitutability. For instance, a class that is oth-erwise 
closed to change can apparently be extended to work within a 
framework, e.g., “extending” iostreams to understand new types. 
Some extension is less transparent, but it is important that it 
follow as much of the base form as possible. An obvious example 
is the use of placement new operators, which, in spite of taking 
additional arguments, have the same purpose and much of the 
same form as the vanilla new. Tagged overloads, such as 
new(std::nothrow), provide a means of compile-time selection that 
is a compromise between operators and named functions. 
Derivation Substitutability with respect to derivation is perhaps 
the most familiar category for programmers coming to C++ with 
a conventional OO angle. A public class interface establishes a be-havioral 
contract that the user relies on; derivation through pub-lic 
inheritance tells the compiler that the types are interchangeable, 
which only makes sense if the derived class developer promises to 
still fulfill the contract, even if it is extended in some way. Drop-ping 
LSP can lead to surprising behavior. 
In terms of coupling, derivation is also the strongest relation-ship 
one can have in a C++ system: It defines a dependency that 
is strongly physical, e.g., with respect to #include, as well as one 
that is strongly logical. The combined effect can lead to a tsunami-like 
recompilation of a whole system, rather than a gentle ripple 
effect, whenever the slightest change is made. Although C++ does 
not clearly separate the concepts of subtyping and subclassing in 
its inheritance mechanism, it is possible to effect this with inter-face 
classes,9 i.e., abstract classes containing only pure virtual func-tions. 
This offers a vehicle for substitutability independent of 
representation issues. Interestingly, this means that as a mecha-nism, 
inheritance may be used to either significantly increase or 
significantly decrease the coupling in a system. 
Mutability Mutability is concerned with the effects of change. For 
objects in C++ this means qualification: const and volatile. ...Well, 
const if we are being really honest with ourselves. From this per-spective 
every class has two public interfaces: the interface for 
const qualified objects and the interface for non-const qualified 
objects. The const interface is effectively a subset of the non-const 
interface, and therefore a non-const object may be used wherever 
a const one is expected; i.e., the qualified interface may be con-sidered 
a supertype of the unqualified one. Note that the subtyp-ing 
relationship need not be strict: Overloaded functions differing 
only in const or non-const will be selected according to the call-ing 
const-ness. In OO terms this can be considered a form of 
compile-time overriding of the const function by the non-const 
variant, typically to return something more specific: 
class string 
{ 
public: 
char operator[](size_t) const; 
char &operator[](size_t); // 'overrides' const version 
... 
}; 
... 
const string read_only = ...; 
cout << read_only[0]; 
string read_write = ...; 
cin >> read_write[0]; 
cout << read_write[0]; 
Genericity Templates offer a route to substitutability that grows 
out of the basic concept of overloading. A templated function can 
be considered to have a potentially infinite number of overloads 
all sharing a common name, purpose, and structure, but differ-ing 
in their parameter types. A similar view can be extended to 
template classes, and from there, to member templates. 
Generic programming, as typified by the part of the standard 
library derived from the STL, is based on the compile-time poly-morphism 
of C++ templates, as well as the concepts and mecha-nisms 
of the other substitutability categories. 
CONCLUSION Substitutability provides a useful way to structure 
a system's meaning. It can be recognized as reaching further than 
a commonplace recommendation for inheritance, drawing to-gether 
many C++ features in a set of practices that make sense of 
mechanism. 
Future columns will explore the different types of substi-tutability 
in greater detail, looking at language features and their 
use in idioms, and highlighting the practices that commonly (or 
uncommonly) appear in application and library code. ˘ 
References 
1. Coplien, J. Advanced C++: Programming Styles and Idioms, 
Addison–Wesley, Reading, MA, 1992. 
2. Coplien, J. Software Patterns, SIGS, New York, 1996. 
3. Coplien, J. Multi-Paradigm Design for C++, Addison–Wesley, 
Reading, MA, 1999. 
4. Henney, K. “Creating Stable Assignments,” C++ Report, 10(6): 
25–30, June 1998. 
5. Liskov, B. “Data Abstraction and Hierarchy,” OOPSLA '87 
Addendum to the Proceedings, Oct. 1987. 
6. Meyer, B. Object-Oriented Software Construction, 2nd ed., 
Prentice–Hall, Englewood Cliffs, NJ, 1997. 
7. Cardelli, L. and P. Wegner. “On Understanding Types, Data 
Abstraction, and Polymorphism,” Computing Surveys, 17(4): 
471–522, Dec. 1985. 
8. Meyers, S. More Effective C++: 35 New Ways to Improve Your 
Programs and Designs, Addison–Wesley, Reading, MA, 1996. 
9. Carroll, M. D. and M. A. Ellis. Designing and Coding Reusable 
C++, Addison–Wesley, Reading, MA, 1995. 
May 2000

More Related Content

What's hot

Introduction to Distributional Semantics
Introduction to Distributional SemanticsIntroduction to Distributional Semantics
Introduction to Distributional SemanticsAndre Freitas
 
Lean Logic for Lean Times: Varieties of Natural Logic
Lean Logic for Lean Times: Varieties of Natural LogicLean Logic for Lean Times: Varieties of Natural Logic
Lean Logic for Lean Times: Varieties of Natural Logic
Valeria de Paiva
 
An introduction to compositional models in distributional semantics
An introduction to compositional models in distributional semanticsAn introduction to compositional models in distributional semantics
An introduction to compositional models in distributional semanticsAndre Freitas
 
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYAMORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
ijnlc
 
Barreiro-Batista-LR4NLP@Coling2018-presentation
Barreiro-Batista-LR4NLP@Coling2018-presentationBarreiro-Batista-LR4NLP@Coling2018-presentation
Barreiro-Batista-LR4NLP@Coling2018-presentation
INESC-ID (Spoken Language Systems Laboratory - L2F)
 
First order predicate logic (fopl)
First order predicate logic (fopl)First order predicate logic (fopl)
First order predicate logic (fopl)
chauhankapil
 
amta-decision-trees.doc Word document
amta-decision-trees.doc Word documentamta-decision-trees.doc Word document
amta-decision-trees.doc Word documentbutest
 
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
Andre Freitas
 
Supporting language learners with the
Supporting language learners with theSupporting language learners with the
Supporting language learners with the
ijaia
 
Lean Logic for Lean Times: Entailment and Contradiction Revisited
Lean Logic for Lean Times: Entailment and Contradiction RevisitedLean Logic for Lean Times: Entailment and Contradiction Revisited
Lean Logic for Lean Times: Entailment and Contradiction Revisited
Valeria de Paiva
 
Syntax and semantics of propositional logic
Syntax and semantics of propositional logicSyntax and semantics of propositional logic
Syntax and semantics of propositional logic
Janet Stemwedel
 
Phrase structure grammar
Phrase structure grammarPhrase structure grammar
Phrase structure grammar
SubramanianMuthusamy3
 
Modular Ontologies - A Formal Investigation of Semantics and Expressivity
Modular Ontologies - A Formal Investigation of Semantics and ExpressivityModular Ontologies - A Formal Investigation of Semantics and Expressivity
Modular Ontologies - A Formal Investigation of Semantics and ExpressivityJie Bao
 
Distributional semantics
Distributional semanticsDistributional semantics
Distributional semantics
Rabindra Nath Nandi
 
Corpus-based part-of-speech disambiguation of Persian
Corpus-based part-of-speech disambiguation of PersianCorpus-based part-of-speech disambiguation of Persian
Corpus-based part-of-speech disambiguation of Persian
IDES Editor
 
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
Svetlin Nakov
 
Automatic Identification of False Friends in Parallel Corpora: Statistical an...
Automatic Identification of False Friends in Parallel Corpora: Statistical an...Automatic Identification of False Friends in Parallel Corpora: Statistical an...
Automatic Identification of False Friends in Parallel Corpora: Statistical an...
Svetlin Nakov
 
First order predicate logic(fopl)
First order predicate logic(fopl)First order predicate logic(fopl)
First order predicate logic(fopl)
surbhi jha
 

What's hot (20)

Introduction to Distributional Semantics
Introduction to Distributional SemanticsIntroduction to Distributional Semantics
Introduction to Distributional Semantics
 
Lean Logic for Lean Times: Varieties of Natural Logic
Lean Logic for Lean Times: Varieties of Natural LogicLean Logic for Lean Times: Varieties of Natural Logic
Lean Logic for Lean Times: Varieties of Natural Logic
 
Presentation1
Presentation1Presentation1
Presentation1
 
An introduction to compositional models in distributional semantics
An introduction to compositional models in distributional semanticsAn introduction to compositional models in distributional semantics
An introduction to compositional models in distributional semantics
 
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYAMORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
MORPHOLOGICAL SEGMENTATION WITH LSTM NEURAL NETWORKS FOR TIGRINYA
 
Barreiro-Batista-LR4NLP@Coling2018-presentation
Barreiro-Batista-LR4NLP@Coling2018-presentationBarreiro-Batista-LR4NLP@Coling2018-presentation
Barreiro-Batista-LR4NLP@Coling2018-presentation
 
First order predicate logic (fopl)
First order predicate logic (fopl)First order predicate logic (fopl)
First order predicate logic (fopl)
 
amta-decision-trees.doc Word document
amta-decision-trees.doc Word documentamta-decision-trees.doc Word document
amta-decision-trees.doc Word document
 
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
A Distributional Semantics Approach for Selective Reasoning on Commonsense Gr...
 
Supporting language learners with the
Supporting language learners with theSupporting language learners with the
Supporting language learners with the
 
Lean Logic for Lean Times: Entailment and Contradiction Revisited
Lean Logic for Lean Times: Entailment and Contradiction RevisitedLean Logic for Lean Times: Entailment and Contradiction Revisited
Lean Logic for Lean Times: Entailment and Contradiction Revisited
 
Syntax and semantics of propositional logic
Syntax and semantics of propositional logicSyntax and semantics of propositional logic
Syntax and semantics of propositional logic
 
Phrase structure grammar
Phrase structure grammarPhrase structure grammar
Phrase structure grammar
 
Modular Ontologies - A Formal Investigation of Semantics and Expressivity
Modular Ontologies - A Formal Investigation of Semantics and ExpressivityModular Ontologies - A Formal Investigation of Semantics and Expressivity
Modular Ontologies - A Formal Investigation of Semantics and Expressivity
 
J79 1063
J79 1063J79 1063
J79 1063
 
Distributional semantics
Distributional semanticsDistributional semantics
Distributional semantics
 
Corpus-based part-of-speech disambiguation of Persian
Corpus-based part-of-speech disambiguation of PersianCorpus-based part-of-speech disambiguation of Persian
Corpus-based part-of-speech disambiguation of Persian
 
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
Nakov S., Nakov P., Paskaleva E., Improved Word Alignments Using the Web as a...
 
Automatic Identification of False Friends in Parallel Corpora: Statistical an...
Automatic Identification of False Friends in Parallel Corpora: Statistical an...Automatic Identification of False Friends in Parallel Corpora: Statistical an...
Automatic Identification of False Friends in Parallel Corpora: Statistical an...
 
First order predicate logic(fopl)
First order predicate logic(fopl)First order predicate logic(fopl)
First order predicate logic(fopl)
 

Viewers also liked

Ch09
Ch09Ch09
Ch09
Dorian K
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
Kevlin Henney
 
Collections for States
Collections for StatesCollections for States
Collections for States
Kevlin Henney
 
Worse Is Better, for Better or for Worse
Worse Is Better, for Better or for WorseWorse Is Better, for Better or for Worse
Worse Is Better, for Better or for Worse
Kevlin Henney
 
Promoting Polymorphism
Promoting PolymorphismPromoting Polymorphism
Promoting Polymorphism
Kevlin Henney
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
Kevlin Henney
 
The Perfect Couple
The Perfect CoupleThe Perfect Couple
The Perfect Couple
Kevlin Henney
 
Learning Curve
Learning CurveLearning Curve
Learning Curve
Kevlin Henney
 
Inside Requirements
Inside RequirementsInside Requirements
Inside Requirements
Kevlin Henney
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
Kevlin Henney
 
Exceptional Naming
Exceptional NamingExceptional Naming
Exceptional Naming
Kevlin Henney
 
Making Steaks from Sacred Cows
Making Steaks from Sacred CowsMaking Steaks from Sacred Cows
Making Steaks from Sacred Cows
Kevlin Henney
 
Flag Waiving
Flag WaivingFlag Waiving
Flag Waiving
Kevlin Henney
 
The Next Best String
The Next Best StringThe Next Best String
The Next Best String
Kevlin Henney
 
Put to the Test
Put to the TestPut to the Test
Put to the Test
Kevlin Henney
 
The Programmer
The ProgrammerThe Programmer
The Programmer
Kevlin Henney
 

Viewers also liked (17)

Ch09
Ch09Ch09
Ch09
 
One Careful Owner
One Careful OwnerOne Careful Owner
One Careful Owner
 
Collections for States
Collections for StatesCollections for States
Collections for States
 
Worse Is Better, for Better or for Worse
Worse Is Better, for Better or for WorseWorse Is Better, for Better or for Worse
Worse Is Better, for Better or for Worse
 
Promoting Polymorphism
Promoting PolymorphismPromoting Polymorphism
Promoting Polymorphism
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
 
The Perfect Couple
The Perfect CoupleThe Perfect Couple
The Perfect Couple
 
Learning Curve
Learning CurveLearning Curve
Learning Curve
 
Inside Requirements
Inside RequirementsInside Requirements
Inside Requirements
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
 
Unit 3 Java
Unit 3 JavaUnit 3 Java
Unit 3 Java
 
Exceptional Naming
Exceptional NamingExceptional Naming
Exceptional Naming
 
Making Steaks from Sacred Cows
Making Steaks from Sacred CowsMaking Steaks from Sacred Cows
Making Steaks from Sacred Cows
 
Flag Waiving
Flag WaivingFlag Waiving
Flag Waiving
 
The Next Best String
The Next Best StringThe Next Best String
The Next Best String
 
Put to the Test
Put to the TestPut to the Test
Put to the Test
 
The Programmer
The ProgrammerThe Programmer
The Programmer
 

Similar to Substitutability

Conventional and Reasonable
Conventional and ReasonableConventional and Reasonable
Conventional and Reasonable
Kevlin Henney
 
SELFLESS INHERITANCE
SELFLESS INHERITANCESELFLESS INHERITANCE
SELFLESS INHERITANCE
ijpla
 
Form Follows Function
Form Follows FunctionForm Follows Function
Form Follows Function
Kevlin Henney
 
Objects of Value
Objects of ValueObjects of Value
Objects of Value
Kevlin Henney
 
Valued Conversions
Valued ConversionsValued Conversions
Valued Conversions
Kevlin Henney
 
Patterns of Value
Patterns of ValuePatterns of Value
Patterns of Value
Kevlin Henney
 
Ruby Interview Questions
Ruby Interview QuestionsRuby Interview Questions
Ruby Interview Questions
Sumanth krishna
 
Pattern-Level Programming with Asteroid
Pattern-Level Programming with AsteroidPattern-Level Programming with Asteroid
Pattern-Level Programming with Asteroid
ijpla
 
Object Oriented Principles
Object Oriented PrinciplesObject Oriented Principles
Object Oriented Principles
Emprovise
 
Advance oops concepts
Advance oops conceptsAdvance oops concepts
Advance oops concepts
Sangharsh agarwal
 
C++ interview question
C++ interview questionC++ interview question
C++ interview question
Durgesh Tripathi
 
A Survey of Object Oriented Programming LanguagesMaya Hris.docx
A Survey of Object Oriented Programming LanguagesMaya Hris.docxA Survey of Object Oriented Programming LanguagesMaya Hris.docx
A Survey of Object Oriented Programming LanguagesMaya Hris.docx
daniahendric
 
Top 30 Technical interview questions
Top 30 Technical interview questionsTop 30 Technical interview questions
Top 30 Technical interview questions
SohailSaifi15
 
SMalL - Semantic Malware Log Based Reporter
SMalL  - Semantic Malware Log Based ReporterSMalL  - Semantic Malware Log Based Reporter
SMalL - Semantic Malware Log Based Reporter
Stefan Prutianu
 
Programming topics. syed arslan rizvi
Programming topics. syed arslan rizviProgramming topics. syed arslan rizvi
Programming topics. syed arslan rizviSyed Arslan Rizvi
 
Oop by edgar lagman jr
Oop by edgar lagman jr Oop by edgar lagman jr
Oop by edgar lagman jr Jun-jun Lagman
 
EasyChair-Preprint-7375.pdf
EasyChair-Preprint-7375.pdfEasyChair-Preprint-7375.pdf
EasyChair-Preprint-7375.pdf
NohaGhoweil
 

Similar to Substitutability (20)

Conventional and Reasonable
Conventional and ReasonableConventional and Reasonable
Conventional and Reasonable
 
SELFLESS INHERITANCE
SELFLESS INHERITANCESELFLESS INHERITANCE
SELFLESS INHERITANCE
 
Form Follows Function
Form Follows FunctionForm Follows Function
Form Follows Function
 
Objects of Value
Objects of ValueObjects of Value
Objects of Value
 
Oop
OopOop
Oop
 
Valued Conversions
Valued ConversionsValued Conversions
Valued Conversions
 
Patterns of Value
Patterns of ValuePatterns of Value
Patterns of Value
 
Ruby Interview Questions
Ruby Interview QuestionsRuby Interview Questions
Ruby Interview Questions
 
LectureNotes-01-DSA
LectureNotes-01-DSALectureNotes-01-DSA
LectureNotes-01-DSA
 
Pattern-Level Programming with Asteroid
Pattern-Level Programming with AsteroidPattern-Level Programming with Asteroid
Pattern-Level Programming with Asteroid
 
Object Oriented Principles
Object Oriented PrinciplesObject Oriented Principles
Object Oriented Principles
 
Advance oops concepts
Advance oops conceptsAdvance oops concepts
Advance oops concepts
 
C++ interview question
C++ interview questionC++ interview question
C++ interview question
 
A Survey of Object Oriented Programming LanguagesMaya Hris.docx
A Survey of Object Oriented Programming LanguagesMaya Hris.docxA Survey of Object Oriented Programming LanguagesMaya Hris.docx
A Survey of Object Oriented Programming LanguagesMaya Hris.docx
 
Top 30 Technical interview questions
Top 30 Technical interview questionsTop 30 Technical interview questions
Top 30 Technical interview questions
 
SMalL - Semantic Malware Log Based Reporter
SMalL  - Semantic Malware Log Based ReporterSMalL  - Semantic Malware Log Based Reporter
SMalL - Semantic Malware Log Based Reporter
 
Mcs024
Mcs024Mcs024
Mcs024
 
Programming topics. syed arslan rizvi
Programming topics. syed arslan rizviProgramming topics. syed arslan rizvi
Programming topics. syed arslan rizvi
 
Oop by edgar lagman jr
Oop by edgar lagman jr Oop by edgar lagman jr
Oop by edgar lagman jr
 
EasyChair-Preprint-7375.pdf
EasyChair-Preprint-7375.pdfEasyChair-Preprint-7375.pdf
EasyChair-Preprint-7375.pdf
 

More from Kevlin Henney

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
Kevlin Henney
 
Get Kata
Get KataGet Kata
Get Kata
Kevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
Kevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
Kevlin Henney
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
Kevlin Henney
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
Kevlin Henney
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Recently uploaded

A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 

Recently uploaded (20)

A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 

Substitutability

  • 1. FROM MECHANISM TO METHOD Substitutability IF I WERE TO SAY that C++ is a language with a large number of features, it is unlikely that I would be in much danger of igniting a flame war. Where fact gives way to opinion—and sometimes to the holiest and most heated of wars—is in the recommendation of how to work with these features. What is their purpose? What concepts do they express? In short, what methods give sense to the mechanisms, elevating the programmer's view of the language from a shopping list of features to recipes that marshal features into designs? Sure, programmers need knowledge of syntax and semantics to make any headway with the language, but this learning curve quickly levels out to a plateau with the sheer face of design rising above it. Idioms offer a steady and complementary companion route— patterns that capture an understanding of problem and solution married together at the level of the language.1,2 Idioms establish a vocabulary for communicating and formulating design, where "design is the activity of aligning the structure of the application analysis with the available structures of the solution domain."3 On the other hand, while practices based on accepted wisdom generate comfortable habits that generally simplify day-to-day de-velopment, this is no reason to be complacent. Occasionally re-visiting old maxims can reveal other useful insights that were hiding in the shadows.4 IS-A IS NOT ENOUGH Attractive as the idea first seems, the Eng-lish language does not offer consistently useful guidance for the analysis of problems and the statement of software structure. Excitement about nouns as objects and verbs as methods often wears off when the nouning of verbs and verbing of nouns is rec-ognized as common usage. So it is with the common good practice recommendation guiding the use of public inheritance: that it should model an is-a relationship rather than ad hoc code reuse. For example, a save dialog is a dialog box and a list is a sequence, whereas a bounded list is not an unbounded list and vice versa. The view is that reuse-(over)driven approaches lead to the kind of spaghetti in-heritance hierarchies that give inheritance a bad name, and the is-a approach constrains inheritance hierarchies to more closely model expected classifications. Kevlin Henney is an independent con-sultant and trainer based in the UK. He may be contacted at kevlin@curbralan.com. However, like all analogies, it has a breaking point beyond which rhyme and reason denatures to protracted theological de-bate around the coffee machine. For instance, Rex is a dog, and although his owner might regard him in a class of his own, it is more likely that developers would view this as an instance-of re-lationship. Preferring is-a-kind-of to is-a steers us clear of many of the vagaries of natural language, but not so clear that it clari-fies how state models are inherited or how a virtual function should be overridden. For example, can a function that in the base class is guaranteed to accommodate null pointer arguments and never return a null pointer be sensibly overridden to accept only non-null arguments and return null pointers? The linguistic view does not provide a useful map through such territory. Liskov Substitution Principle The Liskov Substitution Principle (LSP)1,5 is often cited as giving more detailed guidance on the use of inheritance. It makes a clear separation between type— described in terms of the behavior of operations—and class—the realization of the behavior in programmatic detail. LSP then es-tablishes the criteria for subtyping relationships in terms of con-formant behavior5: A type hierarchy is composed of subtypes and supertypes. The intuitive idea of a subtype is one whose objects provide all the behavior of objects of another type (the supertype) plus something extra. What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P de-fined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. So, in answer to the previous question: No, a function cannot sen-sibly be overridden to strengthen the requirements on its arguments and weaken the requirements on its return type. This same rec-ommendation can be found echoed in Design by Contract.6 Polymorphic Polymorphism LSP is normally presented as an in-heritance guideline, but taking a step back we can see that it need not be so narrow: It is a relationship about types, not implemen- 28 May 2000
  • 2. 29 tations—i.e., subtyping, not subclassing. LSP relies on polymor-phism; the concept of structural relationships, such as public in-heritance, need not enter into it. C++ developers have “inherited” from other OO languages and literature the notion that polymorphism concerns only in-heritance and virtual functions. Deserving of its name, polymor-phism manifests itself in many forms (see Table 1). This classification7 gives us a broader and more liberated view of type relationships. Constraining C++ solely to OO usage ignores its other strengths and denies its multiparadigm nature. TYPES OF SUBSTITUTABILITY Substitutability is the property that different elements have if they are grouped—and then treated— in terms of their commonality; variations that are not relevant to their use are not a part of this abstraction, or rather they do not dominate.3 Building on the previous discussion allows us to think outside the box, giving a broader view of substitutability grounded in C++'s mechanisms (see Table 2). The substitutability types are neither perfect peers nor perfectly hierarchical; they overlap and build on each other. Nonetheless they offer a useful way to understand and reason about features. There is a close correspondence between these substitutability types and the polymorphism categories described in Table 1. Conversions Conversions may be implicit or explicit, which places them under the control of the compiler or developer, respec-tively. Whether a conversion should be implicit or explicit is a mat-ter of taste, safety, and requirement. Widening conversions—from a specific to a general type—are always safe and can be implicit without offending sensibilities or the compiler, e.g., int to double or derived to base. Narrowing conversions—from a general to a specific type—are not guaranteed to be safe and should be explicit. One would hope that narrowing conversions would be re-quired to be explicit, but this is not always the case, e.g., double to int. Even though the compiler does not require it, one might ar-gue that taste does. Where possible, narrowing conversions should be checked, e.g., the use of dynamic_cast to go from base to derived. Developers need to consider the interoperability of new and existing types. Particularly for value types—i.e., for fine-grained objects such as strings, which express quantities, rather than persistent or strongly behavioral objects—the use of conver-sions to and from other types makes more sense than the use of inheritance relationships. A single argument constructor is also, by default, a converting constructor. Where a type may be safely, sensibly, and easily used in place of another type, an implicit conversion into that type ei-ther by a converting constructor or a user-defined conversion (UDC) operator may be justified, e.g., use of const char * in many places that a string may be used: class string { public: string(const char *); ... }; class file { public: explicit file(const string &); ... }; ... const char *const log_name = getenv(“LOGFILENAME”); file log(log_name ? log_name : “default.log”); Otherwise—and this applies especially to UDCs—single argu-ment constructors should be declared explicit and UDCs left un-written, e.g., a string may not be sensibly used in most of the places a file object is expected, nor may a string always be used safely where a const char * is expected: class string { public: ... operator const char *( ) const; // questionable ... }; string operator+(const string &, const string &); ... const string log_suffix = “.log”; const char *const log_name = getenv(“LOGBASENAME”) + log_suffix; file log(log_name); Overloading Overloading is based on the idea that a common name implies a common purpose, which frees programmers from indulging in their own name-mangling to differentiate similar functions (this is the job of the compiler). Overloading works C++ Report ∫ http://www.creport.com Table 2. Different kinds of substitutability in C++. Substitutability Mechanisms Conversions Implicit and explicit conversions Overloading Overloaded functions and operators, often in combination with conversions Derivation Inheritance Mutability Qualification (typically const) and the use of conversions, overloading, and derivation Genericity Templates and the use of conversions, overloading, derivation, and mutability Table 1. Different kinds of polymorphism. Polymorphism Description Inclusion Conventional OO model of polymorphism, i.e., virtual functions Parametric Based on provision or deduction of extra type information that determines the types used in a function, i.e., templates Overloading Based on the use of the same name denoting different functions, with selection based on the context of use, i.e., argument number and type Coercion Based on the conversion of an object of one type to an object of another type based on its context of use
  • 3. FROM MECHANISM TO METHOD closely with—and sometimes against—conversions. Developers are cautioned to keep any eye open for any such interference. 30 Operators provide a predefined set of names and definitions, and therefore expectations: Overloading operator-> suggests the smart pointer idiom, and overloading operator( ) suggests the function ob-ject idiom. Although compilers do not run through code checking it for stylistic content (e.g., use of meaningful variable names, sensible use of overloading, and conformant use of inheritance) these con-ventions derive from the language itself to establish a common frame for working with the language “when in doubt, do as the ints do.”8 Extension through overloading forms an important part of oper-ator overloading–based substitutability. For instance, a class that is oth-erwise closed to change can apparently be extended to work within a framework, e.g., “extending” iostreams to understand new types. Some extension is less transparent, but it is important that it follow as much of the base form as possible. An obvious example is the use of placement new operators, which, in spite of taking additional arguments, have the same purpose and much of the same form as the vanilla new. Tagged overloads, such as new(std::nothrow), provide a means of compile-time selection that is a compromise between operators and named functions. Derivation Substitutability with respect to derivation is perhaps the most familiar category for programmers coming to C++ with a conventional OO angle. A public class interface establishes a be-havioral contract that the user relies on; derivation through pub-lic inheritance tells the compiler that the types are interchangeable, which only makes sense if the derived class developer promises to still fulfill the contract, even if it is extended in some way. Drop-ping LSP can lead to surprising behavior. In terms of coupling, derivation is also the strongest relation-ship one can have in a C++ system: It defines a dependency that is strongly physical, e.g., with respect to #include, as well as one that is strongly logical. The combined effect can lead to a tsunami-like recompilation of a whole system, rather than a gentle ripple effect, whenever the slightest change is made. Although C++ does not clearly separate the concepts of subtyping and subclassing in its inheritance mechanism, it is possible to effect this with inter-face classes,9 i.e., abstract classes containing only pure virtual func-tions. This offers a vehicle for substitutability independent of representation issues. Interestingly, this means that as a mecha-nism, inheritance may be used to either significantly increase or significantly decrease the coupling in a system. Mutability Mutability is concerned with the effects of change. For objects in C++ this means qualification: const and volatile. ...Well, const if we are being really honest with ourselves. From this per-spective every class has two public interfaces: the interface for const qualified objects and the interface for non-const qualified objects. The const interface is effectively a subset of the non-const interface, and therefore a non-const object may be used wherever a const one is expected; i.e., the qualified interface may be con-sidered a supertype of the unqualified one. Note that the subtyp-ing relationship need not be strict: Overloaded functions differing only in const or non-const will be selected according to the call-ing const-ness. In OO terms this can be considered a form of compile-time overriding of the const function by the non-const variant, typically to return something more specific: class string { public: char operator[](size_t) const; char &operator[](size_t); // 'overrides' const version ... }; ... const string read_only = ...; cout << read_only[0]; string read_write = ...; cin >> read_write[0]; cout << read_write[0]; Genericity Templates offer a route to substitutability that grows out of the basic concept of overloading. A templated function can be considered to have a potentially infinite number of overloads all sharing a common name, purpose, and structure, but differ-ing in their parameter types. A similar view can be extended to template classes, and from there, to member templates. Generic programming, as typified by the part of the standard library derived from the STL, is based on the compile-time poly-morphism of C++ templates, as well as the concepts and mecha-nisms of the other substitutability categories. CONCLUSION Substitutability provides a useful way to structure a system's meaning. It can be recognized as reaching further than a commonplace recommendation for inheritance, drawing to-gether many C++ features in a set of practices that make sense of mechanism. Future columns will explore the different types of substi-tutability in greater detail, looking at language features and their use in idioms, and highlighting the practices that commonly (or uncommonly) appear in application and library code. ˘ References 1. Coplien, J. Advanced C++: Programming Styles and Idioms, Addison–Wesley, Reading, MA, 1992. 2. Coplien, J. Software Patterns, SIGS, New York, 1996. 3. Coplien, J. Multi-Paradigm Design for C++, Addison–Wesley, Reading, MA, 1999. 4. Henney, K. “Creating Stable Assignments,” C++ Report, 10(6): 25–30, June 1998. 5. Liskov, B. “Data Abstraction and Hierarchy,” OOPSLA '87 Addendum to the Proceedings, Oct. 1987. 6. Meyer, B. Object-Oriented Software Construction, 2nd ed., Prentice–Hall, Englewood Cliffs, NJ, 1997. 7. Cardelli, L. and P. Wegner. “On Understanding Types, Data Abstraction, and Polymorphism,” Computing Surveys, 17(4): 471–522, Dec. 1985. 8. Meyers, S. More Effective C++: 35 New Ways to Improve Your Programs and Designs, Addison–Wesley, Reading, MA, 1996. 9. Carroll, M. D. and M. A. Ellis. Designing and Coding Reusable C++, Addison–Wesley, Reading, MA, 1995. May 2000