Subject: Re: bug#40549: More usability issues:

From: Tom Zander <[email-masked]>
Date: Tue, 12 May 2020 22:19:22 +0200

On dinsdag 12 mei 2020 20:08:32 CEST zimoun wrote:
> > The design of the short options is that it is an alias. Identical to the
> > software regardless of what the user typed.
> 
> Yes.  But AFAIU, it is hard -- not impossible -- to detect what is an
> argument or what is another option in the case of optional argument in
> the short-name form.  Because it leads to ambiguous parsing.

The solution here is to be consistent with the way that others do this.
For those cases that you highlight the consistent solution elsewhere is 
something you can apply here too. This follows the rule of the least surprise.
 
> And try "cut -f -d' '", it raises the error "cut: invalid field value ‘d ’".

that is because -f has a required argument. As such I agree with your example, 
but ignore it because it is not relevant to our discussion. It is not an 
optional short option.
 
> All short-name and long-name are ``equivalent`` when they do not
> require any argument -- for example with cut: -s, --only-delimited --
> *_or_* they require one argument -- for example: -f, --fields=LIST.

They are expected to always be equivalent. It would not be logical to have the 
short one as an alias if they are not equivalent.

> But there is an ambiguity for optional argument.  How do you detect if
> the argument is provided or not?
> With the long-name, it is done with the character '='.
> For short-name, it is ambiguous.  Imagine that "guix package" has in

The point here is that there exist rules that others use, to remove this 
ambiguity. I'm trying to explain them to you to allow guix to behave the same.
I agree its tricky, the good thing is that it has been solved before.

For instance you can provide an argument to short options without spaces too:
You can write `cut -f1 -d:`.

> addition to '-S' the option '-2' meaning verbosity to level 2
> (--verbosity=2).  Then what is the meaning of:
> 
>   guix package -S -2

If the user meant the "-2" argument to be an argument to the -S option, they 
would have to write (again, following the rules used by most software) as:

echo "test" > -bla
ls -I \-bla

or, to comment on your specific example. In git you don't use the dash to have 
a negative, they use a different char. The tilde. Or dotdotdot. (think: range)
   git show HEAD~
    git diff  ...master

> Is it equivalent to
>   + --switch-generation=-2
> or
>   + --switch-generation --verbose=2

In most software you would interpret any argument that starts with a dash as 
an option. For consistency sake you would thus interpret your example as the 
latter option.
The user can specify what they mean, but preferably you pick your syntax 
better to avoid the -2 in the example you gave :)

> > You asked for an example;  see `git commit -S`. From the manpage:
> >    -S[<keyid>], --gpg-sign[=<keyid>]
> 
> Thank you for the example.   Let me show you that it raises an issue
> too because it is not so "simple". :-)

Easier example then: from the 'ls(1)' manpage:
  -I, --ignore=PATTERN

seems git is trying to be smart.

> > It looks like the parser could be improved by preferring to see any
> > argument with leading dash as a option when it **might** be an argument.
> 
> It does not work for the general case as you describe.  It is not so simple.
> :-) Because '-d -1' means '--delete-generation=-1' and not
> '--delete-generation -1'.

The point is consistency.
The point is not to reinvent the wheel that have been invented so many 
times... A command line parser is a known thing that you can, and should, 
mirror how others do things.

So, sure, "-d -1" does not give you what you want. BUT it is consistent with
--delete -1.
This is the point the exercise. The basic premise is that the short version is 
an alias for the long version.
Yes, you have to be aware of how to format things, how the rules apply. But 
this is the entire point: people should be able to learn it once. And not 
again for guix because we thought something else worked better...

> From my knowledge, all that is solved by the rule: no short option
> with optional argument.

Sure, you can do that.
You'll probably annoy of a lot of people if you remove the thing they 
use a lot :)

Even 'ls' uses optional short arguments (--ignore). So I'm not sure I agree 
with your line of reasoning.

> > So; if you type -`guix package -l --help` then your parser **first** finds
> > all the items with leading dashes and second it tries to find out if
> > there is an argument for the `-l`.
> > In this case I expect the help to be shown.
> > 
> > This is widely seen as a solution.
> > Users can still use items with leading dashes by using two commonly used
> > tricks.
> > The -l=a type of construction allows the argument to be anything.
> > Including it having a leading dash.
> > 
> > Second is the double-dash argument that stops words leading with dashes
> > being parsed as options.
> > 
> >   For instance;   grep -- -v *
> > 
> > the  -v is parsed as an actual string and not an option because it follows
> > the double dashes.
> 
> You miss the point, I believe.
> The issue of *any* parser is only for the "flag" with optional
> argument in their short-name form.
> Because, as I explained above, the syntax for such cases is ambiguous.

I'm going to have to disagree with you: this is software. You can **decide** 
the rule and thus decide the parsing. Making the idea that it is ambiguous 
false. The rules I explained remove the ambiguity. It makes it extremely clear 
what happens.
And that -S -2 example has a very clear behavior.

The point of this bugreport is that my suggestion is that the behavior should 
be changed to follow what most other software does.

Doing;
  ls -I -v
clearly understands that '-v' is not to be used as an optional argument.
The reason, as far as I can tell, is that it does not fit as another argument.

The actual design of the arguments needs a bit of finesse, I agree. The '-d -2' 
example is really not the best UI design.
Avoidance is best.

Yes, usage of 'guix package [option] is stupid because it generates a lot of 
cornercases here.
Ideally it would be guix package list [options].

In general I do agree that your solution of dropping all optional short 
arguments would be the best solution.
They are extremely rare elsewhere.

It would be a bit of a bigger project to make a nice UI without them, though.
Please keep as the hard rule that the short version is an ALIAS to the long 
version.

-- 
Tom Zander