On 10/31/06, Duncan Coutts<div><span class="gmail_quote"><b class="gmail_sendername"></b> &lt;<a href="mailto:duncan.coutts@worc.ox.ac.uk" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">duncan.coutts@worc.ox.ac.uk
</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
In all this discussion on configurations I think I'm not getting over my main point about why we can't go for the 'easy' option of allowing package 'available' tests everywhere.</blockquote><div><br>&lt;snip&gt;<br></div>


<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">configuration: available(foo &gt;= 2)<br>cpp-options: -Denable_cool_feature</blockquote>


<div><br>I think that everybody already agrees that available(x) should not be allowed in cexp's. You've always been clear about the disadvantages of allowing that. <br><br>My point is that using(x) should not be allowed in cexp's either. I suggestion the following rules, which would eliminate the need for using(x), by allowing a configuration like this:
<br>&nbsp;&nbsp;&nbsp;&nbsp; configuration: using(foo &gt;= x)<br>&nbsp;&nbsp;&nbsp;&nbsp; ....<br>to always be written as:<br>&nbsp;&nbsp;&nbsp;&nbsp; flag: blah<br>&nbsp;&nbsp;&nbsp;&nbsp; default: avalable(foo &gt;= x)<br><br>&nbsp;&nbsp;&nbsp; configuration: blah<br><br><br>1. If Cabal is not given an explicit package version number to use, then it will always choose the latest already-installed version of that package that satisfies the effective Build-depends constraints. This is already how it works right now.
<br><br>2. If Cabal is told to use a specific version of a package (e.g. on the command line), then
available(x) will return false for all versions of that package except for the version that the user requested. If that specifically-requested version fails to satisfy any effective configurations' Build-Depends for that package, then the build stops with an error.
<br><br>
3. If Cabal-get can satisfy a dependency without downloading a
different (usually newer) version of a package, then it will do so.
Otherwise, it will download and installed the latest available
version of the package that satisfies the effective Build-depends in the package
description.<br>
<br>4. The effective Build-depends in the intersection of the main stanza's Build-depends with the Build-depends of all enabled configurations. Effectively, a configuration cannot loosen or remove the dependencies given in the main stanza--a configuration can only restrict the dependencies.
<br><br>&nbsp;&nbsp;&nbsp; Example 1:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 1.0, 2.0, 3.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 2.0<br><br>foo 3.0 is selected because it is the latest available version &gt;= 2.0<br><br>&nbsp;&nbsp;&nbsp; Example 2:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 
1.0, 2.0, 3.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &lt; 2.0<br><br>foo 1.0 is used to build the package, because it is the latest version &lt; 2.0<br><br>&nbsp;&nbsp;&nbsp; Example 3:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 1.0, 2.0, 3.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 
2.0<br><br>&nbsp;&nbsp;&nbsp; Flag: bleeding-edge-features<br>&nbsp;&nbsp;&nbsp; Default: available(foo &gt;= 3.0)<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; configuration: bleeding-edge-features<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 3.0<br>&nbsp;&nbsp;&nbsp; cpp-options: -DBLEED<br><br>(a) Additional user input: use 
foo-2.0 <br>The user did not give the bleeding-edge-features flag, so its default is used. Since the user selected foo-2.0 explicitly, then available(foo &gt;= 3.0) is false (when a specific version is selected, all other versions are made unavailable). Thus, the bleeding-edge-features flag is not enabled automatically, so the corresponding configuration is not used, (no -DBLEED).
<br><br>(b) Additional user input: --bleeding-edge-features, use foo-2.0<br>The user forced the bleeding-edge-features flag, so the corresponding configuration is used. But, that configuration requires foo &gt;= 3.0. The build stops with an error because foo &gt;= 
3.0 is not available due to the &quot;use foo-2.0&quot;.<br><br>&nbsp;&nbsp;&nbsp; Example 4:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 1.0, 2.0, 3.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 2.0<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; Additional user input: none<br>&nbsp;&nbsp;&nbsp; Available for download: 
foo-3.0, foo-4.0<br><br>foo-3.0 will be selected (the latest installed version, &gt;= 2.0)<br>Nothing will be downloaded.<br><br>&nbsp;&nbsp;&nbsp; Example 5:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 1.0, 2.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 3.0
<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; Available for download: foo-3.0, foo-4.0<br>&nbsp;&nbsp;&nbsp; Addtional user input: none<br>
<br>No installed versions of foo satisfy foo &gt;= 3.0<br>If we are using Cabal (not cabal-get), then the build fails with an error.<br>If we are using cabal-get (not just Cabal) then there are two versions of foo available for download that satisfy it. Cabal-get will download and register 
foo-4.0 (the latest version that satisfies the constraint) Then, Cabal will build the package using foo-4.0.<br><br>&nbsp;&nbsp;&nbsp; Example 6:<br>&nbsp;&nbsp;&nbsp; Installed versions of foo: 1.0, 2.0, 3.0<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 2.0<br>&nbsp;&nbsp;&nbsp; Available for download: 
foo-3.0, foo-4.0<br>&nbsp;&nbsp;&nbsp; Addtional user input: use foo-4.0<br><br>Although foo-2.0 and foo-3.0 are installed neither one will satisfy foo &gt;= 3.0 because &quot;use foo-4.0&quot; effectively hides all versions except 4.0. Since 
foo-4.0 is available for download, Cabal-get will download and register it. Then, Cabal will build the package using foo-4.0.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;

 Example 7:<br>&nbsp;&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 2.0<br><br>&nbsp;&nbsp;&nbsp; Flag: use-old-version<br>&nbsp;&nbsp;&nbsp; Default: !available(foo &gt;= 2.0)<br><br>&nbsp;&nbsp;&nbsp; Configuration: use-old-version<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &lt; 2.0<br>&nbsp;&nbsp;&nbsp; cpp-options: -DCOMPAT
<br><br>Here, the user is trying to loosen the dependencies from the main stanza using a flag. But, as I stated in rule 4 above, the build-depends are always taken as intersections. That is, we have (foo &gt;= 2.0) &amp;&amp; (foo &lt; 
2.0) = { }, so the build fails. Notice that Cabal can (and should) determine statically that the Build-depends of the configuration is mutually exclusive with the build-depends of the main stanza and thus issue an error/warning.
<br><br>&nbsp;&nbsp;&nbsp; Example 8:<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 1.0<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; Flag: use-new-version<br>&nbsp;&nbsp;&nbsp; Default: available(foo &gt;= 2.0)<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; #Notice that this stanza is not needed: if availble(foo &gt;= 2.0),<br>&nbsp;&nbsp;&nbsp; #then we are guaranteed to use such a version
<br>&nbsp;&nbsp;&nbsp; #Configuration: use-new-version<br>&nbsp; &nbsp; #Build-depends: foo &gt;= 2.0<br><br>&nbsp;&nbsp;&nbsp; Configuratoin: !use-new-version<br>&nbsp;&nbsp;&nbsp; cpp-options: -DCOMPAT<br><br>This is a reformulation of Example 7 that actually works as intended: If foo &gt;= 
2.0 is not availabe, then we define COMPAT, otherwise, we don't.<br><br>&nbsp;&nbsp;&nbsp; Example 9:<br>&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 2.0<br>
<br>
&nbsp;&nbsp;&nbsp; Flag: use-old-version<br>
&nbsp;&nbsp;&nbsp; Default: !available(foo &gt;= 2.0)<br>
<br>
&nbsp;&nbsp;&nbsp; Configuration: use-old-version<br>
&nbsp;&nbsp;&nbsp; Build-depends: foo &gt;= 1.0<br>
&nbsp;&nbsp;&nbsp; cpp-options: -DCOMPAT<br>
&nbsp;&nbsp; <br>Here is another reformulation of Example 7. Notice that the Build-depends of the main stanza is more restrictive than the build-depends of the configuration. This is a good indication that the user does not understand how Build-depends are combined, so a warning/error should be issued.
<br><br>Regards,<br>Brian<br><br></div></div>