extending and reusing cmdargs option specs ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

extending and reusing cmdargs option specs ?

Simon Michael
Hi Neil,

I just spent a day converting hledger from getopt to cmdargs. cmdargs  
feels more high level and featureful and nicer. And yet... I haven't  
reduced the line count that much - nothing like your HLint 3:1 ratio.  
And, I may have made things worse for myself in the reuse/avoiding  
boilerplate department: I'm not sure how to reuse a cmdargs options  
data structure, extending it with a few more options. Using getopt I  
was able to do this without repeating myself (as long as I defined the  
full set of Opt constructors in one place.) I've looked at the more  
advanced cmdargs api, but don't see a way yet - would you have any  
ideas ?

I want this because I have multiple executables (hledger, hledger-vty,  
hledger-web etc.) which should share most (but not all) options. Also,  
I'd like to move a generic subset of report options, without the ui-
specific ones, into hledger-lib for use by all apps.

Also, the hledger executable has multiple commands, so I'd like to  
define a mode for each, but not have to redeclare all the same options  
for each mode - I didn't see how to do that.

As always, thanks a lot for cmdargs!
-Simon

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

wren ng thornton
On 8/8/11 1:59 PM, Simon Michael wrote:
> And, I may have made things worse for myself in the reuse/avoiding
> boilerplate department: I'm not sure how to reuse a cmdargs options data
> structure, extending it with a few more options.

This is a big problem I'm dealing with too lately. In particular, what I
would like is if cmdargs could do flattening of structures, either
automatically or with a new annotation combinator. With this it would be
easy to have a basic FooBar program:

     data FooBar = FooBar
         { foo :: Foo
         , bar :: Bar
         }
         deriving (Data, Typeable,...)

     getFooBarMode :: IO (Mode (CmdArgs FooBar))
     getFooBarMode = ...

and then extend it to a FooBarBaz program:

     data FooBarBaz = FooBarBaz
         { fooBar :: FooBar
         , baz :: Baz
         }
         deriving (Data, Typeable,...)

     getFooBarBazMode :: IO (Mode (CmdArgs FooBarBaz))
     getFooBarBazMode = ...

The big trick is that I should be able to call getFooBarMode from
getFooBarBazMode equivalently to if I had defined,

     data FooBarBaz = FooBarBaz
         { foo :: Foo
         , bar :: Bar
         , baz :: Baz
         }
         deriving (Data, Typeable,...)

and copied over getFooBarMode inline into getFooBarBazMode. The problem
is that the bulk of the code is in the Mode-generating functions, and
it's also the sort of code that's hardest to keep in sync
documentation-wise.

I don't mind the extra indirection in the Mode structures since I don't
actually use them in the program itself; I have an internal
configuration type that I compile the FooBarBaz down to, so that I can
perform additional semantic consistency checks before execution, as well
as precomputing what the commandline arguments dereference into (e.g.,
functions).


> As always, thanks a lot for cmdargs!
> -Simon

Indeed. Aside from this feature request I've been quite pleased :)

--
Live well,
~wren

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

Neil Mitchell
Hi,

You're asking for:
http://code.google.com/p/ndmitchell/issues/detail?id=291 - it's
something I'm already aware of, and what to do at some point.
Unfortunately, it probably won't be anytime in the next few months,
but it will happen eventually.

Thanks, Neil

On Tue, Aug 9, 2011 at 3:08 AM, wren ng thornton <[hidden email]> wrote:

