
Malcolm Wallace writes:
... so the question here is really about the process for deprecating one existing API and replacing it with a new API. I don't have a solution to this issue. However, it is clear that allocating a new namespace every time an API is improved, is a recipe for confusion amongst users when they search for "the" API without a knowledge of the social history.
Agreed. It seems to me that we do need a way to have multiple versions of an API available, however. We can do this two ways: 1. Use a top-level name 'Old', for old versions of libraries. The contents of Old would mirror the top-level hierarchy, so eg. Old.Control.Monad would be the previous version of the Control.Monad library. This extends nicely to allowing even older versions: Old.Old.Control.Monad :-) 2. Use a suffix instead. For example, Control.Monad.Old would be the previous version, and would import Control.Monad.Trans.Old, etc. (1) means you can retain the structure of the original hierarchy inside Old, and different versions of APIs are completely separate. (2) means less moving around of source files. On balance, think I prefer (1). Cheers, Simon

"Simon Marlow"
It seems to me that we do need a way to have multiple versions of an API available, however. We can do this two ways:
1. Use a top-level name 'Old', for old versions of libraries. 2. Use a suffix instead.
(1) means you can retain the structure of the original hierarchy inside Old, and different versions of APIs are completely separate. (2) means less moving around of source files. On balance, think I prefer (1).
Hmmm, I think (2) also requires every original source file to be moved and renamed. For instance, the file Control/Monad.hs moves into the directory Control/Monad, and is renamed Old.hs, and likewise every X/Y/Z.hs becomes X/Y/Z/Old.hs, so you introduce a new directory for every previous file. The option (1) looks much better from this point of view. Just move the whole directory hierarchy in one go. Also, deprecated imports will also be uniformly recognisable because of "Old." as a prefix on the front of imports, so they line up in a column. As a suffix, ".Old" would tend to disappear in the jagged right-hand edge of the import list, possibly leading to maintenance problems if one gets accidentally overlooked. Regards, Malcolm

There is another more radical suggestion we might want to consider. explicitly versioned interfaces. something like import Control.Monad.2.0 which will match the greatest numbered library which starts with Control.Monad.2. the version numbers being standard major/minor type version numbers for just INTERFACE changes. not internal ones. this would also make forward compatable programs much easier, since older apis can still be exported without interfering with newer ones. Of course, what I would really like is the ability to include by GUID for instance any module with a {-# GUID <foo> optional-export-list... #-} would ALWAYS be available as import GUID.<foo> and would only import those symbols listed in the export list of the GUID pragma. this would solve most all problems as modules just create a new guid and have multiple GUID pragmas for each distinct interface (including their 'past' interfaces) they support. for best results, the export list should support aliasing internally. so you could do things like having these in the same module. {-# GUID dbd159ce980a69ba5008 foo, bar, baz #-} -- new interface {-# GUID 111d5b80771eea99cd7d foo, old_bar as bar #-} -- old interface actually, I would really like to see the GUID thing listed above included in current compilers as an extension (moreso than versioned interfaces) as it could greatly increase the robustness of haskell programs. John On Wed, Jul 30, 2003 at 10:34:25AM +0100, Simon Marlow wrote:
Malcolm Wallace writes:
... so the question here is really about the process for deprecating one existing API and replacing it with a new API. I don't have a solution to this issue. However, it is clear that allocating a new namespace every time a API is improved, is a recipe for confusion amongst users when they search for "the" API without a knowledge of the social history.
Agreed.
It seems to me that we do need a way to have multiple versions of an API available, however. We can do this two ways:
1. Use a top-level name 'Old', for old versions of libraries. The contents of Old would mirror the top-level hierarchy, so eg. Old.Control.Monad would be the previous version of the Control.Monad library. This extends nicely to allowing even older versions: Old.Old.Control.Monad :-)
2. Use a suffix instead. For example, Control.Monad.Old would be the previous version, and would import Control.Monad.Trans.Old, etc.
(1) means you can retain the structure of the original hierarchy inside Old, and different versions of APIs are completely separate. (2) means less moving around of source files. On balance, think I prefer (1).
Cheers, Simon
-- Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@foo.net ---------------------------------------------------------------------------

G'day all. On Wed, Jul 30, 2003 at 03:11:23AM -0700, John Meacham wrote:
There is another more radical suggestion we might want to consider. explicitly versioned interfaces.
I'm pretty wary of explicitly versioned interfaces. Just about every change to a Haskell library is source-incompatible, at least in theory. Something as simple as adding a function can cause a namespace clash with some other module. Adding a typeclass instance can clash with an instance that you declared yourself. Even fixing a bug effectively changes the interface to a library. No, it probably doesn't change the _documented_ interface, but it may well change the interface that you tested your program against. Admittedly these situations are going to be rare given well-written programs and libraries, but that version number may encourage a programmer to think that it can't happen. I think that the argument is different for component-based programming, where one of the criteria is to allow changing vendors of a component or allowing third-parties to write their own "plug ins". For libraries, however, these issues are not so important. For libraries, in fact, what most programmers want is to require the version of some library being used to be greater than or equal to some minimum targeted version. GUIDs seem overkill where a single number would suffice. As always, I'm willing to be persuaded otherwise, but at the moment I can't see the benefit. Cheers, Andrew Bromage
participants (4)
-
Andrew J Bromage
-
John Meacham
-
Malcolm Wallace
-
Simon Marlow