'. '

Blogs:JaroslavTulach:Theory

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(Jaroslav Tulach's Theory Thoughts)
(Jaroslav Tulach's Theory Thoughts)
Line 4: Line 4:
<startFeed />
<startFeed />
 +
 +
==== getDate() method evolution thoughs by Tim Band ====
 +
 +
Imagine that you have a class with method ''getDate()'' which returns the date of creation of that object. Can you add ''setDate()'' in new version? Can that change be compatible? This is topic discussed recently by [http://lambda-the-ultimate.org/node/2950#comment-43612 Tim Band at LtU] discussion forums:
 +
 +
If the get_date function had a comment stating "Returns the date at which the object was created" then you have to update that comment -- and that semantic change to get_date is the break.
 +
 +
It is hard to think of a semantic meaning for a get_date function that covers the setting of an arbitrary date, so let's imagine that we want to add "refresh_date" and that the original documentation of get_date said "Returns some date between the creation of the object and the calling of the function", then adding refresh_date is OK.
 +
 +
If get_date is undocumented or ambiguously documented, you need some process to resolve this. At Symbian we have a board of beard-strokers (of whom I am an occaisional member) who deliberate on the difficult cases and inform the customers of our decisions, and get feedback on certain issues. This process is considered integral to our backwards compatibility promise.
 +
 +
It is tempting to dream of a world where a programming language or supporting infrastructure would free us of the compatibility burden, turning it into just another language feature. However, it is in the mucky world of semantics, where interfaces meet the world of human use and abuse where this stuff really matters. You can break compatibility if you know it won't matter (we once changed our formerly weird floating-point implementation to match IEEE with no-one even noticing), but you can't make some compatible changes (changing priorities of processes that have no stated dependency on each other is a classic).
 +
 +
Having said all that, there is much work to be done on merely keeping interfaces stable. You can get quite far just by assuming that the source interface (your class and function signatures in your .h files in C++) matches the semantics, and picking up incompatible changes to that over time (removal of functions for example) and alterations of the binary interface in relation to the source interface (adding a virtual function for example).
 +
 +
Of course, occasionally you must allow customers to override common sense; I'm sure many readers here are familiar with the story of Microsoft Windows' memory manager running in a different mode if it detected Sim City running -- this is always a risk and you have to be aware that you might be forced to retract changes in the face of politics.
 +
 +
I should probably stop now, although really I'm just getting started!
 +
 +
--[[User:JaroslavTulach|JaroslavTulach]] 07:45, 16 September 2008 (UTC)
==== Joel Neely on Enums in APIs ====
==== Joel Neely on Enums in APIs ====

Revision as of 07:45, 16 September 2008

Contents

Jaroslav Tulach's Theory Thoughts

getDate() method evolution thoughs by Tim Band

Imagine that you have a class with method getDate() which returns the date of creation of that object. Can you add setDate() in new version? Can that change be compatible? This is topic discussed recently by Tim Band at LtU discussion forums:

If the get_date function had a comment stating "Returns the date at which the object was created" then you have to update that comment -- and that semantic change to get_date is the break.

It is hard to think of a semantic meaning for a get_date function that covers the setting of an arbitrary date, so let's imagine that we want to add "refresh_date" and that the original documentation of get_date said "Returns some date between the creation of the object and the calling of the function", then adding refresh_date is OK.

If get_date is undocumented or ambiguously documented, you need some process to resolve this. At Symbian we have a board of beard-strokers (of whom I am an occaisional member) who deliberate on the difficult cases and inform the customers of our decisions, and get feedback on certain issues. This process is considered integral to our backwards compatibility promise.

It is tempting to dream of a world where a programming language or supporting infrastructure would free us of the compatibility burden, turning it into just another language feature. However, it is in the mucky world of semantics, where interfaces meet the world of human use and abuse where this stuff really matters. You can break compatibility if you know it won't matter (we once changed our formerly weird floating-point implementation to match IEEE with no-one even noticing), but you can't make some compatible changes (changing priorities of processes that have no stated dependency on each other is a classic).

Having said all that, there is much work to be done on merely keeping interfaces stable. You can get quite far just by assuming that the source interface (your class and function signatures in your .h files in C++) matches the semantics, and picking up incompatible changes to that over time (removal of functions for example) and alterations of the binary interface in relation to the source interface (adding a virtual function for example).

Of course, occasionally you must allow customers to override common sense; I'm sure many readers here are familiar with the story of Microsoft Windows' memory manager running in a different mode if it detected Sim City running -- this is always a risk and you have to be aware that you might be forced to retract changes in the face of politics.

I should probably stop now, although really I'm just getting started!

--JaroslavTulach 07:45, 16 September 2008 (UTC)

Joel Neely on Enums in APIs

Today I found out that there is an interesting comment to the blog entry published by Andrei a week ago. Andrei shared with us few thoughts on the use of enums in API. Joel Neely noted that it all depends on how the enum is used in the API. I cannot do anything else than agree with his words, yes it depends on whether the enum is used covariantly or contravariantly. If the enum is used covariantly only, then extending it with new constant in new version of the API is OK.

The only problem is that as soon as you publish an enum, one can immediately write a switch statement over it. And the switch statement's behaviour is contravariant. That is no good news for the API writers and compatible extensibility of their enum based APIs...

--JaroslavTulach 21:22, 26 August 2008 (UTC)

Are there any Languages Ready for API Evolution?

When I was describing my API design adventures in TheAPIBook, I could not realize that many of these problems would not even appear if we had better languages, or systems more suitable for the DistributedDevelopment.

I may be wrong, but I do not know about any language that would support modularity. And here I mean not compilation piece by piece, but also modularity in time. Because that is the kind of modularity that is needed quite often during development of APIs for our libraries.

At one point of time we release a version of a library and distribute it to others by publishing it on the website. Now people unknown to us, distributed all around the world download it and use it. As a result, the amount of applications built on top of such library is increasing, which implies also that the amount of bugs and feature requests is growing too. After a while the time to release new version of the library comes. However what if the first version used to have a class:

public abstract class View {
  public abstract String getDisplayName();
}

What if one of the feature requests demands to add an HTML title to each view. Can we change the view class to following form:

public abstract class View {
  public abstract String getDisplayName();
  public abstract String getHTMLTitle();
}

Indeed, this cannot be done. Existing subclasses of View would no longer compile, because the change is not source compatible. Also, even if someone links already compiled subclass with the new version of the library, the Java virtual machine will complain and throw some kind of linkage error, as definition of an abstract super class method is missing.

I would love to see a language or system that would fail the compilation whenever I want to modify my already released classes in a style that could prevent some of their users to continue to use them in previously working way. This would be the real modularity, which is ready for changes in time. So far it seems to me that the current languages do not deal with changes in time really well. Just like Andrei described in his Enums in APIs blog, it seems that our languages do not think about the process of API evolution much and include constructs that one needs to avoid to make DistributedDevelopment possible.

Releasing new version of libraries with modified APIs is really common and our software engineering practices cannot live without it, yet it seems that there is no language in the world that would make this easy and clueless. Or am I wrong?


Also lively discussed at Lambda the Ultimate.

--JaroslavTulach 06:50, 24 August 2008 (UTC)

Visual Aspects of an API

The usual consensus is that visual aspects that are presented just to the end user are not part of API of some application. This is usually well justified and correct, except in some situations...

--JaroslavTulach 11:40, 11 August 2008 (UTC)

Dependencies Are Important Type of API

New type of API has been discovered!

JaroslavTulach 07:05, 15 July 2008 (UTC)

Personal tools
buy