Chapel: Support argparse-like functionality

Created on 25 Jan 2018  路  10Comments  路  Source: chapel-lang/chapel

Based on Python's Argparse

Chapel supports main() arguments, but does not appear to parse the arguments in any meaningful way. Something like argparse would allow you to do

// oscar.chpl
proc main(args: [] string) {
  var as = parse(args);
  writeln("And the winner is! ", as.winner);
}
./oscar  --winner='Emma Stone'
And the winner is! Emma Stone

Right now, it appears you have to loop over a in args and parse the string, like splitting on =.

Libraries / Modules Feature Request user issue

All 10 comments

Note that if you simply want to parse a --winner flag as above, the simplest option would probably be to use a config const:

// oscar.chpl
config const winner: string;

proc main() {
  writeln("And the winner is! ", winner);
}

But I agree that for those programs that want/need more general / complete argv-style argument parsing, something more than dealing with the array of strings manually would be desirable.

Noted.

If it's more "chapel-like" to use config const that's fine with me. I could use examples of how to halt if something isn't defined and stuff like that. Argparse is pretty mature and has a lot of error catching, etc.

For instance, can I do

// oscar.chpl
config const winner: string;

proc main() {
  if winner == "" {  // Is 'winner' set?
     writeln("But I waited through all the boring speeches and red carpet stuff!");
  } else {
    writeln("And the winner is! ", winner);
  }
}

I suppose I could try this myself, but it seems like the answer might be useful to others, and I'm lazy.

If it's more "chapel-like" to use config const that's fine with me.

I think for flags that config const supports well, that is the more chapeltastic way to do things. It arguably breaks down if you want to have a command line that lists a bunch of filenames (say) as standalone arguments with no flag defining them.

Argparse is pretty mature and has a lot of error catching, etc.

I think what you're saying is "I'm used to argparse and think it's pretty nice" but what I hear on my end is "I want you to do a lot of work to recreate all of that capability and complexity for me and have it integrate with config declarations naturally." So I'm inclined to drag my feet until we come up with some compelling cases where configs and the current features are problematic. I'll mention that my preference for handling more arbitrary arguments would be to have a capability in which modules could register argument parsing handlers that would be invoked automatically in a way that reflected the module use chain to make it more integrated with the language and program structure, but we haven't found the time to pursue that idea yet either.

I've edited your "nobody defined it" case above to make it work (the only change was to replace !winner with winner == ""), and you can do that, yes. Stylistically, I tend to handle such cases closer to their declaration point in order to keep the mainline code cleaner:

// oscar.chpl                                                                   
config const winner: string;
assert(winner!="", "But I waited through all the boring speeches and red carpet stuff!");

proc main() {
  writeln("And the winner is! ", winner);
}

(or if you don't like the assert's output style, you could use a halt):

if winner!="" then halt("But I waited through all the boring speeches and red carpet stuff!");

(or a writeln + exit):

if winner!="" {
  writeln("But I waited through all the boring speeches and red carpet stuff!");
  exit(1);
}

I generally do, e.g.,

const defaultfilename="SomethingUnlikely";
config const infile=defaultfilename;

if infile != defaultfilename {
...
}

But note that if support for multi line string literals are here, one needn鈥檛 be satisfied with argparse, one could write a docopt package...

They are HERE and I'm using them already. Very very useful.

I'm a big fan of argparse, but I agree with Brad that config consts mostly avoid the need for something like argparse.

The only things I find myself missing when I want to write something user-facing are that:

  • It's not easy to attach a help/usage message to a whole program
  • You can't attach a help/info message to individual config consts
  • You can't hide non-user facing config consts from the --help output (all are printed)
  • You can't have short names (or use unambiguous abbreviations) for variables, you have to type the whole thing out

I think most of those are solvable without implementing a full argparse though

  • It's not easy to attach a help/usage message to a whole program
  • You can't attach a help/info message to individual config consts

Somewhat related: #6282

  • You can't hide non-user facing config consts from the --help output (all are printed)

Related: #4973

Even if using config const instead of args, there should be a way to to handle

  • Hey, you didn't give me this constant!
  • Here are your options for this constant:

    • Option A

    • Option B

  • You provided two incompatible flags, idiot.
  • The file you said was there? It wasn't there. I'm using my own default file (as in https://github.com/chapel-lang/chapel/issues/8154)

You can implement each of these by hand, but it's not DRY. Seems like an easy use Constants module or something.

Agreed, those are also useful things that argparse provides. Maybe update the issue message to explicitly list the features of argparse that aren't provided by config consts?

Was this page helpful?
0 / 5 - 0 ratings