Alistair Cockburn

Re: Shu Ha Ri

For a much more detailed explanation of different levels of learning, I highly recommend From Novice to Expert, by Patricia Benner. Though about nursing, I found a lot of it applied pretty much directly to my XP coaching.

-by Curt Sampson on 12/11/2008 at 8:11 PM

Someone vidd’d me describing Shu Ha Ri in my agile class, so I uploaded it: Vid of Alistair describing Shu Ha Ri (discussion: Re: Vid of Alistair describing Shu Ha Ri)

-by Alistair on 7/22/2010 at 4:25 PM

FYI Just posted a link between Shu-Ha-Ri and Daniel Kahneman’s awesome new book on the workings of the mind.

-by John Rusk on 1/21/2012 at 2:11 AM

Is there a meaningful/useful/reasonable distinction between mastery and expertise?

I’m beginning to consider the conversion of ‘recommended’ software engineering from a culture of expertise to a culture of learning.

Probably a remnant of my earlier Deming reading, but it seems that development teams seek to learn, through practical exercise, bot what works for the customer/client/product owner/sponsor and what works for themselves/team/company.

This seems different from an artist learning to paint from a master (or a white belt from a black belt), where Shu-Ha-Ri results in mastery of techniques. This is the application of (learned, understood, or) mastered techniques to a dynamic/fluid environment — rather like surfing as opposed to skiing.

Hopefully, that’s close enough description to get the gist. Do you see such a distinction?

-by Skip Pletcher on 8/23/2012 at 10:37 AM

Hi, Skip: I do, personally. To me (at this instant) ‘expertise’ connotes mostly knowledge, ‘mastery’ connotes ability. As I see it, someone can be a master at something without knowing explicitly; whereas to say they have expertise, I would expect ability to articulate more of the nuances. Does that do you any good? Alistair

see also James Holmes’ page

Evidently the akidofaq website is no longer funtioning. For those who are interested in a revised version of my ShuHaRi article, it’s a two parter on the kendo-world dot com website.
Sorry for the whacked out links but I don’t want this to be destroyed by the html link filter:

Part 1
www.kendo-world dot com /wordpress/?p=1822

Part 2

www.kendo-world dot com /wordpress/?p=1824

-by Ron Fox on 9/29/2015 at 8:58 AM

Visually deconstructing paint on ladies

Visually deconstructing paint on ladies,
Pencils poised, pursed lips puckered
in concentration.

Feigned indifference, as though
they – I – know
what they are doing.

But they – I – are here anyway,
So they will just continue
To deconstruct in silence

© Alistair Cockburn, 2015.


You cant catch yourself by chasing yourself

You Can’t Catch Yourself By Chasing Yourself

When you see the world through the eyes of another person
you are seeing the other person.

When you see another person through your own eyes
you are seeing yourself.

The God that split into an infinity of pieces to experience life
sits behind you, before you, in you.

The God you see behind you is you.
The world you see before you is you.

As I feel, you are.
As I see the world, I am.


You lead yourself through the darkness;
you are your own light.

The light reflecting off others
is your own light reflecting back,
reflecting, also,
the light of millions of others
lighting their own way
through the darkness.


When you see the world through the eyes of another person
you are seeing the other person.

When you see the world through your eyes of yesterday
you are seeing yourself yesterday.

But yourself is always new,
different from ‘just now’.

The light reflecting off others is your light,
out of time with yourself, just now…

and the lights of others,
millions of others,
are the lights of stars
long moved on.


That light you see in others
is your light, reflected,
reflecting also the millions of others
lighting their own way
through the darkness;

the lights of others
the lights of stars
long moved on.

That light you see in yourself
is your light, reflected,
delayed, out of time with yourself,
long moved on.

© Alistair Cockburn, 2011.


(Thanks to Krishnamurti, “Meeting Life” p 57)
“As I look at myself I am learning about myself. Do I accumulate knowledge about myself, and then, with that knowledge, observe? Is this the same as looking at myself through Freud? Can I learn about myself without any accumulation? That is the only way to learn, because ‘myself’ is always moving…. I cannot learn about his through something static, whether it be the knowledge I have accumulated about myself or Freud. Therefore I have to be free of the knowledge I gathered about myself yesterday.”

Ghosts walk with me

Ghosts walk with me
this path I have not walked before,
but like others I have walked
in places like this, with friends, past.

Those friends who might pass again,
and others, not,

I keep you near me on this walk,
for company, and for memories
of your company.

I send you away,
to be present on this walk, alone,
with fear of losing you again.

And come again.
And go, again.

Let’s find what this present future

