emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] (icomplete-vertical-mode): Add support for affixations and,


From: Dmitry Gutov
Subject: Re: [PATCH] (icomplete-vertical-mode): Add support for affixations and, annotations
Date: Wed, 2 Jun 2021 21:29:15 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1

On 02.06.2021 15:59, João Távora wrote:

In terms of usability and speed of these approaches (propertized string
or struct or something else) would be faster than "sometimes string,
sometimes cons, let's just test it here and there and everywhere".

Not necessarily: a struct is extra allocation and extra indirection to get the string. Also could slow down the hot path (the 'all-completions' call).

The cases you are referring to could be solved with a "completions and
some extra info" struct or several, I think. Where one of the fields is
the list of completion strings.

OK, but that's on another level. We do have per-completion properties which
could possibly not be modeled as string properties.  It's much faster
to access say, the completion score for a given company from a slot,
rather than from a text property.  Other less important things could stay in
the string property list (or in a plist of said hypothetical struct,
which should
be about the same in terms of cost).

Another problem with such structs is it encourages "materializing" properties for all completions ahead of time, instead of doing it lazily. Or if we put a function in every its optional slot, that would be both non-obvious and smell of over-engineering.

But speaking of pulling things in the right direction, I think one of
the main troubles on minibuffer.el is a lot of the implicit, untyped
global state. And that change would add to it. The "little md dance", on
the other hand, makes things explicit.

The little md dance is the same.  In the end it relies on global state
as well, unless you thread the whole thing down again.

Everything ultimately relies on the global state, but this way one can trace the logic from the call site to find out how the group function is retrieved. Both alternatives (getting the transformer from the text property and binding group-fun to a dynamic var) rely on "magical" knowledge of sorts, without a comparable handy way to find how the value was computed (Grep will help, of course, but it leaves more opportunity to set the wrong value, or fail to set it in some contexts).

Anyway, I agree with you and that's basically why I prefer keeping
properties of completion objects in the completion object.  I'm not a
fan of the global state either for exactly the reasons you list.

Threading MD, like Stefan suggested later, seems like a good alternative to me.

Which is a fine thing for the
caller to do, but there's no need to make the API less flexible than it
is now.

It wouldn't be less flexible.  Having a "group fun" take a single completion
string and no other args and return its group and a transformer function isn't
less flexible.  Alternatively having a "group fun" take a completion string
and fills in its "group" and "transform" properties is also no less flexible.
And both these options are, IMO, better than having a "group fun" take a
second boolean parameter telling it which of two actions to perform, because
of (yet) unproven performance concerns.  It seems pretty clear that that's
letting  the implementation spill into the API.

Now that I understand it better, I say that your proposal is fine (the first one in the paragraph above, at least), but I (obviously) don't agree that that the current one is as ugly as you paint it. It's also more in line with the current shape of the c-a-p-f API (have a xyz-function return a struct where one of the values if also a function is a bit out there).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]