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

Already on GitHub? Sign in to your account

Syntax for setting option to no value in ~/.cabal/config #1053

Closed
dag opened this Issue Oct 3, 2012 · 17 comments

Comments

Projects
None yet
4 participants

dag commented Oct 3, 2012

cabal install -j uses the available cores, figuring it out automatically, but in ~/.cabal/config you have to give it a number explicitly.

Member

23Skidoo commented Oct 20, 2012

This is not that difficult to add if we agree on what the syntax should be for such options. My suggestion: jobs: $DEFAULT.

What do others think?

dag commented Oct 20, 2012

My suggestions:

jobs:
jobs: ""
jobs: -
jobs: True
Owner

tibbe commented Oct 20, 2012

I like $DEFAULT or something that makes it clear what value is being used. @dcoutts thoughts?

@ghost ghost assigned 23Skidoo Nov 17, 2012

Member

23Skidoo commented Nov 18, 2012

I'd really like to extend this to all option types, but it's not obvious how to do it - we don't know what the default value is in all cases.

Owner

tibbe commented Nov 19, 2012

We need to define what we mean by default value. Are they the values defined in Cabal/Distribution/Simple/Setup.hs and cabal-install/Distribution/Client/Setup.hs as defaultFooFlags? Can we always make up a sensible default value (other than NoFlag)? We need a way to look up the default value for any flag, but we don't really have one.

Perhaps we're going about this wrong, if we're only trying to allow users to say that they want parallel builds by default perhaps we should add --parallel (with a default of False, that can be set to True in the config file) and have -j imply --parallel? Do we have any prior art where one flag implies another?

If we add --parallel we could just do fromFlagOrDefault defaultNumJobs (jobs installFlags).

Member

23Skidoo commented Nov 19, 2012

There are two issues here:

  1. Special syntax for setting options with optional arguments to a default value.
  2. The --parallel flag.

Let's decide whether we want 1 first, and then what to do about 2.

Member

23Skidoo commented Nov 19, 2012

We need to define what we mean by default value. Are they the values defined in Cabal/Distribution/Simple/Setup.hs and cabal-install/Distribution/Client/Setup.hs as defaultFooFlags?

For OptArg options, the default value is a part of the definition of the option (see the definition of OptDescr in D.S.Command). For other options, they are defined separately (defaultFooFlags). To communicate the default values to the option parser, we'll have to change the definitions of all options.

Can we always make up a sensible default value (other than NoFlag)?

Defaulting to NoFlag is fine, the problem is mappending two SavedConfigs where the first has foo: bar and the second has foo: $DEFAULT. For OptArg options, this works fine since $DEFAULT is represented as Flag Nothing. For other options, it doesn't work since NoFlag is the unit of the Flag monoid.

To sum up: extending other option types to support $DEFAULT is non-trivial.

Owner

tibbe commented Nov 19, 2012

So does $DEFAULT mean "the actual default value (e.g. a number)" or is another special zero (like mzero, but with another meaning)? The whole thing feels a bit ad-hoc. I'm happy to do it if we can come up with a sensible meaning that is meaningful in the presence of mappend (i.e. it needs to be some sort of monoid).

If we just do --parallel for now, we can postpone this until we have a solid solution.

Member

23Skidoo commented Nov 19, 2012

So does $DEFAULT mean "the actual default value (e.g. a number)" or is another special zero (like mzero, but with another meaning)? The whole thing feels a bit ad-hoc.

It depends on the value given to optArg. In the case of -j, the default value is Flag Nothing, which signals the code to use numberOfProcessors, though I think that we could use numberOfProcessors directly here, since it is a top-level constant.

Member

23Skidoo commented Nov 19, 2012

Defaulting to NoFlag is fine, the problem is mappending two SavedConfigs where the first has foo: bar and the second has foo: $DEFAULT. For OptArg options, this works fine since $DEFAULT is represented as Flag Nothing. For other options, it doesn't work since NoFlag is the unit of the Flag monoid.

One (half-baked) idea for a solution: add a right zero to the Flag monoid:

data Flag a = Flag a | NoFlag | DefaultFlag

where

DefaultFlag `mappend` NoFlag      = DefaultFlag
NoFlag      `mappend` DefaultFlag = DefaultFlag
DefaultFlag `mappend` (Flag f)    = Flag f
(Flag _)    `mappend` DefaultFlag = DefaultFlag

This way, userConfigmappendsandboxConfigmappendcabalConfig will preserve DefaultFlag values from ./cabal.config. We'll also need a method to set the DefaultFlags in the end to the values from defaultFooFlags(no good ideas about how to implement that without adding humongous amounts of boilerplate).

Owner

tibbe commented Nov 19, 2012

This is no longer a monoid though, as

(Flag _)    `mappend` DefaultFlag = DefaultFlag

violates the identity law. You need two separate monoids if you want two identities. We could perhaps achieve the affect we want by wrapping one monoid in another.

I would like @dcoutts opinion before we do something more invasive like this (and hence I suggested the --parallel flag to unblock the current use case we have in time for 1.18).

Member

23Skidoo commented Nov 19, 2012

This is no longer a monoid though, as (Flag _)mappendDefaultFlag = DefaultFlag violates the identity law.

Please correct me if I'm wrong, but that would be the case if DefaultFlag was the monoid's identity (mempty), which it is not. That's why I called it right zero instead of right unit.

I would like @dcoutts opinion before we do something more invasive like this.

Agreed. It's just an idea.

Member

23Skidoo commented Nov 19, 2012

This does violate the identity law, however:

DefaultFlag `mappend` NoFlag      = NoFlag

Should be changed to

DefaultFlag `mappend` NoFlag      = DefaultFlag
Owner

tibbe commented Nov 19, 2012

Please correct me if I'm wrong, but that would be the case if DefaultFlag was the monoid's identity (mempty), which it is not. That's why I called it right zero instead of right unit.

My apologies. I guess it doesn't really make sense to talk about the monoid laws at all here, as this is not a monoid (which can only have one identity).

Member

23Skidoo commented Nov 19, 2012

I guess it doesn't really make sense to talk about the monoid laws at all here, as this is not a monoid (which can only have one identity).

Looks like it is called a monoid with a right absorbing element:
http://en.wikipedia.org/wiki/Absorbing_element

Member

dcoutts commented Dec 13, 2012

See #1142 for a simple solution.

The semantic problem is that --blah lets you have an extra value compared to what you can specify with --blah=X. If we don't allow that, then it's all fine. That is, we say that --blah must be expressible in terms of --blah=X for some X.

The reason it's a problem is that blah: in a config file is supposed to mean the same as if it had not been specified at all, that is mzero, not a default value. What can be expressed with flags is supposed to be the same as with config file, so we must disallow flags that use inexpressible default values.

Owner

tibbe commented Dec 13, 2012

We're doing this: 9926424

@tibbe tibbe closed this Dec 13, 2012

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