Open ezyang opened 8 years ago
CC @grayjay
What I see that there are three options:
http
curl
curl
and http
Using binary flags, there aren't way to exclude the fourth option. Or at least using build-depends: base<0
would be better way.
base<0
is definitely better, it makes the solver reject the plan, as opposed to just toggling library to be not buildable.
FWIW darcs.cabal has had flags that set the library to buildable: False for quite a while, but now it's started going wrong (only with GHC 8.0 AFAICT) I see the logical fallacy :-)
I will probably drop the -f-http
option entirely from darcs.cabal as it doesn't add much, which will remove this block. Good to know the base<0
trick though, I was looking for some way to explicitly throw an error and failing.
(I hope this isn't excessively flippant...)
A1: Well, what about "^" (aka Xor in most languages)? I mean
Build-depends: curl [range omitted] ^ http [range omitted]
doesn't seem too bad to me? I'm probably missing something.
A2: Make it simpler to state your intent. I think A1 does that to some degree.
EDIT: Anyway, it's an idea, I suppose.
@hsenag Thanks for volunteering to fix this Darcs side!
@BardurArantsson The reason to not do this is historically build-depends is a flat list of dependencies, not an arbitrary logical expression. So adding an xor operator would be quite a forward looking change with major syntax changes.
As for making the intent clearer, see #3526
We've considered adding more direct support for "fail" conditions. This is probably doable but will be much much easier once we replace the parser and the .cabal AST.
There's two related ideas:
explicit failure, with error messages
if !(flag(curl) xor flag(http))
fail: one of curl or http must be used
This is more or less equivalent to the existing tricks to make the solution impossible in some condition, but with more obvious intention and better error messages.
multi-value enum flags
flag transport
values: none, curl, http
default: curl
This is interpreted as an enumeration, and one value must be set.
Then instead of all flags being bools, e.g --constraint=darcs +curl -http
they can be enums --constraint=darcs transport=curl
.
FWIW from the darcs perspective we don't really need either of these - discovering the problem led to us re-evaluating what we really needed. A single boolean flag was actually fine and it makes our code simpler.
It makes sense in principle to have something like these though.
Multi-value enum flags are IMO nicer than explicit failures.
In Darcs, there is some code that looks like this:
I think the intent is to say, "Darcs needs either the curl or http flag to be turned on." But I don't think this is the right way to go about doing it: this says that it is acceptable for Cabal to set curl and http false; the only consequence is the library isn't buildable. If we somehow have a constraint that the library must be buildable, I suppose this has the desired effect if darcs is a dependency (I imagine the solver then requires the library to be buildable), but if you run
cabal configure
there's no reason to enable the library (well, if we want to build the executable there is, but you could also set the executable flag false and now nothing is built.)Question 1: What's the right way to write the logic program that is desired here?
Question 2: How should we document this, and educate users to write logic programs that actually work?
I got this from #3740.