New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to specify flag A XOR flag B / reject install plan? (from darcs) #3742

Open
ezyang opened this Issue Aug 31, 2016 · 9 comments

Comments

Projects
None yet
6 participants
@ezyang
Contributor

ezyang commented Aug 31, 2016

In Darcs, there is some code that looks like this:

    if (!flag(curl) && !flag(http))
        buildable: False

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.

@ezyang

This comment has been minimized.

Show comment
Hide comment
@ezyang

ezyang Aug 31, 2016

Contributor
Contributor

ezyang commented Aug 31, 2016

@phadej

This comment has been minimized.

Show comment
Hide comment
@phadej

phadej Aug 31, 2016

Collaborator

What I see that there are three options:

  • with http
  • with curl
  • with 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.

Related: #3526

Collaborator

phadej commented Aug 31, 2016

What I see that there are three options:

  • with http
  • with curl
  • with 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.

Related: #3526

@ezyang

This comment has been minimized.

Show comment
Hide comment
@ezyang

ezyang Aug 31, 2016

Contributor

base<0 is definitely better, it makes the solver reject the plan, as opposed to just toggling library to be not buildable.

Contributor

ezyang commented Aug 31, 2016

base<0 is definitely better, it makes the solver reject the plan, as opposed to just toggling library to be not buildable.

@hsenag

This comment has been minimized.

Show comment
Hide comment
@hsenag

hsenag Aug 31, 2016

Member

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.

Member

hsenag commented Aug 31, 2016

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.

@BardurArantsson

This comment has been minimized.

Show comment
Hide comment
@BardurArantsson

BardurArantsson Aug 31, 2016

Collaborator

(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.

Collaborator

BardurArantsson commented Aug 31, 2016

(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.

@ezyang

This comment has been minimized.

Show comment
Hide comment
@ezyang

ezyang Aug 31, 2016

Contributor

@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

Contributor

ezyang commented Aug 31, 2016

@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

@ezyang ezyang added this to the milestone Sep 6, 2016

@dcoutts

This comment has been minimized.

Show comment
Hide comment
@dcoutts

dcoutts Sep 14, 2016

Member

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:

  1. 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.

  2. 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.

Member

dcoutts commented Sep 14, 2016

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:

  1. 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.

  2. 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.

@hsenag

This comment has been minimized.

Show comment
Hide comment
@hsenag

hsenag Sep 14, 2016

Member

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.

Member

hsenag commented Sep 14, 2016

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.

@23Skidoo

This comment has been minimized.

Show comment
Hide comment
@23Skidoo

23Skidoo Sep 15, 2016

Member

Multi-value enum flags are IMO nicer than explicit failures.

Member

23Skidoo commented Sep 15, 2016

Multi-value enum flags are IMO nicer than explicit failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment