[DEPS][PAPER] Dependencies for Squeak

Stephan Rudlof sr at evolgo.de
Sun Aug 8 18:44:12 UTC 2004


lex at cc.gatech.edu wrote:
>>> First, if I'm not mistaken, your capabilities model seems to boil
>>> down, for each package, to this form:
>>> 
>>> (cap1 AND cap2 AND cap3)  IMPLIES  (cap4 AND cap5) (cap6 AND
>>> cap7)  IMPLIES  (cap8 AND cap9 AND cap10) 
> 
> [...]
> 
>> Yes. But the Caps can be hidden, so that the user asking for
>> installing a package does not see them. And the mechanism allows to
>> express more complex dependencies.
> 
> 
> Well that was my question.  Can you give an example of something more
>  complex than what I showed?

More to this point below.

> 
> 
> 
>>> Do you have any concrete examples where these transformers would
>>> be useful, Stephan?  It would help in thinking about them.
>> 
>> Good question ;-)
>> 
>> In general I want to have a mechanism which *allows* expressing
>> complex dependencies as a backend, without beeing forced to go into
>> nasty technical details in the frontend, at least for expressing
>> simple dependencies.
> 
> 

> You may want to consider this strategy carefully.  If the point is to
>  build a useful system, then you *don't* want it to be able to do 
> absolutely everything.

The core mechanism should be as flexible as possible: therefore you have
to model at a level abstract enough. This also should lead to 'elegant'
concepts:
- no redundancy,
- as less elements as possible,
- well defined,
- good terms (language is important!).

But it should be possible to do complex things with them...

> If your scheme does not support something, but it's something no user
> desires, then the users still do not have to do complicated things in
> the front-end.

1. There is a difference between
- more or less complex backend mechanisms, needed for providing some
functionality, and
- the usage of this functionality in the frontend, beeing as simple as
possible.

2. I'm thinking of making a dependency mechanism not only usable by a
package management system.

> 
> 
> 
>> A concrete example is the possibility to express ORed dependencies
>> via logical Caps in extra Transformation rules: something like I
>> need package SocketStuffFastButRisky in this OR package 
>> SocketStuffSlowButReliable in that version (assumed that both are
>> OK for me). But this is just the tip of the iceberg...
> 
> 
> 

> These examples do not require transformers, and do fit the
> slimmed-down model I described above.  Both of the two socket
> packages can each provide "SocketStuff".

Agreed.
But if this hasn't been expressed in the package version provides, it is
possible to introduce a logical package providing "SocketStuff"
*afterwards* without changing the provides of the original package versions.

> 
> Have you run across an example where a package provides extra
> abilities whenever some other package is around?  I've seen this in
> code a lot -- for example, you can storeString an array iff its
> elements understand storeString -- but I am having trouble thinking
> of an example involving packages.

Also see above.
A simple example: 'MozillaFull' as logical 'package' dependent from the
real packages 'Mozilla_WebBrowser' and 'Mozilla_MailClient'. Could also
be modeled as conditioned provide of one of the real packages, if the
other one exists (but this seems to be more complicated).

> 
> 
> 
> 
>>> One aspect of baking in dependencies into version numbers is that
>>> people may well end up not wanting to use the dependency-accurate
>>> version numbers as their normal version numbers.  If am working
>>> on Chuck II Son of Chuck(y), then I just want version numbers
>>> that go 2.0, 2.1, 2.2, etc., but those will not capture the
>>> dependency information accurately. This makes me wary of
>>> capturing *accurate* dependency information in the versions,
>>> though it may still be that the *intent* of the dependencies can
>>> still be encoded in them.
>> 
>> As Gsran has already written, compatibility code and version number
>> are separated.
> 
> 
> Cool.  The checkboxes he describes sound very easy to use.
> 
> But it does not address the main question I was getting at, that is 
> about *intended* compatibility versus measured compatibility.  If you
>  are willing to drop back to encoding *intended* compatibility, then
> you can greatly simplify your work.  For example, with intended 
> compatibility, you would never need to change the compatibility 
> information retroactively.

It is always 'intended' compatibility what a package maintainer states;
it is a human being!
After thinking a while about the CC (compatibility code) issues, I've
come to the point, that there a good cases, where it makes sense to
change them *afterwards*, and to recompute the CCs for newer versions
(which are depending on the change). See 'compatibility code' Swiki page
  http://minnow.cc.gatech.edu/squeak/3792
for incrementally computing CCs.

