[Development] Proposal: Deprecate QVector in Qt 6

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Thu Apr 23 16:45:02 CEST 2020


On 4/23/20 1:20 PM, Edward Welbourne wrote:
> So how much harm does it really cause, to keep both names; and use
> whichever feels like the more natural description of the value one is
> returning ?

I missing the bigger picture about this thread. What are we trying to 
assess / solve?


== Source compatibility in the presence of QList = QVector (only 
relevant for porting code from Qt 5 to 6)? ==

There are some known breakages [1]. But the example quoted before,

   QList<T> fun();

will still work whether the client code uses QList<T> or QVector<T> to 
store the result. That's why I was asking what that was about.


Similarly,

   QVector<T> fun();

will also allow

   QList<T> l = fun();


Can this cause source incompatibilities? How? How would the proposed 
QVector = QList change things instead?




== API maintenance if QList = QVector: do we mass s/QList/QVector/g in 
our public APIs? ==

I'd be in strong favour of it; it favours consistency and one single 
message.

Please: let's not open the debate about whether it's a good idea to have 
functions that return containers when such containers are not part of 
the object representation (vs: those functions use output iterators, or 
become coroutines, etc., so I can choose the container I want). We have 
those functions around and we need a source compatible solution for them 
in 6.0.

The problem I see with this is the sheer size of the task ahead. I'm not 
sure how much it can be automated. Has anyone tried? Even if some magic 
script fixes everything we may still need manual style touches.

Does it need a C++ parser, or can it be a mass search&replace?

(And even if could build a clang script that does it for Qt itself, what 
about user code which won't compile at all under clang?)

On the positive side, since we're talking about typedefs, this can be 
done incrementally, without any API/ABI compatibility concerns.



If we went the other way around, i.e. QList is the "default" type, like 
proposed: doesn't the task stay fundamentally the same?



== Naming of functions and types if QList = QVector ==

We have QStringList, QVariantList and friends, which are aliases / 
subclasses of QList<QString> and so on.

Should they become QStringVector, QVariantVector; and the *List names 
stay, aliases for the *Vector names, mirroring QList and QVector 
themselves?

I'd say yes, but this has another impact on the API maintenance (we 
should change all of our public APIs to use the *Vector types, for 
consistency).

A broader question is: in the long run, do we want start deprecating all 
the *List names, and leave just the *Vector names? If yes, then 
certainly we have to do the replacements.

As proposed in this thread, if we keep QList and make QVector the alias, 
then we would just leave these datatypes unchanged, and there would be 
no need of introducing the *Vector counterparts.


Functions naming: how many public APIs have a "List" suffix, 
specifically returning a QList? (=> QTextCursor::insertList doesn't count.)

First and foremost, we have a problem of coding guidelines, which demand 
simple pluralization of the entity returned, not "List" suffixing:

* QObject::children, not childList
* QObject::dynamicPropertyNames, not dynamicPropertyNameList
* QSslSocket::sslErrors, not sslErrorList
* QRegularExpressionMatch::capturedTexts, not capturedTextList
* QSslConfiguration::supportedEllipticCurves, not 
supportedEllipticCurveVector (yes, this one returns a QVector)

So the first "go to" solution is: rename the functions, so they follow 
the guideline (keep and deprecate the old name).


Second, would it cause confusion for a function called getFooList() to 
return a QVector? Is "list" used as an abstraction of the return type 
(it doesn't return an object, but a sequence of them), or strictly in 
some sort of Hungarian notation to require that the type returned is a 
QList? (And I mean, specifically _spelled_ QList, even if it's an alias 
to QVector).

I don't have a good answer here.


== Terminology, "list" vs "vector"? ==

Debating whether "vector" is a good term for the respective container is 
only useful for mathematicians and linguists -- in other words, all 
aboard the bikeshedding train!

But: *today*, in 2020, in C++, it represents a very specific and 
well-understood thing. Same for "list". They should cause no 
ambiguities. I cannot stress enough that we shouldn't and cannot 
possibly care about the names in other languages!

(Otherwise, "list" in Python is heterogeneous, why isn't QList 
heterogeneous? Don't we care about developers coming from Python? Repeat 
for any other language out there.)

The major problem in this department has to do with caring that 
something is actually a vector (contiguous in memory, etc.) rather than 
just a sequence implemented "somehow" (... as efficiently as possible, 
this is C++ after all).

In this regard, QList is a bad term for representing a generic sequence 
(because "list" already has a meaning in C++).

I'm not proposing a type-erased sequence type. I'm just thinking: when a 
function returns a QVector, is it because we care about the 
representation? When a function returns a QList, is it because we 
_don't_ care about the representation? (Because, well, it's not a list!).

This strongly favours QVector in the sense that it does what it says on 
the box, whether you care about its actual representation or not; vs. 
QList which says "I'm a list" but somehow implies "you don't care" (and 
actually means "I'm a vector")


== Teachability ==

Builds upon terminology, but surely, deserves its own point.

1) It doesn't help that for years we've said "don't use QList, use 
QVector"; and now in Qt 6 we do the switcharoo and say "use QList, don't 
bother with QVector, it's just an old alias".

It can be managed; "that was about Qt 5 QList, Qt 6 QList is different". 
I'm not sure how many people care about it, to be honest.

2) It doesn't help that it's still called "QList". "Why is Qt not using 
a vector here?" "It is, in fact, a vector" "Then why it's called QList" 
and similar.

3) It doesn't help that 100% of the existing teaching material is still 
targeting Qt 5 (and 4). That material uses QList (and QStringList, etc.) 
and will be around for a long, long time. Using it to learn Qt 6 might 
cause some confusion about what's going on with all the *Vector types 
instead. I still think it can be managed, though.

4) It helps having _one_ "standard" sequential container instead of two 
mixed up all over the place and having to explain pros, cons, 
differences, history, whatnot. Going forward, given the containers will 
be identical, it would help leaving just one around.


====

[1] Major source incompatibilities insofar:

* functions overloaded on both QList/QVector will stop working (easy to 
diagnose, code doesn't compile; easy to fix by dropping the QList 
overload, although for things like logging, what type do you end up 
printing?).

* iterator stability for QList-in-array-of-pointers-mode is gone 
(potentially very hard to diagnose, if it happens rarely; potentially 
intrusive to fix properly).

* object lifetime issues for objects with broken special member 
functions when stored in QList-in-array-of-pointers-mode -- not a bug in 
QList.


My 2 c,
-- 
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4329 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.qt-project.org/pipermail/development/attachments/20200423/52e44f25/attachment-0001.bin>


More information about the Development mailing list