`188:© 2015 Alistair Cockburn / / being )



land of the rulebook

where for each action is assigned a responsible party

so one knows who to blame,

and one needs a diploma to be a gardner.

How do you maintain such continual prosperity,

stay neutral while world wars rage on all sides,

and earn both respect and scorn from your guests?

Wait, let me back up and rephrase those questions.

How can you refuse to acknowledge the pain and

persecution of non-citizen neighbors,

close your borders to supplicants,

and ignore overwhelming forces about to

crush you from two sides?

Well, it worked. Twice.

You even made money.

How do you justify employing foreigners to clean

your streets and stairwells at cut rates,

and evicting them when jobs get tight?

Oh, it reduces the burden of unemployment benefits,

the streets look tidy,

and you don’t even have to clean them yourself.


land of four classes of people:

the janitors, the tourists, the workers, the rich.

proud of its hardened uneducated mountain folk

who still use their teeth to make cheese in the old way.

Why are you so nice to visit?

So nice to live in that aliens clamor at your border

and endure embarrassing violations to enter

the upper circle: citizen?

How is it that even I, with all these malicious thoughts,

like to live here?

How do you do it? and how can you live with yourself?

© Alistair Cockburn, 1986

Re: Use cases, ten years later

Not really a comment but more of a question: what in your opinion is the difference between system use cases and business use cases (points of view of authorities/goeroes vary from “no difference at all” to “they are totally different views at different levels of abstraction”).

-by Chris Scholten on 1/14/2010 at 9:10 AM

A true “business use case” doesn’t show the technology of storage and transmission; there’s a creative gap from there to inventing system(s!) to support that movement. Any system use case documents the design of the proposed system services.

That help?


-by Alistair on 1/14/2010 at 12:53 PM


When reading the excellent, “use case modelling” by Bittner and Spence they say that you should not be afraid of the detail in your use cases. I agree on your point about the length of main flow, and I am also finding that mine are much shorter just by avoiding the urge to stretch them out with no good reason. It is difficult, however, to know when enough detail is really nough sometimes. It’s soemthing I am currently struggling on a project.

-by dee on 2/11/2010 at 4:47 AM

Hi Alistair,

I have been challenged by use cases that define user interfaces…

For example, I have a use case “View Order Validation Rules”
So the basic steps are:
1. I search for the appropriate vailidation rules based on some criteria
2. The system displays the rules
3. I am able to filter or sort these rules.

1. By selecting a specific field in the rule, I can also view how that rule should be handled. Meaning if rule A is not true, then reject the order. if rule B is not true, then only reject the specific sub-item within the order etc.

Is this sufficient from a use case perspective? There might be situations when I search for example, to be able to search for a customer, then when I select the specific customer, I am presented with a list of orders from which I can pick an order… where would you see this kind of functionality described? Is it going to be in the UI (related to step 1 of the main flow) or as part of the use case?

thank you

-by SS on 5/24/2010 at 3:20 PM

Hi Alistair,

I have been challenged by use cases that define user interfaces…

For example, I have a use case “View Order Validation Rules”
So the basic steps are:
1. I search for the appropriate vailidation rules based on some criteria
2. The system displays the rules
3. I am able to filter or sort these rules.

1. By selecting a specific field in the rule, I can also view how that rule should be handled. Meaning if rule A is not true, then reject the order. if rule B is not true, then only reject the specific sub-item within the order etc.

Is this sufficient from a use case perspective? There might be situations when I search for example, to be able to search for a customer, then when I select the specific customer, I am presented with a list of orders from which I can pick an order… where would you see this kind of functionality described? Is it going to be in the UI (related to step 1 of the main flow) or as part of the use case?

thank you

-by SS on 5/24/2010 at 4:51 PM

Hi Alistair,

Would you consider to write another article on use cases as year 2012 has marked another decade of evolution since this article was first published? Thanks.


-by Isabel on 7/26/2012 at 3:47 PM

Hi, Isabel… point #4 of my predictions happened: agile and user stories have eclipse use cases. I still like them, BAs and testers like them, but programmers won’t touch them, and things move so fast these days there is scarcely time to think, let alone write use cases. Even I find it hard to write complete use cases any more, even though piles of story cards don’t do the trick for larger, more complex domains.

-by Alistair on 7/26/2012 at 7:46 PM


What is your take on using use case format to describe analytical flows? Wikipedia lists it as one of the limitations, but wikipedia is wikipedia. You are the expert.



-by Alexei on 8/2/2012 at 4:52 PM

what is an “analytical flow”? I don’t find it on the Wikipedia page. In general, use cases describe well mildly branching interactions between a few parties. Wildly branching interactions call more for state machines or tables; no interactions calls for formulae or algorithms; many parties: i have no idea what. Does that help a bit? Alistair


It does. What I mean is, would I use a use case format to describe how one goes about analyzing website behaviors (not how users interact with the website, but the actual analysis flow, i.e. analyze referring sources, analyze messages within referring source, analyze content). Pretty much, if i were to use a use case for a problem analysis or decision making process (

Thanks and apologies for multiple comments.


-by Alexei on 8/3/2012 at 9:14 AM

good luck. Alistair

Hi Alistair,

I am a business analyst and would like to know the very basic difference between the Analytical Use Case vs Synthetic Use Case.

As i have checked many website, they suggest to use the synthetic use case for the Root Level problems.

Please share your views.


-by Vaibhav on 9/6/2012 at 5:08 AM

Elective vitality is the vitality highly utilized by men for option vitality and the cost shoddy . www[dot]samb[dot]at/95Nzl

-by cila on 9/5/2015 at 1:05 AM

JDKrise Scrum laid out.pdf

Recent Change Note: Minor updates - removed "Hughes"The document should open in a new window in three seconds.

If it does not, please click here.setTimeout(function(){'/get/2736');}, 3000);

Coeur dAgile en Francais 2015.pdf

Recent Change Note: Merci Nicolas Mereaux pour la traductionThe document should open in a new window in three seconds.

If it does not, please click here.setTimeout(function(){'/get/3571');}, 3000);

The magic of pi for project managers

An experienced project manager told me he multiplies his developers’ estimate by π.
“It’s a natural law,” he said.
I have since found that π, π^2, and √π are all important magic numbers for project managers .

  • Multiply by π for small, known teams, doing a new job,
  • by π^2 for unknown teams,
  • and √π for known teams who have already started, know their work and have a good track record.

Here’s an example from real life:

I was asked to come in and be technical coordinator on a project of 3 people who were in phase 2 of a 3-phase project. They had said the project would take 15 work weeks.

(In my world, this small of a project does not need a technical coordinator, it is a “do it and go home” size of a project)

I started asking questions and got strange answers back, indicating that this might not be actually just a 15-work week project. We decided to hold a proper estimating meeting (I had not yet run across the Blitz Planning technique at that time, sadly). On the way in, I was describing to the sponsor about the magic of π^2 on estimates, not really thinking about it, just chatting. When we finished the session, the estimate came out to a whopping 130 work-weeks! Yikes! (and imagine the fun discussion that followed, with the various project funding groups!). As we walked out, she said, “130 work-weeks about 9 times 15 work-weeks. How did you know that?” I said, “I didn’t, it’s just one of those magic numbers.”

About 4 months later, she did some more re-estimation, and said to me, “I can’t keep multiplying their estimates by π^2, what should I do?”
I replied, “They are in steady-state now, working well along. Just multiply by √π at this point.”
She did, and they did.

The project came in at about 190 work-weeks, and was considered a “success”, because they got to the final estimate well ahead of the end of the project, which was a first for them.

I’ll add the logic as to why these three numbers work as a 2nd installment to this post… stay tuned.

Part 2. Why does this work

OK, to be honest, I don’t know. That’s the magic of magic numbers. But I’ll load up some observations and see if they make sense.

You move at 1/3 the speed you think you will.

Did you ever make a list of things to do on Saturday? You know

  • take dog to vet
  • buy replacement thimtwiddlle for the doohickey
  • take kids to visit auntie
  • clean the basement
  • put the back of the garage into order
  • vaccuum under the kids’ beds
  • read more of Lost in a Good Book
  • get in-box to zero
  • et cetera

And you run around all day like a maniac, and at the end of the day you moan, “Gag! I didn’t even get HALF my list done?”

Next time this happens, take another look: Did you get 1/3 of the list done?
If so, that was a good day. Congratulate yourself.

It’s very often the case that we move / accomplish at about 1/3 the speed we think we will.

There are often 3x as many tasks inside a new project as you can visualize

Imagine you make a list of all the things you would have to do to get a particularly complicated piece of work done.

  • I did this once when we were considering adding a little bathroom all by ourselves. The list of tasks as easily 3x the list we expected.
  • It is not too different to going to the grocery store without a shopping list — you get to the checkout counter, and sure enough, you’ve managed to buy 3x the amount of stuff you expected, 3x the cost.
  • Or write a description of how to make a meal or something for your teenager, and see how many elements you normally do without thinking you left out

The thing is, when we think about things to do, we gloss over many of the small details, forget the setting up, the cleaning up afterwards, movements of transition.

For many (not all) things that we do, especially things we haven’t done before, we only manage to list about 1/3 of all the things to do.

Off by 3 on speed, off by 3 on size, and you’re off by 9. π^2.

In the project example up above, this team of experienced developers left out gathering the requirements, meeting with the other team, testing, and many other things. They only wrote the estimate for “programming”. Off by 3x. Then, once they looked closely at the tasks and thought in more vivid terms about doing them, they realized they would take longer than they originally imagined. In fact, a lot longer, like 3x.

That’s π^2.

But what about long-term, steady state? You can’t keep multiplying everything by π^2! Surely there is some learning?!

Yes, indeed. The key to understanding √π is the small distractions of daily life.

The same project manager who told me the magic of π later, when discussing utilisation quota for consultants and employees, told me, “I never count on a person being productive more than 60% of the time. There are just too many small things happening during the day.”

hmmm if something were scheduled to take 1 day, at 60% efficiency, it would end up taking about 1.7 days.
√π is 1.77.
Not bad.

So now imagine a team is rolling along nicely. They understand their job and their normal pace. They are still likely to forget about all those little things, the phone calls, the meetings, someone dropping in to ask questions, having to reboot their computer or install a new program…. so, they will still estimate at a full pace, not one recalibrated to account for all the little slowing down items that happen during the day. And they will be off by √π

Here’s the graphic for all the above:

Postscript: It took a long time before I noticed one interestinng little detail about the project described at the beginning. It came in at 190 work-weeks, after we had carefully examined it for 130 work weeks. 190/130 is 1.46, or very close to √π!

That’s magic.

Take a look and see how these thoughts all fit into your day(s).

Screechingly obvious code

Back in the very late 90s I wrote on Ward's wiki the entry Screechingly Obvious Code. That entry was prompted by reading one of Kent Beck’s articles on programming, where he had described the State pattern. His code was all clean and tidy by usual standards, but somehow I couldn’t get comfortable with it for some reason – the naming was still too obscure for me.

Then I watched people find and fix bugs in a hurry, and it became clearer to me —- they needed function/method names that really shouted out what was about to happen in there.

The contents of the Ward’s wiki entry go like this, slightly reformatted and few sentences with example code added:

Times used to be when people who were really conscientious wrote Squeaky Clean Code. Others, watching them, thought they were wasting their time. I got a shock one day when I realized that Squeaky Clean Code isn’t good enough.

I was standing behind two people who were working their way through a bug list sent up by the testing group. Instead of helping them work, I started watching their movements (this was Smalltalk, 1995, many browser windows on the screen). They would look through the method where the error had been caught, and guess at which called method contained the error. They called up the browser for a class, scanned the method list and opened a method. They looked at the method to see whether it was the place they were going to type in their fix. When it turned out not to be, they looked for what other method could be the one? They averaged 15-45 seconds per method as they went down through the code and across the methods in the browser list. At each point, they were looking for, is this the place I type my fix, or where does it point to next?

It occurred to me that where they went down a dead end was because the method’s contents did not match its name. These people were basically looking for a sign in the browser that would say, “Type in here, buddy!”

That’s when I recognized that they needed ScreechinglyObviousCode.

At the time, it was considered an OK thing to do to have an event method,

do this
do that

i.e., inside that method do whatever needed to be done.

That would be allowed under Squeaky Clean Code.

However, in Screechingly Obvious Code, it wouldn’t, because the method name doubleClicked only says that something was double clicked, and not what would happen.

Let’s say that it should refresh the pane or something. There should therefore be a method called refreshPane, and doubleClick would only contain the one line: self refreshPane.


So if you were tracking down what happens on a double-click, you’d naturally spot doubleClicked, and opening it you’d know the pane gets refreshed. And/But/Further, if you were having trouble with pane refreshes, you wouldn’t have to go and dig out that pane refreshes (maybe also) happen after a double click, you could just go and read

do this
do that

Exactly that was happening on this project. The people fixing the bug knew there was a problem refreshing the pane, but had to dig to learn that refreshing the pane was being done inside doubleClick. It would have saved them much effort if the method refreshPane was clearly marked in the method list in the browser, so they could go straight there.

I learned, from that afternoon, not to put behavior into an event-handling method, but for such a method to call out a behavior-containing method with the appropriate name. The reading of the code is then, simply: “When a doubleClicked event occurs, refresh the pane” rather than “When a doubleClicked event occurs, do all this stuff, which, by the way, if you read carefully, you will notice refreshes the pane.”

At that point I started looking for ScreechinglyObviousCode (hint: be sure to use “IntentionRevealingNames”). XP, of course, encourages this. Personally, I think the StatePattern violates ScreechinglyObviousCode and makes for pretty obscure code, but I don’t have the energy to revise it and publish… maybe someone else will take up the challenge. — AlistairCockburn

Anyway, that was my posting back then, and James Shore fortunately picked up the theme in his article Quality with a Name and his book, Art of Agile Development.

Then today, I saw a reference to Bob Martin’s codingtips (probably from his new book Clean Code which I’m itching to take a look at), and lo and behold – there’s almost the same example, except he ran into it by looking for code duplication.

Bob describes it under his particular conditions, but basically, he had two functions, slim_to_ruby_method(method_name) and to_file_name(module_name), both of which used letter-for-letter identical code, that just accidentally did the same thing … convert a CamelCase word to lower case with ’_’ between words (e.g., moduleName -> module_name).

In the article, Bob works out that they aren’t really duplication but they are really duplication, and he generates the same answer as if he had been running the Screechingly Obvious Code argument through his head … that is, that the code was REALLY identical, in that it was quite intentionally doing the same thing: camel case to underscore between words; and that the calling methods intentions were different – i.e., one was converting method names, the other module names.

The Screechingly Obvious Code result looks just like above, and just like what he produced, and here I quote his code:

def slim_to_ruby_method(method_name)
enddef to_file_name(module_name)
def camel_to_underscore(camel_namme)
value = camel_name[0..0].downcase + camel_name[1..-1]
value.gsub(/[A-Z]/) { |cap| ”_#{cap.downcase}” }

And those tell the reader both what each function is supposed to do and what it really does. It gets rid of the duplication where the duplication is supposed to gone and leaves things apart where they are supposed to be left apart.


Interview with Alistair 2015 on Software Requirements Specifications

Short interview with me on user stories and use cases versus Software Requirements Specification

The Differences between User Stories and Software Requirements Specification (SRS) – Interview with Dr. Alistair Cockburn

Posted on July 23, 2015 in Education, Research
This is the fifth post in the series in which I have interviewed several Agile experts to reveal the differences between user stories and software requirements and their application in regulated systems (i.e. health IT systems). You can find the previous post in this series here.

Today’s interview is with Dr. Alistair Cockburn, one of the original creators of the Agile Software Development movement and co-author of “The Agile Manifesto.” He was voted as one of the “All-Time Top 150 i-Technology Heroes” for his pioneering work in the software field. Besides being an internationally renowned IT strategist and author of the Jolt award-winning books “Agile Software Development” and “Writing Effective Use Cases,” he is an expert on agile development, use cases, process design, project management, and object-oriented design.

In 2003 he created the Agile Development Conference; in 2005 he co-founded the Agile Project Leadership Network; and in 2010 he co-founded the International Consortium for Agile. Many of his articles, talks, poems, and blogs are online at

Do you think that “user story” is just a fancy name for SRS?

No, but close.

How do you compare a user story with SRS?

A story must be end-user visible, something that an end user declares is valuable to him/her, and implementable in one sprint. SRS does not have those characteristics.

Do you think that user stories replace SRS?


Which of the two do you prefer working with?

Neither. Use cases + user stories works well.

Which of the two methods do you recommend using for regulated systems (i.e., health IT systems, medical device software)?

I do not recommend user stories for regulated systems. I do not recommend SRS ever.

Interview with Alistair 2012 Audio Interview for Agile Revolution in Australia Nov 2012

Craig Smith, Renee Troughton and Tony Ponton in Brisbane (Australia) caught hold of me and tied me down, plied me with wine while they joked about and asked questions… the result on the site is their podcast #49, about 45 minutes of fun interview (missing only the Oath of Non-Allegiance (discussion: Re: Oath of Non-Allegiance), which they say they’ll get in the next interview).

Check out

Some timing marks:

  • Advanced Agile at 5:30
  • 1st of Tony’s funny faces about 9:45 – 10:00
  • Agile manifesto “x OVER y” 19:30
  • 2nd Tony funny face about 22:20
  • Organizational transformation about 26:00+
  • Renee speechless for a few seconds about 27:00 – 27:15
  • Baby crying “mummy” at 20:00
  • IC Agile at 42:00
  • can’t find tony’s second funny face where he nearly spills the wine, let me know if you find the marker.

Constructive deconstruction of subtyping


Reflection is the programmer’s tool for deconstruction. “Deconstruction”, a modern technique for literary criticism, involves using any available information about a text to help interpret it, even what is not said. Similarly, a programmer using reflection takes advantage of information about the argument passed in, rather than simply using it directly as a value. This poses a threat for type checking and what we typically think of as subtyping.

This paper shows that subtyping cannot be expressed as the binary relation betweem two types, subtype(S, T), (more accurately, Γ |- S<:T), but must be expressed with respect to the range of usage permitted in the operating environment, i.e., subtype(S, T, EP) (or [E]P |- S <: T). Making the environment a first-class entity lets us resolve certain conflicts in the literature. This paper identifies four categories of usage and shows how they resolve some conflicts in subtyping discussions.

The paper in brief

The purpose of this paper is to tie up a loose end. The loose end is that literature on subtyping discusses assertions, “S is a subtype of T” (written S<:T), as if such an assertion can be pronounced true or false for all programs. Most authors assume that, in principle, such an assertion is possible. Formal literature on subtyping carries a symbol, Γ , to denote the “environment” of the typing assertion (so, officially, Γ |- S<:T) . But Γ is defined only over the variables of the environment. The loose end is that Γ should be defined also with respect to the power of the environment, the sorts of activities that can take place against the type, possibly beyond those defined in the types themselves (e.g., reflective operations). I use the letter E to refer to this more general sense of environment.

Without tying up the loose end, we find seemingly conflicting or incorrect assertions in the literature. Reexamining the assertions in the context of the operating environment often sorts out the contradictions. Different authors, offering opposite pronouncements of what is a valid subtype, are merely speaking to different environments.

The simplest environment is one in which only the static representation of the typed item is important, not the operations. The next two differ by whether one or more than one client might be invoking operations on the item at one time. The fourth is the reflective environment, an environment that ruins standard type systems.

The matter is merely a “loose end”, in the sense that most researchers into type systems understand the environment for which they are writing. It is a significant loose end, though. Many researchers really do believe that S<:T can be evaluated once, for all programs. Some programmers give up on the idea of subtyping, because they work in a more powerful environment than their typing system is equipped to handle. And it is difficult to sort out the conflicting messages in the literature.

In this paper, I use two running examples. The first is the old riddle, “Is a circle a subtype of an ellipse?” and the second is, “Is a working person a subtype of a person?” The answer I give is an agressive form of “it depends”:

Those questions cannot be answered as phrased (this should not be a surprise to the reader). They cannot be answered when given the abstract definition of all items. In fact, they cannot be answered even when given concrete implementations in any mathematical or executable language (this should be a surprise to the reader). They cannot be answered except in the context of an interpreting environment, where the usage of the items is known.

What are typing and subtyping?

To get the discussion off the ground, we need to look at the different intents and definitions for typing and subtyping.


For typing, it suffices to scan the literature:

The primary goal of a type system is to ensure language safety by ruling out all untrapped errors in all program runs. [The] declared goal of a type system is usually to ensure good behavior of all programs, by distinguishing between well typed and ill typed programs. [Cardelli]

“A program variable can assume a range of values during the execution of a program. An upper bound of such a range is called a type of the variable.” [Cardelli]

Types are linguistic expressions defined thus: (i) each type-variable is a type (called an atom). (ii) if σ and τ are types, then (σ → τ ) is a type (called a composite type). [Hindley]

1. Atomic types T1, ..., Tn are types
2. If U and V are types, then U x V and U->V are types.
3. The only types (for the time being) are those obtained by ways 1 and 2. [Firard]

A type is the range of significance of a propositional function. [Bertrand Russell, from his doctrine of types, 1903 [Sambin]]

A type is well defined if we understand… what it means to be an object of that type. [Lof, from [Sambin]]

In the terms that will be developed in this paper, Hindley and Firard have restricted themselves to “function application” environments in their definition. The generous and informal definitions of Cardelli and Lof will carry forward to the the reflection-based examples discussed later.


There are two schools of thought as to the purpose of subtyping: substitutability, and safety.

Substitutability: My program behaves the same when I pass in an argument that is declared as a subtype. [programmer A]

Safety: My program, once type-checked, still will not issue any message that is not accepted by its recipient or misintepret any set of bits, even if I substitute subtypes. [programmer B]


The main goal in safety preservation is ensuring that all objects in a system maintain consistent states [Lea]

These two schools are reflected in the technical literature:

What is wanted here is something like the following substitution property: if for every object o1:S there is o2:T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. [Liskov]

An element of a type can be considered an element of any of its supertypes….if a term has type A, and A is a subtype of B, then the term also has type B. [Cardelli] (whose intent is still to detect ill-behavior.)

Different authors have different recommendations as to how to achieve these goals (not all authors state which goal they are after).

Class C is a subtype of a class D, ..., if there is a total map φ : methods© -> methods(D) and a data refinement relation R on c;d such that the theory Γ D of D extends the translation of the theory Γ C of C under φ and R. (...) Initializations and invariants may be strengthened, preconditions weakened and postconditions strengthened, all modulo the refinement relation R. Aliasing is a major problem in preventing modular reasoning about a class… there is no simple solution to this problem. [Lano]

The terms type, subtype and supertype, unqualified, refer to scalar types specifically… T and S are used generically to refer to a pair of types such that S is a subtype of T. Every value in S is also a value in T. Subtypes are subsets. A subtype has a sub set of the values but a super set of the properties. Type inheritance implies (value) substitutability. [Date] (for consistency in this paper, I substitute S for his T’)

From these definitions, we get surprisingly different recommendations as to what actually counts as a valid subtype. Let us take a look at some of the conflicting statements.

The running examples

Is Circle a subtype of Ellipse?

Date says, “yes”, because, “every possible representation for ellipse is – necessarily albeit implicitly – a possible representation of circles, too.” [Date]

According to Lano’s definition, we cannot tell without looking at the actual definitions of Circle and Ellipse. So let us look at two definitions.

Let Ellipse1 support three functions: major, minor, area, which return the length of the major axis, minor axis, and area, respectively. Circle1 has the same operations, but minor and major always return the radius.

For Lano to evaluate the subtyping, we need to construct the data refinement relation R and the mapping of functions φ . In this case, they are trivially established, and so we conclude that Circle1 is a subtype of Ellipse1. According to theory, for every program P, we should be able to happily use an instance of Circle1 as an argument wherever Ellipse1 is declared.

It turns out that this is a wrong belief, as we shall see.

Let Ellipse2 supports two more functions, major(x), minor(x), setting the major and minor axes. Circle2 supports only major(x). The mapping φ cannot be established, quite appropriately, because a Circle2 cannot be asked to change its aspect ratio. Therefore, Circle2 is not a subtype of Ellipse2, according to Lano’s definition.

It turns out that this also is a false belief, as we shall see.

What else?

Is ColoredCircle a subtype of Circle? Suppose ColoredCircle is just like a Circle, but has one more attribute, the color.

Is WorkingPerson a subtype of Person? Working person has additional attributes over Person.

Is 25SecondStoplight a subtype of UnspecifiedDurationStoplight? The UnspecifiedDurationStoplight has an attribute for its times, but no defined value for those attributes. The 25SecondStoplight has those values defined.

Is VariablePolygon a subtype of Polygonal? Suppose a type Polygonal is defined with a number of sides that stays constant over the lifetime of an instance. VariablePolygon is defined so that the number of sides can be changed over the lifetime.

Disagreements about subtypes

Now we encounter the surprises. Lano says that a WorkingPerson is a subtype of Person because it has “new attributes not logically linked to existing attributes”, and of the 25SecondStoplight, “the resulting class is a subtype” of the UnspecifiedDurationStoplight.

But Date disagrees. He consider the code fragment:

Circle c; ColoredCircle cc; c := cc;

and notes that suddenly the variable c has lost some information, the fact that it had a color. After lengthy consideration he writes the surprising sentence, “we find the idea of colored_circle being a subtype of circle somewhat suspect anyway, because it was not defined through specialization by constraint”. He makes the assertion:

...if S is a subtype of T, then subtyping should always be via S[pecialization] by C[onstraint]. ... a value of type T is specialized to type S precisely if it satisfies the constraint P’. Thus we see S[pecialization] by C[onstraint] as the only conceptually valid means of defining shapes. And we reject examples like the one involving COLORED_CIRCLE as a subtype of CIRCLE… [Date], ( again I use S where he uses T’, bold type is his )

I shall put Date’s comments into perspective shortly. For now, let us shift to the second surprise, the idea that VariablePolygon might not be a subtype of Polygonal. We can provide the mapping required by Lano, so what could be the problem?

Lano considers “the aliasing problem”, the situation in which multiple client objects are using the same Polygonal object, and finds object ob:Polygonal to satisfy its specs could observe state changes to ob which were not explicable on the basis of specification if ob was shared with another client who applied the add_edge operation.

The VariablePolygon situation above jeopardizes the safety goal of subtyping as well as substitutability.

I resolve these puzzles shortly. The point for the moment is to illustrate that there is disagreement and some confusion in what seemed to be a simple discussion. The next section takes reflective programming and deconstructionism into account, to take that confusion to its logical extreme.

What’s deconstruction got to do with it?

Deconstruction is to literature what reflection is to programming (using deconstruction to connote a set of related techniques of modern literary criticism). I borrow from the history of deconstructionism to peek ahead at possible futures for reflective programming and type theory, and to construct a safety valve for subtyping.

Jorge Borges presages deconstruction in his fiction, “Pierre Menard, Author of the Quixote”. In this story, the contemporary authors Pierre Menard sets himself the task of writing a story that is letter-by-letter identical to Cervantes’ Don Quixote, but created freshly and totally out of Menard’s personal, artistic experience in 20th century France instead of Cervantes’ in centuries earlier Spain. Borges considers what it means that a piece is thought to be written by someone else, and concludes with the prescient words:

Menard… has enriched … the halting and rudimentary art of reading… This technique, whose applications are infinite, prompt us to go through the Odyssey as if it were posterior to the Aeneid… To attribute Imitatio Christi to Louis Ferdinand Celine or to James Joyce, is this not a sufficient renovation of its tenuous spiritual indications?

Deconstruction is indeed a bottomless technique. The reader is allowed to consider any information at all about the piece, including surmises as to what the author intentionally or accidentally left out. It is always possible to invent something new to relate the piece to.

Similarly, a programmer using reflection can examine any and all information about the arguments being passed in to a function: the name of the class, the language, date of origin, naming style, etc., things that are not normally considered part of formal type definition and subtyping. The client can fiddle with the textual description of the type or class definition itself. This programming trend is happening at the same time that type theorists are tightening the rules of type compliance.

Programmers and type theorists are facing what Bloom and Terjera wrote about literature, in 1975 and 1995:

Literary meaning tends to become more undetermined as even as literary language becomes more over-determined. ...there are… only relationships between texts. These relationships depend upon a critical act, a misreading or misprision, that one poet performs upon another and that does not differ in kind from the necessary critical acts performed by every strong reader upon every text he encounters. [Bloom]

But language as utterance… cannot be fully understood in separation from the human producers and users of it. [Terjera]

A subtype is not a subtype in a reflective environment

The programmer examining the name of the argument, or the definition of the type itself, bypasses the standard mathematics of type theory. If the code contains:

return ( argument.getClass().getName().equals (“T”) );

then nothing else can be a subtype of T, no matter what the Lano mappings are!

Let us consider Circle1 and Ellipse1. It was easy to provide Lano’s mappings, and so we assert

Circle is a subtype of Ellipse, ( Γ |- Circle<:Ellipse )

We then encounter someone’s program, in which is written:

class Client { public boolean useable (Ellipse1 ellipse) { return (ellipse.getClass ().getName ().equals (“Ellipse1”)); } };

Our Circle1, proven to be a legitimate subtype of Ellipse1, cannot be substituted in the above code. In fact, nothing except for Ellipse1 can be substituted in the above code. To put it in the form recommended by this paper,

in the environment of the client code, Ellipse has no subtypes.

If the above code appears in program P, then,

( ¬ [E]P |- Circle1 <: Ellipse1 ).

The type definition has been “deconstructed”. The act of deconstructing it violated the assumptions of usage of the original subtyping assertion.

From a stylistic perspective, we might like to argue that the above code shows “poor coding style”. However, from a mathematical perspective, it is a legal code fragment and must be taken into account by type theory. Further, it is not only legal, but the kind of code that quite a large number of programmers will write. Further still, we can motivate that there are circumstances where similar code is not only good style, but appropriate, natural and desirable.

A growing number of systems are written to take advantage of reflection, often during code development, test, and migration. On one reported project, every class added to the system within the project is given a significant prefix. The migration harness code checks each class’s prefix to decide how to upgrade the class.

In a second example, the reflective Java code below searches all classes for all functions that start with the prefix “test”. They are automatically collected into a test suite, simplifying the life of the programmer.

private boolean isTestMethod( Method m ) {
:: String name= m.getName();
:: Class[] parameters= m.getParameterTypes();
:: Class returnType= m.getReturnType();
::: return
:::: parameters.length == 0 &&
:::: name.startsWith(“test”) &&
:::: returnType.equals(Void.TYPE) &&
:::: Modifier.isPublic(m.getModifiers());

This test-suite generation code illustrates a more refined use of deconstruction, one that “refers to that which it includes”, and, by consequence, also “refers to that which it excludes”, a practice of literary deconstruction:

As an interpretive practice, deconstructive readings follow the motifs or metaphors that govern a text, seeing where they lead and what these motifs exclude, or, as the jargon puts it, “marginalize” or render unimportant in favor of the overt thesis of the text. A deconstructive strategy then reads that excluded component back into the text, demonstrating that the language of the text, practice, or institution must simultaneously refer to that which it excludes. [Nordquist]

Some in the literary world found deconstruction left them with an empty, nihilistic feeling. As literary critics, they saw a loss of control

For deconstructors in philosophy, the multiple meanings are in part generated by the interpreter who reads the text; for the literary critic, the ambiguity is in the text itself and its language, grammar, and rhetorical mechanisms. To the literary critic, the reader/subject is no longer in control of the text/object… [Nordquist] (my italics)

I do not wish to see type theory annihilated, only rebalanced. I take the side of the philosopher in the above quote, not that of the literary critic. The ambiguity of types in not in the text itself, it is generated by the interpreter who reads the text. The subtyping relation is established by the “interpreter who reads the text”, the programmer (or program, depending on how one likes to talk about it). Still, it is not really the case that the type definition has no meaning at all.

For now, it is sufficient to recognize that it is neither practical nor desirable to define “subtyping” as a static relation between two type definitions.


[Deconstruction] is an effort to reverse the ratio of writer to reader. To make the reader larger than the writer. I could say I find this disturbing… Those we call Reconstructionists are urged on by a hard sense of reality asserting itself. [Nason]

If we are not careful, we could end up with years of arguments about whether type definitions actually mean anything. Let’s fast forward the discussions about deconstructionism to see where they ended up. The answer is that one must eventually find some directly intended meaning of the writing.

We do not speak of poems as being… right or wrong. A poem is either weak and forgettable, or strong and so memorable. [Bloom’s Kabbalah and Criticism, quoted in [Nason]]

[Bloom] has brought back value into his assessment of texts, simply replacing such things as “good” and “true” with “weak” and “strong”. In so doing he reintroduces the notions of “good” and “bad” and “true” and “false” into criticism [Nason]

In type definitions, the writing does have intrinsic meaning, but the meaning is not absolute, it varies with the environment of use. It is not sufficient – it is not possible! – to make the blanket assertion: S is a subtype of T. Formally, we cannot hope to prove E |- S<:T, that S can be considered a subtype of T in all environments E, for interesting S and T. The properties of the execution environment matter too much.

Is Circle1 a subtype of Ellipse1? Yes, as long as the client only invokes the declared Ellipse1 functions. No, the subtyping relation is not guaranteed to hold in a reflective environment.

The authors of the Java testing code are counting on their clientele to be at least as smart as the average compiler, to understand and take advantage of their use of function prefixing. They made the prefix part of the (informal) type declaration. Their user community is able to understand the convention, is happy with the labor savings, and they write their test function on the assumption that the code will pick up the ‘test’ prefix.

If reflection breaks subtyping in certain ways, aliasing breaks it in other ways, as we have seen. So the presumed environment of usage is a first-class element of the subtyping relation. It is a necessity to assert: S is a subtype of T in environments E. Formally, that

[E]P |- S<:T

(“S can be considered a subtype of T in all environments E that use operational properties P”).

With this in mind, we consider Lano’s informal definition of a subtype as “a contract stating to any client of the class what behavior can be expected from any instance of any of the new subtypes of this class” [Lano]. This description fits the Java test code example, if we take the programmer as the client.

Four usage envelopes

Let us consider four categories of execution:

R – Static representation only, clients’ access to functionality is not considered.

S – Single-user, user clients access declared functions only.

M – Multi-user, user clients access declared functions only.

F – Reflective usage, user client can access the type definition.

With those four categories in hand, we can clean up the discussions of Colored_circle, Circle and the polygons.

Date and Darwen’s book assumes R usage most of the time. They are primarily concerned with database requirements for elements of the type hierarchy. Under the R conditions, they need not consider what behavior the types might be given. Therefore, value substitutability is sufficient, and behavioral substitutability is not needed. In the R environment, it is even true that Circle2 is a subtype of Ellipse2.

[E]R |- Circle2 <: Ellipse2, or, subtype( Circle2, Ellipse2, r )

Date and Darwen use Colored_circle as a valid subtype of Circle for most of the book. However, in Chapter 14 and Appendix C, they start considering the S category of environments (without explicitly differentiating the environments), and notice that “a certain update operator might be defined for type Rectangle but not for type Square.” Under the new conditions, they announce

It therefore does not seem reasonable to regard type CIRCLE as being a subtype of type ELLIPSE!

What they mean to say, is that

¬ [E]S |- Circle2 <: Ellipse2 ( not (subtype( Circle2, Ellipse2, s ) ))

Discussing Zdonick and Maier’s wish for substitutability, static type checking, mutability, specialization by constraints [Zdonick], they conclude:

inheritance applies to values, not variables.
Thus it seems to us that the key to the problem is to recognize : ...
* The logical difference between The Principle of Value Substitutability and The Principle of Variable Substitutability.

which is their way of separating R and S environments.

In the example of the variable subtype of Polygonal, Lano was interested in subtyping that preserves behavior. As he points out, his substitution mapping works as long as there is only one client using a type instance. A polygon with variable number of sides might be substituted, and the client would be none the wiser, because it would not consider invoking any of the functions of the variable-sided polygon. In other words,

[E]S |- VariablePolygon <: Polygonal

a VariablePolygon is a subtype of Polygonal in an S environment, but

¬ [E]M |- VariablePolygon <: Polygonal

a VariablePolygon is not a subtype of Polygonal in an M environment, because things get difficult with multiple client objects pointing to the same polygon. If one client thinks it has a polygon with constant number of sides, and the other knows of it as a variable-sided polygon, then there is trouble. The second client may change the number of sides and surprise the first. As he writes:

[A]liasing is a major problem in preventing modular reasoning about a class… there is no simple solution to this problem. [Lano]

In terms of this paper, Lano has an workable definition of subtyping for S environments, but not for M environment. Other researchers are working on subtyping in M environments, e.g., [LiskovWing] and [Clark]. In their research, they mention that they are addressing multi-user aliasing, but they do not recognize and separate the different subtyping claims that the different environments permit.

None of the given subtyping definitions work in a reflective environment, as we have seen. The surprise is that, in a reflective environment, we cannot even guarantee substitutability of Circle1 for Ellipse1:

¬ [E]F |- Circle1 <: Ellipse1 (not (subtype( Circle1, Ellipse1, f ) ))

Once the client has the ability to deconstruct the type, it is no longer the case that we can guarantee – without looking directly at the client code – that an instance of S can be substituted for T. In fact, it becomes hard to say just what a type is in the reflective environment.

In many cases, the programmer using reflection is careful to describe and use the reflection consistently, so that the other programmers know what to expect. As Lof wrote,

A type is well defined if we understand… what it means to be an object of that type.

In the Java testing framework, the other programmers understand that test methods are supposed to start with “test”, and write the programs that way. They understand what it means to be an object of that type, fitting Lof’s definition.

Epilog: Local subtypes

It may prove useful to consider “local subtypes”, in order to simplify aspects of program verification. A person checking a program may discover that S is not a subtype of T in the absolute sense previously sought, but is a subtype of T in all the uses in program P. They would prove the weaker, but sufficient assertion:

[E]P |- S <: T

(S passes as a subtype of T in programs P)

That proof might be considerably simpler, and of value in an industrial setting. In an industrial setting, the program set P is likely to change it characteristics over time. Therefore, it may only be practical to carry out the proof if the proof can be done fully automatically, and to make that happen, it may be necessary that the proof is simpler.

Local subtyping can even invert intuitive subtyping (as if they are not being turned upside-down already!). Examining a Queue and a Stack as used in program P, we might demonstrate

[E]P |- Deque <: Stack

(This implementation of Deque passes as a subtype of this implementation of Stack in program P.)

which is the reverse of the usual.


Starting from a deconstructionist view of the view, we saw that

  • Subtyping is not as simple a construct as it might have been thought to be. Trained authors contradict each other and even seem to contradict themselves.
  • The usually announced goal of subtype analysis, to guarantee substitutability without examining the client code, fails in the context of reflective programs. The reflective client can examine everything about the argument passed in to a function, including its name, and even the prefix on the name.

The disagreements between the authors and the damaged goal of substitutability can be resolved by enriching consideration of the environment, making it an intrinsic part of the subtyping relation. Four categories of environment were named:

  • R- the client will make no use of the behavior of the types involved. Data subtyping definitions apply here. For S and T, prove subtype( S, T, r ).
  • S – only one client uses an instance at any one time, and only accesses the declared functions. Standard functional subtyping definitions apply here. For S and T, prove subtype( S, T, s )
  • M- multiple clients may use an instance at any moment, but only access functions declared for that type. Substitutability guarantee is unsolved as yet. For S and T, prove subtype( S, T, m )
  • F – client may use reflection. Substitutability of one type for another cannot be guaranteed, since the client may require the name of the instance to be a particular string. The assertion subtype( S, T, f ) cannot be proved in general.

Placing seemingly contradictory examples into the above categories resolved the contradictions.

Finally, it is possible to consider simplifying substitutability proofs by narrowing the environment of usage to a single program P, and proving only subtype( S, T, P ).


Abadi, M, Cardelli, L., A Theory of Objects, Springer, 1996.

Bloom, H., A Map of Misreading, Oxford U. Press, 1975.

Borges, J., “Pierre Menard, Author of the Quixote”, in Labyrinths, Modern Library, 1983.

Cardelli, L., “Type Systems”, Handbook of Computer Science and Engineering, chapter 103, CRC Press, 1997, also at

Dasenbrock, R., Redrawing the Lines: Analytic Philosophy, Deconstruction, and Literary Theory, U. of Minnesota Press, 1989.

Date, C., Darwen, H, Foundations for Object/Relational Databases, Addison-Wesley, 1998.

Firard, J-Y, Taylor, P., Lafont, Y., Proofs and Types, Cambridge Univ. Press, 1989.

Hindley, J., Basic Simple Type Theory, Cambridge University Press, 1997.

Lano, K., Formal Object-Oriented Development, Springer, 1995.

Lea, D., Concurrent Programming in Java, Addison-Wesley, 1996.

Liskov, B., in “Data Abstraction & Hierarchy”, OOPSLA ‘87.

Liskov & Wing, “Family values: a behavioral notion of subtyping”, Technical Report CMU-DS-93-187, School of Computer Science, Carnegie Mellon University, 1993.

Liskov, B., Wing, J.. “A behavioral notion of subtyping”. ACM TOPLAS, 16(6):1811-1841, November 1994.

Mitchell, J., Foundations for Programming Languages, MIT Press, 1996.

Morningstar, C., “How To Deconstruct Almost Anything”,

Nason, R., Boiled Grass and the Broth of Shoes, McFarland & Company, 1991.

Nordquist, J., Deconstructionism: A Bibliography, Reference and Research Services, 1992.

Sambin and Smith / Loef, 25 Years of Constructive Type Theory

Tehera, V., Lieterature, Criticism, and the Theory of Signs, John Benjamins Publishing, 1995.

Zdonick, S. and Maier, D., “Fundamentals of object-oriented databases”, in Readings in Object-Oriented Database Sys, Zdonick, S. and Maier, D., eds., 1990, Morgan Kaufmann.

Level A Heart of Agile

The Heart of Agile is the idea to clear away for a few minutes all the decorations that have come to surround agile development, and get back to the heart of the matter: Collaborate, Deliver, Reflect, Improve. There is plenty of complexity to deal with, but these four actions capture the heart and the spirit and the way forward.

You can show support for it, and already get started with the progression of the Heart of Agile, by adopting and posting the Level A marker.

Level A stands for “Aspiring”. That means you can already get started by declaring yourself at Level A of the Heart of Agile progression sequence. Simply grab one of these images, the size that suits your needs, and put it as your email footer, or somewhere on your website, as you wish. No further attribution is needed. Just:

“Level A: Heart of Agile” and the picture of your choice:

Level A Heart of Agile badge small.png
Level A Heart of Agile badge smaller.png
Level A Heart of Agile badge medium.png
Level A Heart of Agile badge large.png

(Note: Level B has already started. Level B is for people who have taken a course from an accredited Heart of Agile instructor. Although Level B (for “breathing”) only means that someone attended a 1-3 day class from an accredited instructor, it is still a step forward from Level A. As with Level A, there is no cost associated with being Level B.

Level C will be coming soon.