Imho this is a bad pitch. It took me a moment to realize that you have already solved the problem that you're proposing (and the "challenge" is only meant to pitch the solution).
Given the elegance of that very solution I think this marketing stunt is entirely unneeded and actually harmful; it's confusing and you miss out on getting a descriptive headline such as "Generate OptParser from code comment!".
That said... Brilliant idea!
I'm definitely trying out docopt for my next project.
And I have a counter-challenge for you:
How about making docopt work with nested commands? I.e. multiple methods could have a docopt-style comment and they would smartly merge to enable usages such as "mygit remote show --help", where 'show' is a subcommand of 'remote', with its own set of parameters and a matching help-page.
If you can work that one out then docopt could become the defacto standard for generating even complex OptParsers.
I think it's a great pitch, because the pseudo-pitch appeals to exactly the people who would be interested in this. "Ha! I've got this licked, I'll just whip out argparse ... Wait ... Oh!"
For me, your new presentation worked brilliantly. The short while it took me to get what was going on, was exactly what caused me to keep reading. Granted, it is a bit of a bait and switch, but a pleasant one.
I too think the pitch is brilliant - specially when you think about the target audience - folks who get turned on by the word "Challenge", er developers, and most of them must have felt the need for something like this at some point of their life("Some day I'll have to write clean & DRY way ...").
Only thing different might be instead of giving the solution on that page itself - a hyperlink to the solution which takes you to docopt.org landing page
I agree. I thought, interesting challenge, although not interesting enough for me to actually try it. I wonder if he has any example solutions that I could look through. Huh? Ooooh.
If I had just seen it presented straight out as, "Parse arguments based on docstrings," I doubt it would have been nearly as memorable.
But I'd strongly vote for making it possible to annotate multiple functions and merging their respective doc-strings smartly.
I don't think you'd want to express the entire syntax-tree of a reasonably complex program (e.g. 'git') in a single doc-string. Not only would that turn into a mess, but you'd also lose modularity. I.e. subcommands often need to be dynamically generated (e.g. depending on loaded modules) and not all subcommands may be available at all times.
I'm also a fan of idea of using function-docstrings for separate subcommand help-screens. Problems: (1) exact API, (2) how to do that in non-python implementations. You (and everyone) is very welcome to suggest APIs for that in issues:
https://github.com/docopt/docopt/issues
The docopt documentation suggests that a lone "--", signifying the end of the command-line flags, is only supported if "[--]" is added explicitly to the syntax string. In my opinion this is a mistake, and may even break POSIX XBD §12 [1]. I would seriously recommend the authors support it by default.
Ouch, and I implemented https://github.com/andreyvit/dreamopt.js only a few months ago. Similar idea, but yours is better. (Not sure how you deal with type coercion and the like, but I guess it's not too hard to figure out.)
I've found Plac[1] to be a suitably terse and DRY method of building command-line interfaces. Basically, you write a Python function where each argument to the function becomes either an option, flag, or positional argument on the command line. It's one "line" to define the function's arguments (which might be split on multiple lines due to length, but it's just the function's argument list), plus one "line" to annotate each argument with a type, single-letter abbreviation, docstring, etc. (which might be longer than one line if the docstring is extra long). The "type" of an argument is any function that takes a string and returns anything, so you can for example have a function that parses and returns a comma-separated list of numbers as a Python list of floats. I think Plac supports subcommands, but I haven't used it that way.
If you want to see some examples of real-world usage of Plac, here are some examples from my own projects:
Docopt looks like a useful library, but I'd be interested to see how intelligent the "help" parsing is when faced with slight variations in the format.
Using Commons-CLI in Java actually goes the opposite direction and if can be reasonably terse (one line per parameter or option) but it's also got to be wrapped in a class and have the rest of the Java boilerplate (a main method to execute, etc).
When the DSL (http://docopt.org/) was designed, the main goal was just to formalise that pattern-language used for decades in man pages and `--help` screens. So variations that are conventional (such as `UPPER-CASE` for arguments or `<angular-brackets>` for arguments) are supported.
The question, of course, is whether it will scale to more complex cases with more elaborate option documentation (i.e., multiple paragraphs, formatting, short version for usage, extended version for man/html, etc).
For C++ there is the CLI compiler that implements a similar idea (i.e., uses a DSL) but instead of using the usage itself as a specification, it is based on the class-with-members abstraction. While the result is not as terse, it is quite a bit more flexible. Plus it allows you to specify option type (i.e., int, double, string, etc).
From a single interface specification CLI will generate C++ parsers, usage printing code, man pages, and html pages. Here is an example of a real-world interface that is handled with CLI:
Users can't name their ships 'new' or 'shoot' and you can't safely add more 'ship something' commands in new versions as you risk colliding with some user's ship name.
You could try to warn of such conflicts, but that sounds like a lot of work... :)
Very nice! And especially clever that the DSL is the usage help we all know and love. I'm never happy about the amount of code normally required to write these.
One nitpick is that there is still some repetition: "naval_fate", and well as the long options are repeated. Granted, there might be ways around that which I haven't discovered yet.
About long options repeated: you can either specify "[options]" shortcut in a pattern in order not to put all options in that pattern, or you can have all options listed in the pattern--then you can avoid having them in option description.
About repeating program's name (say "naval_fate"), you can do:
If you are looking for something like this for .NET, "synoptic" can generate cli-usage help in a similar format based on your methods/classes complete with defaults, examples etc: https://github.com/bitdiff/synoptic (disclaimer: it's my companies' project)
It should be relatively easy to update it to work with 0.4; if you can make it work with 0.4 it would be great if you make a pull request to the project above.
Given the elegance of that very solution I think this marketing stunt is entirely unneeded and actually harmful; it's confusing and you miss out on getting a descriptive headline such as "Generate OptParser from code comment!".
That said... Brilliant idea!
I'm definitely trying out docopt for my next project.
And I have a counter-challenge for you:
How about making docopt work with nested commands? I.e. multiple methods could have a docopt-style comment and they would smartly merge to enable usages such as "mygit remote show --help", where 'show' is a subcommand of 'remote', with its own set of parameters and a matching help-page.
If you can work that one out then docopt could become the defacto standard for generating even complex OptParsers.