> 
> 
> 
> 
>>> Along these lines, note that a conflict can be detected after the
>>>  version number has already been decided.  What happens in that
>>> case?  If the version number only captures intent then there is
>>> no problem.  If it is supposed to be accurate, then that seems
>>> impossible.
>> 
>> There are some ways to go (writing more into this direction at the 
>> 'compatibility codes' Swiki page is in the queue):
>> 
>> 1. a bug would be fixed resulting in a new package release without
>> this conflict, having a new CC: then the package could be
>> installed;
>> 
>> 2. the package wouldn't be changed, but its CC would be corrected
>> (not the *constant* version number): the dependency resolver would
>> avoid it then;
>> 
>> 3. a conflict would be expressed explicitely in the Transformation
>> rules (e.g. if a package maintainer is on holidays).
>> 
>> The last variant is the worst, since it requires extra rules for 
>> describing the exception from the wished behavior.
> 
> 
> 

> Note that in case 1, the dependency information is less specific than
>  the known compatibility information.  The recorded dependency 
> information will not only let people install the new package, but
> they will also allow them to install the old incompatible one.

It depends on how the dependencies will be computed: this may be
dependent on some policy. If you give the CC an important role in this
play the behavior described above is possible.

> 
> 
> In cases 2 and 3, you are fixing the dependency information,

> but it means that people who have the package already installed are
> going to enter a state where their dependencies are not met.

This is alway true, if there is a conflict! Which has been the
assumption for this scenario.

> 
> 
> 
> 
>>> You beat me to it.  For packaging purposes, it gives you a small 
>>> simplification if Chuck1 and Chuck2 are simply different packages
>>> if they are in fact incompatible.  Additionally, putting them in
>>> separate packages means that you can arrange for *both* of them
>>> to be installed simultaneously....
>> 
>> If they don't conflict! One important thing not to forget: that the
>> API is compatible does *not* mean, that the implementation is
>> compatible, too!
> 
> 
> Yes.  It happens sometimes, though.  An example from Debian would be
> the packages "squeak-image3.4" and "squeak-image3.5".  I have
> carefully arranged that these can be installed simultaneously.  All
> my care would have been for naught, however, if I had called them the
> slightly different "squeak-image-3.4" and "squeak-image-3.5", because
> then the installer tool would consider -3.5 to be an upgrade of -3.4.
> 
> 
> In short, it seems helpful to make your theoretical name of "name
> plus first major verion", in fact be the *real* name of the package.

The model in my mind has:
- package name,
- one CC for each version for each compatibility measurement universe,
- constant version numbers.

This shouldn't be put into one name string IMHO.

> 
> 
> 
>>> And anyway, it makes me wonder in a lot of cases if it is not
>>> simpler to *fix* a conflict between two packages and upload a new
>>> version of the package, as opposed to trying to accurately report
>>>  that Chuck 1.28 is incompatible with RB 2.11.
>> 
>> Yes, of course: variant 1. above.

I've read '*fix*' as bug fix here, and made my argument accordingly.

> 
> 
> Be careful not to speak too fast -- I inserted an "easier" in there.
> If you really think that variant 1 is all you need,

I don't think so, as I've written above (describing more variants).
Variant 1 is just the best for a *bug* fix.

> then you will have less work to do because you can just assume people
> will tend to grab newer packages in preference to older ones.dd

> Variant 1 means you can fix dependency problems just like you fix any
> other bugs: you simply release a new version.

This is possible for fixes of *bugs*. If there is e.g. an API
incompatibility: what to fix there?

> 
> 
> 
> 
>> It depends on what you want: if you want to have packages
>> accessible in different versions (for simplicity let's assume
>> different stable versions) and packages requiring different of
>> these stable versions (e.g. they need different APIs) accessible in
>> one catalogue, then the world is not so simple.
> 
> 

> By definition, an auto-installer will *not* want to have everything 
> accessible in one catalog.

Disagreed, as it is written.
Agreed, if you have filters working before and/or with the dependency
resolver and you mean the state *after* filtering. Before filtering
*everything* may be accessible in *one* catalogue.

> An auto-installer should only show those packages which have a good
> chance of being installable, which will typically be a subset.

Agreed.


Greetings
Stephan

> 
> 
> 
> -Lex
> 
> 

-- 
Stephan Rudlof (sr at evolgo.de)
   "Genius doesn't work on an assembly line basis.
    You can't simply say, 'Today I will be brilliant.'"
    -- Kirk, "The Ultimate Computer", stardate 4731.3




More information about the Squeak-dev mailing list