Skip to content
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

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

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

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

dag opened this issue Oct 3, 2012 · 17 comments
Assignees

Comments

@dag
Copy link

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.

@23Skidoo
Copy link
Member

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
Copy link
Author

dag commented Oct 20, 2012

My suggestions:

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

@tibbe
Copy link
Member

tibbe commented Oct 20, 2012

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

@23Skidoo
Copy link
Member

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.

@tibbe
Copy link
Member

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

@23Skidoo
Copy link
Member

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.

@23Skidoo
Copy link
Member

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.

@tibbe
Copy link
Member

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.

@23Skidoo
Copy link
Member

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.

@23Skidoo
Copy link
Member

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, userConfig mappendsandboxConfigmappend cabalConfig 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).

@tibbe
Copy link
Member

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

@23Skidoo
Copy link
Member

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.

@23Skidoo
Copy link
Member

This does violate the identity law, however:

DefaultFlag `mappend` NoFlag      = NoFlag

Should be changed to

DefaultFlag `mappend` NoFlag      = DefaultFlag

@tibbe
Copy link
Member

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

@23Skidoo
Copy link
Member

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

@dcoutts
Copy link
Contributor

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.

@tibbe
Copy link
Member

tibbe commented Dec 13, 2012

We're doing this: 9926424

@tibbe tibbe closed this as completed Dec 13, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants