I think I set myself up for it, so no apology needed :) Hopefully its alright if I do the same in kind.

> The click example (I use click all the time, by the way) has completely different methods for introducing other constructs or doing custom logic. The F# version just uses lambdas (a sore spot on Python) to do this

Does it? It certainly makes strong use of pre-defined functions, but those are just functions and one can provide your own functions (even lambdas!) instead.

>You seem to think that's bad because of DRY principles and because it's easy to make an error.

Not because its easy to make an error, but because its unnecessarily verbose. Consider some variants on the same invocation, in relatively handwaved python-y, java-y, and f#-y syntax:

@flag('--flag', '-f',
type=validator,
help='a flag description')

f = new Flag().name('flag').short('f')
.validator(aValidator)
.description('a flag description);

type f =
| [<AltCommandLine("-f")>] Flag of validator
with
interface IArgParserTemplate with
member this.Usage =
match this with
| Flag _ -> "a flag description"

This isn't a knock on F# (necessarily), I'm specifically arguing that the API for the flag validator was badly designed. There's no obvious reason that argu should require Usage to be defined by a match block instead of part of the construction of the flag itself. Especially when the IArgParserTemplate interface must be implemented by all flags. They even have a special annotation to opt out of that interface after implementing it, `Hidden`. (This may be a bit ranty, but you can reduce this to "why isn't Description also an annotation"? (at which point you're doing with annotations exactly what Java is doing with method chaining or python with kwargs).

>The same could be done for the F# variant by removing them. That doesn't mean it's a good idea.

My point is that adding newlines is a totally reasonable thing to do if you feel that the python example is overly terse. Its a trivial, straightforward, and often recommended fix.

>I think you misunderstand how this works.

Perhaps I misunderstood. I was responding to the objection that two kwargs had similar names and therefore this was a wart. Such an issue can't be caught at compile time (since the code will be valid either way).

>What am I being "disingenuous" about? Am I engaging with you dishonestly?

Perhaps "unfairly assuming that everyone else is engaging with the same intent that you are" is a better way to put it. I see no signal that the so called "attempt to dismiss it" was such. I think that a much more reasonable way of interpreting it is that "From a cursory analysis, your unsubstantiated claim that F# is obviously superior to python in every way doesn't appear to pan out, can you better substantiate it?" (which they never did).

>Well hopefully this post has helped illustrate some of the considerations that make that comparison more reasonable?

Not particularly. Certainly those are features that might be useful in some contexts, but they're of dubious value in the context of scripting. And the cost is a parsing syntax that is both more verbose and more magical (again, it apparently name-mangles things internally for you just for funsies).

You brought up optparse-applicative, and it looks much more reasonable. In fact, minus haskell's love of inventing extra operators (<>, <$>, <*>), it actually closely resembles what the others are doing (and that the definition of an flag has a semigroup of arguments very closely resembles a set of keyword args for setting flag options). If F# used optparse-applicative, we wouldn't be having this conversation.