What does HackerNews think of cligen?

Nim library to infer/generate command-line-interfaces / option / argument parsing; Docs at

Language: Nim

20 milliseconds? On my 7 year old Linux box, this little Nim program https://github.com/c-blake/bu/blob/main/wsz.nim runs to completion in 109.62 +- 0.17 microseconds when fully statically linked with musl libc on Linux. That's with a stripped environment (with `env -i`). It takes more like 118.1 +- 1.1 microseconds with my usual 54 environment variables. The program only does about 17 system calls total, though.

Additionally, https://github.com/c-blake/cligen makes decent CLI tools a real breeze. If you like some of Go's qualities but the language seems too limited, you might like Nim: https://nim-lang.org. I generally find getting good performance much less of a challenge with Nim, but Nim is undeniably less well known with a smaller ecosystem and less corporate backing.

EDIT: I make only observations here, not demands. Another observation on the same machine is `python-3.11.5

Nim is terse yet general and can be made even more so with effort. E.g., You can gin up a little framework that is even more terse than awk yet statically typed and trivially convertible to run much faster like https://github.com/c-blake/bu/blob/main/doc/rp.md

You can statically introspect code to then generate related/translated ASTs to create nearly frictionless helper facilities like https://github.com/c-blake/cligen .

You can do all of this without any real run-time speed sacrifices, depending upon the level of effort you put in / your expertise. Since it generates C/C++ or Javascript you get all the abilities of backend compilers almost out of the box, like profile-guided-optimization or for JS JIT compilation.

EDIT: There really is much more, as with any system - I was just trying to give a flavor of what appeals to me.

>Does nim have anything as polished and performant as clap and serde?

"Polished" and "high quality" are more subjective/implicitly about adoption, IMO. "Performant" has many dimensions. That said, I just tested the Nim https://github.com/c-blake/cligen vs clap: cligen used 5X less object file space (with all size optimization tweaks enabled in both), 20% less run-time memory for large argument lists, and the same run-time per argument (with march=native equivalents on both, within statistical noise). cligen has many features - "did you mean?/suggestions", color generated help and all that - I do not see obvious feature in clap docs missing in cligen. The Nim binary serde showing is unlikely as good but there are like 10 JSON packages and that seems maybe your primary concern.

More to add color your point than disagree (and follow up on my "adoption") - your ideas about polish, quality, docs, etc. are part of feedback loop(s) you mentioned. More users => Users complain (What is confusing? What is missing? etc.) => things get fixed/cleaned up/improved => More users. Besides "performant" being multi-dimensional, the feedback loop is more of a "cyclic graph". :-) Or maybe this is just a sub-graph of "ecosystem richness". While I probably prefer Nim as much or more as @netbioserror, I am not too shocked by the mindshare capture. It seems to happen every 5..10 years or so in prog.langs.

While many of your points are not invalid, tech is also a highly hype-driven & fad-driven realm. In my experience, the more experience with this meta-feature that someone has, the more skeptical they are of the latest thing (more rounds of regret, etc.). Also, that feedback graph is not a pure good. Things can get too popular too quickly with near permanent consequences. ipv4 got popular so quickly that we are still mostly stuck on it 40 years later as ipv6 struggles for penetration. Whatever your favorite PL is, it may also grow features too fast.

Nim gives a bit more choice in many dimensions than many languages -- how to manage memory, whether to use the stdlib at all for things like hash tables, and yes, also syntactic choices like several ways to call a function. This can actually be convenient in constructing a DSL for something with minimal fuss. While `func arg1 arg2` might look weird in "real" "code", it might look great inside some DSL and you can just have it be a "regular Nim invocation" instead of something special to get that.

There are also compile-time superpowers like macros that just receive a parsed AST. That can be used to "re-parse" or "re-compile" external code as in https://github.com/c-blake/cligen. So, trade-offs like in all of life.

There is even a book called The Paradox Of Choice [1]. I think there is just a spectrum/distribution of human predisposition where some like to have things "standardized & packaged up for them" while others more like to invent their own rules..and enough variation within the population that people have to learn to agree to disagree more. (EDIT: and FWIW, I think this is context-modulated - the same person could be on one end of the spectrum about gardening and the other about software.)

I do feel like the syntax is far less chaotic than Perl.

[1] https://en.wikipedia.org/wiki/The_Paradox_of_Choice

Since `ps` is featuring prominently here, folks might be interested in https://github.com/c-blake/procs which is a color ps (Linux-only right now). It has a more canonical CLI since it is based upon the Nim CLI generator https://github.com/c-blake/cligen. It also uses cligen's subcommand feature (display, find, scrollsys) and so it can replace pgrep, pkill, ps, top, vmstat, etc., etc. Uses the same color scheme as https://github.com/c-blake/lc which re-organizes the mismash ls CLI quite a bit.
If the PL you are using already has named parameters with defaults then you can roll a CLI on top of it with a more well specified "spec" language (the PL itself) and with less work. There are a few Python packages for this and https://github.com/c-blake/cligen (which lets you add a CLI to an existing API with just one line of code).

This is theoretically even possible for C++ with some kind of compile-time reflection API, but the way the C preprocessor works probably makes it hard to preserve structured comments for automatic documentation extraction. It was quite easy to do in Nim.

Nim [1] has cligen [2]. An output binary size for the trivial:

    proc f = discard
    import cligen
    dispatch f
is about 708 KiB on Linux, 621 KiB stripped. And if you like colors, hldiff [3] is not a terrible example.

[1] https://nim-lang.org/

[2] https://github.com/c-blake/cligen

[3] https://github.com/c-blake/hldiff

Sometimes endowing existing syntax with richer semantics requires almost no documentation because things "just work". For example, cligen [1] uses a macro to synthesize an argv parser -> call dispatch CLI system. It could almost have been a template but it needs to loop over parameters more than once (and then grew a lot of features).

Anyway, since Nim has user-defined new operators, using those might also bother some. E.g., there could be a proc `=>` meaning something very different from that sugar module macro of the same name. Really, these work just like other procs modularity-wise. The syntax/grammar does not actually change, though. It's just flexible in the first place.

These complaints sound more like excuses to me. Every language has calls, styles, idioms, etc. you need to learn as a client of whatever it is you're calling/doing. And every language has quirky syntax corners. E.g., many are unaware that C lets you say "(a,b,c,d)" { which evaluates but ignores the result of "a,b,c" }. Yet you still often hear people proclaim how simple C syntax is. "Compared to what?", I guess (e.g. C++).

I do get where you are coming from "overloading"-wise - not just operators, but also regular procs (which in Nim are the same...there is just a proc `<`). When learning an alien language/code-base/libraries it really helps to have jump-to-definition. Nim via nimsuggest has great support for this if you configure your editor (vim, emacs, VisualStudio Code, etc.). You may have skipped that step but might love it more if you did it next time. nimsuggest can be aware of local and global --path modifications and the type context of the jump-to-definition. So, it can do a much better job than, say, ctags. (and yes, nimsuggest works for all the various definition types like macros, templates, etc., even the ones named like an operator such as `<`).

[1] https://github.com/c-blake/cligen

Also, I am not sure what counts as "in production" but on literally a daily basis I use about 15 different command line utilities I wrote in Nim using cligen [1] (EDIT: Really I have written several dozen but only about 15..20 are useful every day). There are always compiler bugs/things to workaround (as with any language), but Nim has been pretty usable for years.

[1] https://github.com/c-blake/cligen

If a little CLI app to do something useful (instead of say, some shell script/batch file or something) is your entry point then you might try cligen [1]. Everyone is different, but from many and varied reports (e.g. in this very thread [2]), it is hugely more probable that you get up & running with some basic skills in like 30 minutes to 4 hours or so with Nim than you would with Rust. Nim really seems to "scale up gracefully" for most.

[1] https://github.com/c-blake/cligen [2] https://news.ycombinator.com/item?id=25596285

Nim is indeed a great answer for this.

Should you want to give that script a nice, traditional CLI then you can do so with very low effort using https://github.com/c-blake/cligen

Should you want "script like" edit-test development cycle ergonomics you can use the TinyCC/tcc backend for compiles in ~200..300 milliseconds. Once it's how you like it you can compile with gcc & -d:danger for max performance in deployment.

func-argparse seems much like https://pypi.org/project/argh/ the inspiration for the Nim https://github.com/c-blake/cligen which can source its "pseudo specification" from either a proc signature or a type/object definition.
I was wondering the same thing. Perhaps he means all the extra "fire::" annotations one needs to put in place in function parameter lists as well as the ultimate dispatcher instatiating cpp macro? Really there is always at least 2.5 with the #include , later macro and annotations.

https://github.com/c-blake/cligen achieves the actual 1-line of code dream without extra annotations and even leveraging existing API documentation and even colorizing said rST docs in terminal generated help output. { Of course, that one line might be an "import cligen; dispatch(foo)" which is arguably denser than most people would format it. } One usually wants to add some per-parameter help, though, unless your parameter names are always much more descriptive than "x" and "y".

I feel like argh and plac preceded/inspired Click.

Also, it's not Python but in Nim there is https://github.com/c-blake/cligen which also does spellcheck/typo suggestions, and allows --kebab-case --camelCase or --snake_case for long options, among other bells & whistles.

Honestly dyson is just something I wrote for myself to see how difficult it would be to write. I don't expect anyone else to use it. The tool is also a punny name, because you'd need to terraform a dyson sphere before you(r apps) can live in it.

I just wanted something with easy templating syntax like this: https://github.com/Xe/within-terraform/blob/master/dyson/src...

The fact that cligen (https://github.com/c-blake/cligen) exists too makes it super easy for me to define subcommands of the thing: https://github.com/Xe/within-terraform/blob/master/dyson/src...

I've been using a similar library in Nim called cligen[0]. Like Fire, it infers the CLI long form/short form switches from the arguments of the function it is linking to. Follow the repo link for examples.

[0]: https://github.com/c-blake/cligen