> On 8/8/11 1:59 PM, Simon Michael wrote:
>>
>> And, I may have made things worse for myself in the reuse/avoiding
>> boilerplate department: I'm not sure how to reuse a cmdargs options data
>> structure, extending it with a few more options.
>
> This is a big problem I'm dealing with too lately. In particular, what I
> would like is if cmdargs could do flattening of structures, either
> automatically or with a new annotation combinator. With this it would be
> easy to have a basic FooBar program:
>
>    data FooBar = FooBar
>        { foo :: Foo
>        , bar :: Bar
>        }
>        deriving (Data, Typeable,...)
>
>    getFooBarMode :: IO (Mode (CmdArgs FooBar))
>    getFooBarMode = ...
>
> and then extend it to a FooBarBaz program:
>
>    data FooBarBaz = FooBarBaz
>        { fooBar :: FooBar
>        , baz :: Baz
>        }
>        deriving (Data, Typeable,...)
>
>    getFooBarBazMode :: IO (Mode (CmdArgs FooBarBaz))
>    getFooBarBazMode = ...
>
> The big trick is that I should be able to call getFooBarMode from
> getFooBarBazMode equivalently to if I had defined,
>
>    data FooBarBaz = FooBarBaz
>        { foo :: Foo
>        , bar :: Bar
>        , baz :: Baz
>        }
>        deriving (Data, Typeable,...)
>
> and copied over getFooBarMode inline into getFooBarBazMode. The problem is
> that the bulk of the code is in the Mode-generating functions, and it's also
> the sort of code that's hardest to keep in sync documentation-wise.
>
> I don't mind the extra indirection in the Mode structures since I don't
> actually use them in the program itself; I have an internal configuration
> type that I compile the FooBarBaz down to, so that I can perform additional
> semantic consistency checks before execution, as well as precomputing what
> the commandline arguments dereference into (e.g., functions).
>
>
>> As always, thanks a lot for cmdargs!
>> -Simon
>
> Indeed. Aside from this feature request I've been quite pleased :)
>
> --
> Live well,
> ~wren
>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

wren ng thornton
On 9/11/11 6:11 AM, Neil Mitchell wrote:
> Hi,
>
> You're asking for:
> http://code.google.com/p/ndmitchell/issues/detail?id=291 - it's
> something I'm already aware of, and what to do at some point.
> Unfortunately, it probably won't be anytime in the next few months,
> but it will happen eventually.

Yep, that's the one :)

I'd offer to send a patch, but last time I looked at cmdargs I couldn't
quite figure out how the internal representation all fits together. Do
you have a blog post that talks about the guts of cmdargs rather than
the user-facing side?

--
Live well,
~wren

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

Sebastian Fischer-2
In reply to this post by Simon Michael
Hi Simon,

while it is not possible to reuse the definitions of common fields
themselves, their *descriptions* need to be given only once. Not sure
if you are already sharing descriptions or if it helps you saving a
few more lines. See

    https://github.com/sebfisch/haskell-barchart/blob/v0.1.1.1/src/barchart.hs

for an example of different modes that share most but not all of their
options. IIRC, it works because in the list of exec modes later items
inherit from previous items what they do not define themselves.

Sebastian

On Tue, Aug 9, 2011 at 2:59 AM, Simon Michael <[hidden email]> wrote:

> Hi Neil,
>
> I just spent a day converting hledger from getopt to cmdargs. cmdargs feels
> more high level and featureful and nicer. And yet... I haven't reduced the
> line count that much - nothing like your HLint 3:1 ratio. And, I may have
> made things worse for myself in the reuse/avoiding boilerplate department:
> I'm not sure how to reuse a cmdargs options data structure, extending it
> with a few more options. Using getopt I was able to do this without
> repeating myself (as long as I defined the full set of Opt constructors in
> one place.) I've looked at the more advanced cmdargs api, but don't see a
> way yet - would you have any ideas ?
>
> I want this because I have multiple executables (hledger, hledger-vty,
> hledger-web etc.) which should share most (but not all) options. Also, I'd
> like to move a generic subset of report options, without the ui-specific
> ones, into hledger-lib for use by all apps.
>
> Also, the hledger executable has multiple commands, so I'd like to define a
> mode for each, but not have to redeclare all the same options for each mode
> - I didn't see how to do that.
>
> As always, thanks a lot for cmdargs!
> -Simon
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

Simon Michael
Hi Sebastian,

On Sep 12, 2011, at 4:24 AM, Sebastian Fischer wrote:
   https://github.com/sebfisch/haskell-barchart/blob/v0.1.1.1/src/barchart.hs

for an example of different modes that share most but not all of their
options. IIRC, it works because in the list of exec modes later items
inherit from previous items what they do not define themselves.

Is that because of &= auto ?

I override a default record for each mode as you see at http://joyful.com/darcsden/simon/hledger/hledger/Hledger/Cli/Options.hs#L-49 . At first guess I would say the end result is the same, but maybe not.  Thanks for the example.

-Simon

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: extending and reusing cmdargs option specs ?

Sebastian Fischer-2
Hi Simon,

On Tue, Sep 13, 2011 at 12:13 AM, Simon Michael <[hidden email]> wrote:
> Is that because of &= auto ?

I'm not sure. The feature was added in version 0.2 and is described in
issue 333:

    http://code.google.com/p/ndmitchell/issues/detail?id=333

The description does not mention &= auto.

Sebastian

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe