Re: [Development] Converting types in Qt

2014-07-18 Thread Konrad Rosenbaum
On Thursday 17 July 2014 21:31:31 André Pönitz wrote:
 PS: Random side-track question: How comparable are values of type 'int'
 and 'QUrl' if one applies 'common sense'? I even accept answer related
 to non-0 int values only.

The trouble with common sense is that it is not very common in any sense - 
neither do a lot of people have it, nor do the remainder share a common 
vision of it... ;-)

I'll try anyway...

Intuitive answer without a specific use case in mind: they are not 
comparable at all - an int is a completely different beast from a URL.

Answer with weird use cases in mind: the int could represent the path of a 
relative URL. E.g. I could create a cache directory in which I enumerate my 
resources with a simple int counter (cyrus IMAPd does something similar for 
mail storage) and finally express this as a relative URL - as a transient 
conversion int-string-URL.

I could also imagine the int representing the host (IPv4 address) or port of 
the URL, but it gets really weird once you attempt to go there with 
automatic conversions and try to reconcile the result with RFC3986.

In short: an int is just too ambiguous in relation to a URL to justify an 
automatic conversion.



Konrad
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Ziller Eike

On Jul 16, 2014, at 1:45 PM, Poenitz Andre andre.poen...@digia.com wrote:

 Olivier Goffart wrote:
 Jędrzej Nowacki wrote:
 [...]
 What is wrong with string - int or bytearray - int?
 
 At the very least, _implicit_ conversions should not lose data,
 i.e. a  A a1;  B b = a1; A a2 = b; round trip ideally should yield
 a1 == a2.
 
 If I am ready to give up information, I'd like to need to say so
 in the code explicitly. (And yes, part of the deed is done in the
 core language, but even there compilers start to nag about it.)
 
 André, QVariant conversions are not implicit, they are explicit.
 
 I am aware of that. I tried to answer the question of What is wrong 
 with string - int or bytearray - int”. 

QVariant::operator== is not symmetric :( :( :(

 QDateTime dateTime = QDateTime::currentDateTime();
QTime time = dateTime.time();

qDebug()  (QVariant(dateTime) == QVariant(time));
qDebug()  (QVariant(time) == QVariant(dateTime));

--
false
true

 We admittedly left the original context here (and in other parts of the 
 discussion), but the question was posed in context that I read an 
 example of an conversion that one would always consider convenient
 to have, and I started with At the very least, _implicit.. supposedly 
 setting the context of the answer.
 
 Anyway. To summarize my position in the original context: QVariant 
 is as it is. It is convenient at times, and it is already too convenient 
 at times. Easy type conversion is a different use case than Type 
 agnostic storage. QVariant does a bit of both, only the second one
 has ever been useful _to me_, I have been bitten by the first. As 
 there are typically also more direct ways to convert types than to 
 pass through QVariant, I consider the possibility to do type conversion
 through QVariant a mis-feature, and adding even more conversion 
 abilities would be a step into the wrong direction _for me_. This is 
 a personal opinion.
 
 Andre'

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
 
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Tuula Haataja
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Jędrzej Nowacki
On Thursday 17 of July 2014 10:51:03 you wrote:
 QVariant::operator== is not symmetric
 
  QDateTime dateTime = QDateTime::currentDateTime();
 QTime time = dateTime.time();
 
 qDebug()  (QVariant(dateTime) == QVariant(time));
 qDebug()  (QVariant(time) == QVariant(dateTime));
 
 --
 false
 true

We could make it symmetric, if you want. My recommendation is to not use the 
comparison at all. If you want more features of QVariant you can look into 
isNull() this is a perfect randomizer :P. The whole discussion took wrong 
direction. I didn't want to discuss QVariant API, which is not fixable, even 
Qt6 would not help, to much staff depends on it. 

Jędrek
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Daniel Teske
On Thursday 17 Jul 2014 13:28:10 Jędrzej Nowacki wrote:
 On Thursday 17 of July 2014 10:51:03 you wrote:
  QVariant::operator== is not symmetric
  
   QDateTime dateTime = QDateTime::currentDateTime();
  
  QTime time = dateTime.time();
  
  qDebug()  (QVariant(dateTime) == QVariant(time));
  qDebug()  (QVariant(time) == QVariant(dateTime));
  
  --
  false
  true
 
 We could make it symmetric, if you want. 
A equals operator that is not symetric is broken. Such a class cannot be 
reliably used in std nor qt containers. Or do you know which way around, 
QList::contains uses the equals operation?

daniel
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Olivier Goffart
On Thursday 17 July 2014 13:33:49 Daniel Teske wrote:
 A equals operator that is not symetric is broken. Such a class cannot be
 reliably used in std nor qt containers. Or do you know which way around,
 QList::contains uses the equals operation?

Note that none of the class which have a member operator== is symmetric.
Most of the class had an operator== as a member in Qt4 but that was a design 
mistake.  New classes should have a friend operator== instead.

Example:

qDebug()  (QUrl() == QString());  // true
qDebug()  (QString() == QUrl());  // compilation error


That's because QUrl has a 
 bool QUrl::operator==(const QUrl);
Instead of
 bool operator==(const QUrl , const QUrl);

The later is symmetric, but the former is not.

This is also valid for operator and related.

(That was just to go a bit more out of topic :-))


-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Jędrzej Nowacki
On Thursday 17 of July 2014 13:33:49 Daniel Teske wrote:
 On Thursday 17 Jul 2014 13:28:10 Jędrzej Nowacki wrote:
  On Thursday 17 of July 2014 10:51:03 you wrote:
   QVariant::operator== is not symmetric
   
QDateTime dateTime = QDateTime::currentDateTime();
   
   QTime time = dateTime.time();
   
   qDebug()  (QVariant(dateTime) == QVariant(time));
   qDebug()  (QVariant(time) == QVariant(dateTime));
   
   --
   false
   true
  
  We could make it symmetric, if you want.
 
 A equals operator that is not symetric is broken. Such a class cannot be
 reliably used in std nor qt containers. Or do you know which way around,
 QList::contains uses the equals operation?

The example above shows what happens in case of a missing conversion, in this 
case QTime can be converted to QDateTime, but the QDateTime can not be 
converted to the QTime. Fail.

The operator was / is / will be broken. Even if we make it symmetric, it will 
remain conceptually broken. It should compare QVariants and then (maybe) the 
wrapped value, while currently it tries a fuzzy comparison of the wrapped 
value only.  It should look more or less like that:

bool operator ==(const QVariant left, const QVariant right)
{
return left.userType() == right.userType()  
!QMetaType::compare(left.constData(), rigth.constData(), left.userType());
}

To make it more ridiculous, currently it would not work as QMetType::compare 
do not know about built-in types :P

There are few ways to fix it, sorted from the smallest impact on a user code 
base to a-bomb size:
- Add conversion QDateTime - QTime (Up to now only Olivier agreed with me 
that it is ok to add a new conversions)
- If two QVaraints are not equal we can check if swapping left and right sides 
helps. Inefficient, another behavior change and as odd as the current behavior. 
Nothing to gain really.
- Always compare QVariants twice left to right and right to left. Terribly 
inefficient, more sensible output. Big behavior change as most of comparison 
would return false.
- Allow comparisons of the same types or if there is explicitly registered 
comparisons otherwise return false. Completely different behavior then the 
current one.
- Do not allow QVariant comparison, we can not support custom types if they do 
not register conversion anyway so why bother.

Cheers,
  Jędrek
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Ziller Eike

On Jul 17, 2014, at 2:38 PM, Jędrzej Nowacki jedrzej.nowa...@digia.com wrote:

 On Thursday 17 of July 2014 13:33:49 Daniel Teske wrote:
 On Thursday 17 Jul 2014 13:28:10 Jędrzej Nowacki wrote:
 On Thursday 17 of July 2014 10:51:03 you wrote:
 QVariant::operator== is not symmetric
 
 QDateTime dateTime = QDateTime::currentDateTime();
 
QTime time = dateTime.time();
 
qDebug()  (QVariant(dateTime) == QVariant(time));
qDebug()  (QVariant(time) == QVariant(dateTime));
 
 --
 false
 true
 
 We could make it symmetric, if you want.
 
 A equals operator that is not symetric is broken. Such a class cannot be
 reliably used in std nor qt containers. Or do you know which way around,
 QList::contains uses the equals operation?
 
 The example above shows what happens in case of a missing conversion, in this 
 case QTime can be converted to QDateTime, but the QDateTime can not be 
 converted to the QTime. Fail.

Actually, adding a conversion QTime - QDateTime wouldn’t help, because that 
conversion cannot “invent” the correct missing date information.
So, QVariant(dateTime) == QVariant(time) would still fail, because the date of 
the datetime that is created when converting time-datetime will not be the 
same as the original datetime.
In the presence of lossy conversions, you need to do conversions in both 
directions to make operator== symmetric.

 
 The operator was / is / will be broken. Even if we make it symmetric, it will 
 remain conceptually broken. It should compare QVariants and then (maybe) the 
 wrapped value, while currently it tries a fuzzy comparison of the wrapped 
 value only.  It should look more or less like that:
 
 bool operator ==(const QVariant left, const QVariant right)
 {
   return left.userType() == right.userType()  
 !QMetaType::compare(left.constData(), rigth.constData(), left.userType());
 }
 
 To make it more ridiculous, currently it would not work as QMetType::compare 
 do not know about built-in types :P
 
 There are few ways to fix it, sorted from the smallest impact on a user code 
 base to a-bomb size:
 - Add conversion QDateTime - QTime (Up to now only Olivier agreed with me 
 that it is ok to add a new conversions)
 - If two QVaraints are not equal we can check if swapping left and right 
 sides 
 helps. Inefficient, another behavior change and as odd as the current 
 behavior. 
 Nothing to gain really.
 - Always compare QVariants twice left to right and right to left. Terribly 
 inefficient, more sensible output. Big behavior change as most of comparison 
 would return false.
 - Allow comparisons of the same types or if there is explicitly registered 
 comparisons otherwise return false. Completely different behavior then the 
 current one.
 - Do not allow QVariant comparison, we can not support custom types if they 
 do 
 not register conversion anyway so why bother.
 
 Cheers,
  Jędrek
 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
 
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Tuula Haataja
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread Ziller Eike

On Jul 17, 2014, at 1:28 PM, Jędrzej Nowacki jedrzej.nowa...@digia.com wrote:

 On Thursday 17 of July 2014 10:51:03 you wrote:
 QVariant::operator== is not symmetric
 
 QDateTime dateTime = QDateTime::currentDateTime();
QTime time = dateTime.time();
 
qDebug()  (QVariant(dateTime) == QVariant(time));
qDebug()  (QVariant(time) == QVariant(dateTime));
 
 --
 false
 true
 
 We could make it symmetric, if you want. My recommendation is to not use the 
 comparison at all. If you want more features of QVariant you can look into 
 isNull() this is a perfect randomizer :P.


 The whole discussion took wrong 
 direction. I didn't want to discuss QVariant API, which is not fixable, even 
 Qt6 would not help, to much staff depends on it. 

Well, the discussion is still sort of the same (and sort of not). The original 
question was, if we can/should add new type conversions, and/or which kind of 
conversions these could be. I think the investigations here about the API and 
workings of QVariant give some hints on what an answer to that might be.
There is no need to expose the brokenness of the API even more by adding 
conversions that trigger it.

operator== would be less bad if there were only symmetric and lossless 
conversions, so do not introduce any additional lossy or asymmetric conversions.
Also, the uses of QVariant::toString (fromString), that we have found in Qt 
Creator ((de)serialization of QVariantMaps), definitely break if this 
conversion is *not* lossless (or not symmetric).

int - long” kind of conversions might be sort of ok-ish, since the actual 
conversion can still fail if the long doesn’t fit into int, i.e. for values 
that actually fit into both types the conversion is lossless, for values that 
do not fit into both types, the conversion fails in one direction, and is not 
possible to start with in the other direction.
Since this can only be found out during runtime, I’d try to avoid that though, 
and definitely not put that into the extreme.

I would avoid conversions between containers that do not have the exact same 
type. QLinkedListT  =  QVectorT” maybe, “QLinkedListint  =  
QVectorlong” ... no.

Do not add conversions that do not have a “canonical way” to do it, and which 
do not have a corresponding toXXX function without parameters in the 
corresponding types.
The exception to the “canonical way rule *might* be toString/fromString 
conversions, because of its usefulness. There is no canonical way to convert 
bool - string, but it might be useful for things like (de)serialization. (I’m 
not very convinced of toString conversion being very useful in the MVC context, 
actually, except maybe for quick-hack-debugging. For production you should be 
in better control of what you show to your user. I’m only half-convinced about 
its usefulness for (de)serialization.) Taking QString out of the rule has the 
disadvantage that it makes it harder if you actually want to hold string “data” 
in your variant (for which you would want saner conversion rules).

Br, Eike

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
 
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Tuula Haataja
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread André Pönitz
On Thu, Jul 17, 2014 at 02:36:22PM +0200, Olivier Goffart wrote:
 On Thursday 17 July 2014 13:33:49 Daniel Teske wrote:
  A equals operator that is not symetric is broken. Such a class cannot be
  reliably used in std nor qt containers. Or do you know which way around,
  QList::contains uses the equals operation?
 
 Note that none of the class which have a member operator== is symmetric.
 Most of the class had an operator== as a member in Qt4 but that was a design 
 mistake.  New classes should have a friend operator== instead.
 
 Example:
 
 qDebug()  (QUrl() == QString());  // true
 qDebug()  (QString() == QUrl());  // compilation error
 
 
 That's because QUrl has a 

because is the bigger half of a red herring here.

  bool QUrl::operator==(const QUrl);
 Instead of
  bool operator==(const QUrl , const QUrl);
 
 The later is symmetric, but the former is not.

The fact that the former is asymmetric is indeed not nice, already for
esthetic reasons. But the fact that it actually _hurts_ is only due to the
non-explicit QUrl(const QString url, ParsingMode mode = TolerantMode)
constructor.

If that is not available, e.g. after #define QT_NO_URL_CAST_FROM_STRING,
neither version compiles. That's symmetric, and good.

 This is also valid for operator and related.
 
 (That was just to go a bit more out of topic :-))

We are still on track. The topic is free type conversion cause trouble,
or Why there shouldn't be more type conversions through QVariant.

Andre'


PS: Random side-track question: How comparable are values of type 'int'
and 'QUrl' if one applies 'common sense'? I even accept answer related
to non-0 int values only.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-17 Thread André Pönitz
On Thu, Jul 17, 2014 at 02:38:40PM +0200, Jędrzej Nowacki wrote:
 On Thursday 17 of July 2014 13:33:49 Daniel Teske wrote:
  On Thursday 17 Jul 2014 13:28:10 Jędrzej Nowacki wrote:
   On Thursday 17 of July 2014 10:51:03 you wrote:
QVariant::operator== is not symmetric

 QDateTime dateTime = QDateTime::currentDateTime();

QTime time = dateTime.time();

qDebug()  (QVariant(dateTime) == QVariant(time));
qDebug()  (QVariant(time) == QVariant(dateTime));

--
false
true
   
   We could make it symmetric, if you want.
  
  A equals operator that is not symetric is broken. Such a class cannot be
  reliably used in std nor qt containers. Or do you know which way around,
  QList::contains uses the equals operation?
 
 The example above shows what happens in case of a missing conversion, in this 
 case QTime can be converted to QDateTime, but the QDateTime can not be 
 converted to the QTime. Fail.

The broad problem here is _too many_ conversions. In this case specifically
the QDate-to-QDateTime conversion.

 The operator was / is / will be broken. Even if we make it symmetric, it will 
 remain conceptually broken. It should compare QVariants and then (maybe) the 
 wrapped value, while currently it tries a fuzzy comparison of the wrapped 
 value only.  It should look more or less like that:

It does not have to remain broken. The only reason to not fix it 
right now are compatibility promises.

A trivial solution (and one of the few correct ones) is to consider
QVariants as equal if and only if they have identical type and their
typed values are the same, according to a (proper) equivalence relation
set up for this type.

Of course one can come up with more elaborate schemes to set up 
equivalency classes like putting all integral type into one bucket.
Some might even make sense. What won't work are chains of conversions
int - QChar - QString - QStringList without a direct conversion 
from int to QStringList.

 There are few ways to fix it, sorted from the smallest impact on a user code 
 base to a-bomb size:
 - Add conversion QDateTime - QTime (Up to now only Olivier agreed with me 
 that it is ok to add a new conversions)

Not acceptable. This loses precision, and consequently can't be made
transitive, i.e. there will be objects a, b, and c such that a == b, b == c,
with a != c.

 - If two QVaraints are not equal we can check if swapping left and right 
 sides 
 helps. Inefficient, another behavior change and as odd as the current 
 behavior. 
 Nothing to gain really.

Not acceptable. Albeit ths would solve the symmetry problem, the
transitivity problem remains.

 - Always compare QVariants twice left to right and right to left. Terribly 
 inefficient, more sensible output. Big behavior change as most of comparison 
 would return false.

Not acceptable. The ransitivity problem remains. We are looking in the
right direction, though: Things are less often equal than it appears to be
convienient.

 - Allow comparisons of the same types or if there is explicitly registered 
 comparisons otherwise return false. Completely different behavior then the 
 current one.

[*] Acceptable for Qt 6 (and for Qt 5 as opt-in, due to the changed behaviour)
if and only if the explicitly registered comparison functions don't
violate any of the symmetricy/transitive/reflexive requirements.

 - Do not allow QVariant comparison, we can not support custom types if they 
 do 
 not register conversion anyway so why bother.

Acceptable for Qt 6 (and for Qt 5 as opt-in, due to the changed behaviour),
but overshooting. QVariants of the same type with usable comparison for
that type are perfectly comparable.


The solution is [*].

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Ziller Eike

On Jul 15, 2014, at 7:36 PM, Olivier Goffart oliv...@woboq.com wrote:

 On Tuesday 15 July 2014 10:38:52 Poenitz Andre wrote:
 Olivier Goffart wrote:
 Jędrzej Nowacki wrote:
  1. Are we allowed to add new conversions?
 
 The question is tricky because adding a new conversion is a
 behavior
 change, as this code:
 if (variant.canConvert(QMetaType::int)) ...
 may work differently. If we add custom types into the mix,
 everything
 
 is even more complex.
 
 I'd say yes, for sensible conversion
 You are right that it is a behaviour change, but i think it is worth
 changing it.
 Why?
 
 On one hand you promise binary compatibility. On the other hand
 behaviour changes are proposed to be done on an nice to have
 base?
 
 Do we really think that's ok to disallow changing some int foo() { return
 42; } to some int bar() { return 42; } that's easy to discover at build
 time, but it's fine to change int foo() { return 42; } to int foo() {
 return -1; } ?
 
 It's always a dilemma. We have to look at how likely we are to break 
 applications and I don't think adding a conversion is likely to cause 
 breakages.
 
 so Qt can know it and use it. For certain types we can do much better,
 
 because we can automatically convert some types. For example:
 QVectorchar - QLinkedListint
 
 QVectorchar v; v.append(130);
 QLinkedListint l = /*someSensibleAutomatedConversion*/(v);
 
 assert(l.first() == 130) ?  Depends ?
 
 QVariant(char(130)).toInt() already exists. You may argue that it is not 
 sensible but that's another issue.
 I guess the example is more between QVectorT1 - QLinkedListT2 when there 
 exist a conversion from T1 to T2
 
 A conversion may be arbitrary. For example, most of the
 conversions
 
 to QString. Should bool(false) - QString return False, 0,
 false?
 What about precision of, for example, double - QString ?
 
 We use common sense on a case by case basic.
 
 I tend to believe the common sense in type conversion land is pretty
 close to avoid to do it automatically, prefer to make it explicit.
 
 Already now it's far too easy to make mistakes based on the nice
 and easy QByteArray - QVariant - QString conversions when
 accidentally writing QByteArrays into QSettings and reading QStrings
 back. There shouldn't be more of that.
 
 What's the mistake here? Wrong encoding? Bad performances?

wrong values  unexpected results

 When one use QVariant, it is because we want to enjoy dynamic typing and nice 
 conversions.

I don’t think we have a single place in Qt Creator where we want automatic 
conversions when using QVariant. A search for QVariant(Map) returns 5400 hits.
In the map case, we usually expect the one retrieving the value for a key to 
know the exact type of what was thrown in (that’s usually the same class, or 
related classes), and then we use item models and QSettings which we use in the 
same way.

Even if automatic conversion might be interesting (when, actually?), then the 
point is:

There is no API in QVariant to support the common use case of getting the value 
*without* automatic conversion.

 We use common sense on a case by case basic.


Either there is no “common sense” common to me, or this rule has failed in the 
past already ;)

bool - string ?
bytearray - int/long/double ?
keysequence - int ?
string - bool ?
string - bytearray ?
string - int ?

Br, Eike

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B 

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Tuesday 15 of July 2014 11:59:03 Olivier Goffart wrote:
   1.3 Should we try to support a user's type conversions out of the
 box? 
   Currently a user needs to manually register a conversion function
 
  so Qt can know it and use it. For certain types we can do much better,
 
  because we can automatically convert some types. For example:
   QVectorchar - QLinkedListint
   QListFoo - QVectorFoo
   QPointerFoo - QObject*
   QPointerFoo - void*
   QSharedDataPointerFoo - bool
   MyQObject* - QPointerMyQObject
   Currently we are not doing it for one reason which is behavior
 
  compatibility. What if a user already defined a conversion that we want to
  add? It could happen because the conversion was not available in a
  previous
  Qt version. The problem is that the new conversion function may behave in
  a
  different way, especially in edge cases and because of the lack of
  perfection mentioned in 1.2. We need to pick only one function. That could
  be the Qt version, but then we risk that an existing code will not work
  anymore. Are we willing to accept that?
 
   I believe that we should document the problem, and allow the
 
  conversions.
 
 I think we could try to automatically do conversion when we know how to do
 it.  And if there is an user defined conversion, it overrides the automatic
 one.

We could implement overriding, but we would not control which conversion is 
registered first / last. Moreover it would mean that a conversion could change 
at any point. I think it would be a bit too nondeterministic.

Cheers,
  Jędrek
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Tuesday 15 of July 2014 10:38:52 Poenitz Andre wrote:
 Olivier Goffart wrote:
  Jędrzej Nowacki wrote:
 1. Are we allowed to add new conversions?
 
The question is tricky because adding a new conversion is a
behavior
change, as this code:
if (variant.canConvert(QMetaType::int)) ...
may work differently. If we add custom types into the mix,
everything
   
   is even more complex.
  
  I'd say yes, for sensible conversion
  You are right that it is a behaviour change, but i think it is worth
  changing it.
 Why?
 
 On one hand you promise binary compatibility. On the other hand
 behaviour changes are proposed to be done on an nice to have
 base?
 
 Do we really think that's ok to disallow changing some int foo() { return
 42; } to some int bar() { return 42; } that's easy to discover at build
 time, but it's fine to change int foo() { return 42; } to int foo() {
 return -1; } ?

Yes. Because there are two separate issues here. One is that the build time 
sometimes doesn't exist, and you do not want to break an application that had 
no opportunity to rebuild. Second is that I'm not talking about abstract foo 
or bar function. I was explicit what would change, it would be Qt answer for 
a simply question could you convert this value to this type. I guess in most 
cases the question would be placed in a context: could you convert this value 
to this type, because I know only how to handle the type and not any other. 
In my opinion it is good to answer the question with yes.

  so Qt can know it and use it. For certain types we can do much better,
  
  because we can automatically convert some types. For example:
   QVectorchar - QLinkedListint
 
 QVectorchar v; v.append(130);
 QLinkedListint l = /*someSensibleAutomatedConversion*/(v);
 
 assert(l.first() == 130) ?  Depends ?

Invalid code = undefined output. You can simplify the example to:
 QVectorchar v; v.append(130);
 assert(v.first() == 130) ?  Depends ?
The issue has nothing to do with a magic conversion. You can blame C++ 
standard, which doesn't specify if char is signed or not, or people that write 
such code. I guess both options are valid :-)

A conversion may be arbitrary. For example, most of the
conversions
   
   to QString. Should bool(false) - QString return False, 0,
   false?
   What about precision of, for example, double - QString ?
  
  We use common sense on a case by case basic.
 
 I tend to believe the common sense in type conversion land is pretty
 close to avoid to do it automatically, prefer to make it explicit.

You are right, it is good to avoid it, but sometimes it is not possible 
especially, if you do not control full stack.

 Already now it's far too easy to make mistakes based on the nice
 and easy QByteArray - QVariant - QString conversions when
 accidentally writing QByteArrays into QSettings and reading QStrings
 back. There shouldn't be more of that.

 Andre'
 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Poenitz Andre
Olivier Goffart wrote:
   I'd say yes, for sensible conversion
   You are right that it is a behaviour change, but i think it is worth
   changing it.
  Why?
 
  On one hand you promise binary compatibility. On the other hand
  behaviour changes are proposed to be done on an nice to have
  base?
 
  Do we really think that's ok to disallow changing some int foo() { return
  42; } to some int bar() { return 42; } that's easy to discover at build
  time, but it's fine to change int foo() { return 42; } to int foo() {
  return -1; } ?
 
 It's always a dilemma. We have to look at how likely we are to break
 applications and I don't think adding a conversion is likely to cause
 breakages.

Type safety is a safety net that catches errors very early in the
software production and deployment cycle, and one of the features 
that makes a programming language usable for the development 
of large applications at a reasonable pace.

Implicit type conversions kill type safety. This is widely recognized 
as a bad thing. In case of C++ some are unavoidable due to the 
C legacy, but e.g. for user-defined conversion operators we now got
explicit, _because_ people learned the hard way that implicit 
conversions are causing more trouble than wanted.

[...]
   We use common sense on a case by case basic.
 
  I tend to believe the common sense in type conversion land is pretty
  close to avoid to do it automatically, prefer to make it explicit.
 
  Already now it's far too easy to make mistakes based on the nice
  and easy QByteArray - QVariant - QString conversions when
  accidentally writing QByteArrays into QSettings and reading QStrings
  back. There shouldn't be more of that.
 
 What's the mistake here? Wrong encoding? Bad performances?

Wrong encodings under circumstances that are typically not present on 
the developers or test machines. Here the lack of type safety postpones
a problem that would be immediately visible (and fixable) at compile time, 
to the time after the application has been shipped.

In the best case this only causes a bug report that needs to be handled
normally, i.e. needs triaging/fixing/integration (and hopefully is not so 
critical to require an immediate emergency release, but can be delivered 
with the next regular one). Worst case this could mean that the application 
is unusable in a larger part of the world. With or without someone reporting
the problem.

This is a kind of convenience I don't need, and I pretty much prefer
the inconvenience of having to spell out type conversions explicitly.

 When one use QVariant, it is because we want to enjoy dynamic typing 
 and nice conversions.

I wholeheartedly disagree. Most of my QVariant uses are there because 
the Qt API requires me to use it, and I sometimes use it voluntarily for 
type-agnostic storage or transport of things. But in those cases I never 
want to extract anything else from the variant than exactly the thing 
I put into it. 

I _never_ (at least not intentionally) use QVariant as a kind of magic 
converter bag where I put something in and get something 
conveniently munged back.

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Olivier Goffart
On Wednesday 16 July 2014 08:41:07 Poenitz Andre wrote:
 I wholeheartedly disagree. Most of my QVariant uses are there because
 the Qt API requires me to use it, and I sometimes use it voluntarily for
 type-agnostic storage or transport of things. But in those cases I never
 want to extract anything else from the variant than exactly the thing
 I put into it.

So if I understand you and Eike correctly, what you want is some kind of

templatetypename T T qvariant_cast_safe(const QVariant v) {
Q_ASSERT(v.userType() == qMetaTypeIdT())
return *reinterpret_castconst T *(v.constData());
}

 I _never_ (at least not intentionally) use QVariant as a kind of magic
 converter bag where I put something in and get something
 conveniently munged back.

When you play with qml or itemview, it's cool that there is a 
QVariant::toString()  that puts some string out in order to show to the user 
what's in it.

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Wednesday 16 of July 2014 06:37:25 Ziller Eike wrote:
  [...]
  When one use QVariant, it is because we want to enjoy dynamic typing and
  nice  conversions.
 
 
 I don’t think we have a single place in Qt Creator where we want automatic
 conversions when using QVariant. A search for QVariant(Map) returns 5400
 hits. In the map case, we usually expect the one retrieving the value for
 a key to know the exact type of what was thrown in (that’s usually the same
 class, or related classes), and then we use item models and QSettings which
 we use in the same way. 
 Even if automatic conversion might be interesting (when, actually?), then
 the point is:
 
 There is no API in QVariant to support the common use case of getting the
 value *without* automatic conversion.

Nobody asked for it, It should be easy to implement something equal to this;

 Q_ASSUME(variant.userType() == qMetaTypeTargetType()); 
 TargetType data = variant.valueTargetType();

I believe such new api make sense, we can add it.

 
  We use common sense on a case by case basic.
 
 
 
 Either there is no “common sense” common to me, or this rule has failed in
 the past already ;)
 
 bool - string ?
 bytearray - int/long/double ?
 keysequence - int ?
 string - bool ?
 string - bytearray ?
 string - int ?
 
 Br, Eike

What is wrong with string - int or bytearray - int?

 -- 
 Eike Ziller, Senior Software Engineer - Digia, Qt
 Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
 Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
 Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg,
 HRB 144331 B 
 
 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development


___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Wednesday 16 of July 2014 08:41:07 Poenitz Andre wrote:
 Olivier Goffart wrote:
I'd say yes, for sensible conversion
You are right that it is a behaviour change, but i think it is worth
changing it.
   
   Why?
   
   On one hand you promise binary compatibility. On the other hand
   behaviour changes are proposed to be done on an nice to have
   base?
   
   Do we really think that's ok to disallow changing some int foo() {
   return
   42; } to some int bar() { return 42; } that's easy to discover at build
   time, but it's fine to change int foo() { return 42; } to int foo() {
   return -1; } ?
  
  It's always a dilemma. We have to look at how likely we are to break
  applications and I don't think adding a conversion is likely to cause
  breakages.
 
 Type safety is a safety net that catches errors very early in the
 software production and deployment cycle, and one of the features
 that makes a programming language usable for the development
 of large applications at a reasonable pace.
 
 Implicit type conversions kill type safety. This is widely recognized
 as a bad thing. In case of C++ some are unavoidable due to the
 C legacy, but e.g. for user-defined conversion operators we now got
 explicit, _because_ people learned the hard way that implicit
 conversions are causing more trouble than wanted.

That is a controversial statement. There is many languages, that doesn't offer 
strict type safety and they are fine. Let's no go into this discussion because 
it would lead us nowhere.

 [...]
 
We use common sense on a case by case basic.
   
   I tend to believe the common sense in type conversion land is pretty
   close to avoid to do it automatically, prefer to make it explicit.
   
   Already now it's far too easy to make mistakes based on the nice
   and easy QByteArray - QVariant - QString conversions when
   accidentally writing QByteArrays into QSettings and reading QStrings
   back. There shouldn't be more of that.
  
  What's the mistake here? Wrong encoding? Bad performances?
 
 Wrong encodings under circumstances that are typically not present on
 the developers or test machines. Here the lack of type safety postpones
 a problem that would be immediately visible (and fixable) at compile time,
 to the time after the application has been shipped.
 
 In the best case this only causes a bug report that needs to be handled
 normally, i.e. needs triaging/fixing/integration (and hopefully is not so
 critical to require an immediate emergency release, but can be delivered
 with the next regular one). Worst case this could mean that the application
 is unusable in a larger part of the world. With or without someone reporting
 the problem.
 
 This is a kind of convenience I don't need, and I pretty much prefer
 the inconvenience of having to spell out type conversions explicitly.

In this particular case I would blame QSettings API, which pretends that is 
able to handle everything while it is not. 

  When one use QVariant, it is because we want to enjoy dynamic typing
  and nice conversions.
 
 I wholeheartedly disagree. Most of my QVariant uses are there because
 the Qt API requires me to use it, and I sometimes use it voluntarily for
 type-agnostic storage or transport of things. But in those cases I never
 want to extract anything else from the variant than exactly the thing
 I put into it.
 
 I _never_ (at least not intentionally) use QVariant as a kind of magic
 converter bag where I put something in and get something
 conveniently munged back.

Actually I agree, I believe that QVariant should be just a stupid container 
which allows you to transfer a data in type agnostic way, from one place to 
another. Well, during it lifetime it accumulated a bit of additional 
functionality, but I see that the discussion is floating in wrong direction. 
Let's not talk about implicit QVariant conversions, we have them and we can 
not remove them. We can add, as Olivier suggested qvariant_type_safe_cast to 
our API. Let's talk about QMetaType::convert and 
QmetaType::hasRegisteredConverterFunction,  instead are we allowed to change 
their behavior by adding / modifying conversions ?

Jędrek

 Andre'
 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Poenitz Andre
Olivier Goffart:
 Poenitz Andre wrote:
  I wholeheartedly disagree. Most of my QVariant uses are there because
  the Qt API requires me to use it, and I sometimes use it voluntarily for
  type-agnostic storage or transport of things. But in those cases I never
  want to extract anything else from the variant than exactly the thing
  I put into it.
 
 So if I understand you and Eike correctly, what you want is some kind of
 
 templatetypename T T qvariant_cast_safe(const QVariant v) {
 Q_ASSERT(v.userType() == qMetaTypeIdT())
 return *reinterpret_castconst T *(v.constData());
 }

This would alleviate the environment dependency of the problem, 
i.e. presumably increase the probability that the issue is caught in 
local testing. (Of course, a real compile-time check i.e. something
that would also catch errors in code paths that are not executed during 
testing would be preferable, but that's not achievable in this setup)

 I _never_ (at least not intentionally) use QVariant as a kind of magic
 converter bag where I put something in and get something
 conveniently munged back.

  When you play with qml or itemview, it's cool that there is a
  QVariant::toString()  that puts some string out in order to show 
  to the user what's in it.

That's a one-way route for a specific purpose, pretty much like
qPrintable(). There's nothing wrong with a .toDisplay() (or similar)
function, but that's don't think this is the kind of type conversion
that triggered this thread.

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Konrad Rosenbaum
On Wednesday 16 July 2014 08:41:07 Poenitz Andre wrote:
 Olivier Goffart wrote:
  It's always a dilemma. We have to look at how likely we are to break
  applications and I don't think adding a conversion is likely to cause
  breakages.
 
 Type safety is a safety net that catches errors very early in the
 software production and deployment cycle, and one of the features
 that makes a programming language usable for the development
 of large applications at a reasonable pace.

I feel I need to clear up some misconceptions here: the kind of type safety 
offered by C++ is a possibility, but not a necessity for fast and safe 
development of large applications. I've done Smalltalk for quite some time - 
it does not have a static type system like C++ and development is still 
faster than in most C++ based environments - I'd even go as far as saying it 
is slightly faster to develop with Smalltalk than it is to develop with Qt 
(I still prefer Qt for its more modern API). The key is usually great 
documentation, good tooling, good APIs and fast turn-around from adding a 
few lines to seeing them in action (in the last point C++ can't even hope to 
compete with Smalltalk, the other three are quite good with Qt).

 Implicit type conversions kill type safety. This is widely recognized
 as a bad thing. In case of C++ some are unavoidable due to the
 C legacy, but e.g. for user-defined conversion operators we now got
 explicit, _because_ people learned the hard way that implicit
 conversions are causing more trouble than wanted.

Let's not mix up too much here: type conversions are necessitated by the 
fact that C++ has static typing - otherwise you would not get much done with 
it - from the Smalltalk point of view C++ is not polymorphic. Implicit type 
conversions are necessitated by the fact that programmers (like me) are lazy 
bastards and don't like to read lines which are longer than a couple of 
words.

The explicit keyword is just a way of telling the compiler that a 
constructor is NOT a type conversion - however, I'm not entirely sure 
whether it was such a brilliant idea to have two kinds of implicit user 
defined conversion (constructors and type operators). 

So, just get used to the idea of prefixing each constructor with an 
explicit and only consider removing it again afterwards.

 This is a kind of convenience I don't need, and I pretty much prefer
 the inconvenience of having to spell out type conversions explicitly.

Reminds me of the early days of Java - almost every cast was explicit and 
you wrote endless lines of casts just to get a very simple resource.

Thanks, but no thanks.

In short: you need a certain amount of convenience to not hinder the 
programmer. Too much magic in the background and it is just as bad. The 
difficulty seems to be to define the ideal point between convenience and 
shooting yourself into the foot all the time.

As long as QVariant mirrors the abilities of C++ (i.e. only using implicit 
conversions that are also available in plain C++, plus maybe a few very 
obvious ones, like toString) we are fine. More and we'll get weird bug 
reports, less and programmers will constantly bitch about it.

BTW: you can already implicitly cast QByteArray-QString, so why not allow 
it through QVariant?


Konrad
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Poenitz Andre
Jędrzej Nowacki wrote:
 Eike wrote:
  [...]
  We use common sense on a case by case basic.
 
  Either there is no “common sense” common to me, or this rule has failed in
  the past already ;)
  bool - string ?
  bytearray - int/long/double ?
  keysequence - int ?
  string - bool ?
  string - bytearray ?
  string - int ?
 
 What is wrong with string - int or bytearray - int?

At the very least, _implicit_ conversions should not lose data,
i.e. a  A a1;  B b = a1; A a2 = b; round trip ideally should yield 
a1 == a2.

If I am ready to give up information, I'd like to need to say so 
in the code explicitly. (And yes, part of the deed is done in the
core language, but even there compilers start to nag about it.)

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Ziller Eike

On Jul 16, 2014, at 11:28 AM, Jędrzej Nowacki jedrzej.nowa...@digia.com wrote:

 On Wednesday 16 of July 2014 06:37:25 Ziller Eike wrote:
 [...]
 When one use QVariant, it is because we want to enjoy dynamic typing and
 nice  conversions.
 
 
 I don’t think we have a single place in Qt Creator where we want automatic
 conversions when using QVariant. A search for QVariant(Map) returns 5400
 hits. In the map case, we usually expect the one retrieving the value for
 a key to know the exact type of what was thrown in (that’s usually the same
 class, or related classes), and then we use item models and QSettings which
 we use in the same way. 
 Even if automatic conversion might be interesting (when, actually?), then
 the point is:
 
 There is no API in QVariant to support the common use case of getting the
 value *without* automatic conversion.
 
 Nobody asked for it, It should be easy to implement something equal to this;
 
 Q_ASSUME(variant.userType() == qMetaTypeTargetType()); 
 TargetType data = variant.valueTargetType();
 
 I believe such new api make sense, we can add it.
 
 
 We use common sense on a case by case basic.
 
 
 
 Either there is no “common sense” common to me, or this rule has failed in
 the past already ;)
 
 bool - string ?
 bytearray - int/long/double ?
 keysequence - int ?
 string - bool ?
 string - bytearray ?
 string - int ?
 
 Br, Eike
 
 What is wrong with string - int or bytearray - int?

First of all I wondered what bytearray - int does at all. Convert the first 
byte in the byte array to an int, if bytearray.size() == 1 (which would be 
consistent with QStringList-QString)?
bytearrays are not strings after all…

Otherwise bytearray/string - int has similar problems as string - bool and 
string - bytearray:
There is no canonical “right” way to do it, and it can fail depending on the 
actual *value*. Does QVariant::canConvert actually take that into account? Is 
there any other possibility to find out if it went wrong? Does it interpret 
0xa1 ? Will 076 be interpreted as octal or decimal?
Does it convert “ퟷ” (U+1D7F7) to 1 ? ;)
All in all it creates more questions than it solves problems.

There are no QKeySequence::toInt(), QString::toBool(), QString::toByteArray() 
functions btw, and QString/QByteArray::toInt(…) take arguments. I think one 
prerequisite for possible conversions (automatic or not) should be, that a 
corresponding ::to… function without any arguments in the corresponding type 
would survive an API review, and actually is added as well. Then one also has a 
place to look for documentation how the actual conversion is done.

Br, Eike

 -- 
 Eike Ziller, Senior Software Engineer - Digia, Qt
 Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
 Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
 Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg,
 HRB 144331 B 
 
 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B 

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Ziller Eike

On Jul 16, 2014, at 11:58 AM, Konrad Rosenbaum kon...@silmor.de wrote:

 On Wednesday 16 July 2014 08:41:07 Poenitz Andre wrote:
 Olivier Goffart wrote:
 It's always a dilemma. We have to look at how likely we are to break
 applications and I don't think adding a conversion is likely to cause
 breakages.
 
 Type safety is a safety net that catches errors very early in the
 software production and deployment cycle, and one of the features
 that makes a programming language usable for the development
 of large applications at a reasonable pace.
 
 I feel I need to clear up some misconceptions here: the kind of type safety 
 offered by C++ is a possibility, but not a necessity for fast and safe 
 development of large applications. I've done Smalltalk for quite some time - 
 it does not have a static type system like C++ and development is still 
 faster than in most C++ based environments - I'd even go as far as saying it 
 is slightly faster to develop with Smalltalk than it is to develop with Qt 
 (I still prefer Qt for its more modern API). The key is usually great 
 documentation, good tooling, good APIs and fast turn-around from adding a 
 few lines to seeing them in action (in the last point C++ can't even hope to 
 compete with Smalltalk, the other three are quite good with Qt).
 
 Implicit type conversions kill type safety. This is widely recognized
 as a bad thing. In case of C++ some are unavoidable due to the
 C legacy, but e.g. for user-defined conversion operators we now got
 explicit, _because_ people learned the hard way that implicit
 conversions are causing more trouble than wanted.
 
 Let's not mix up too much here: type conversions are necessitated by the 
 fact that C++ has static typing - otherwise you would not get much done with 
 it - from the Smalltalk point of view C++ is not polymorphic. Implicit type 
 conversions are necessitated by the fact that programmers (like me) are lazy 
 bastards and don't like to read lines which are longer than a couple of 
 words.
 
 The explicit keyword is just a way of telling the compiler that a 
 constructor is NOT a type conversion - however, I'm not entirely sure 
 whether it was such a brilliant idea to have two kinds of implicit user 
 defined conversion (constructors and type operators). 
 
 So, just get used to the idea of prefixing each constructor with an 
 explicit and only consider removing it again afterwards.
 
 This is a kind of convenience I don't need, and I pretty much prefer
 the inconvenience of having to spell out type conversions explicitly.
 
 Reminds me of the early days of Java - almost every cast was explicit and 
 you wrote endless lines of casts just to get a very simple resource.
 
 Thanks, but no thanks.
 
 In short: you need a certain amount of convenience to not hinder the 
 programmer. Too much magic in the background and it is just as bad. The 
 difficulty seems to be to define the ideal point between convenience and 
 shooting yourself into the foot all the time.
 
 As long as QVariant mirrors the abilities of C++ (i.e. only using implicit 
 conversions that are also available in plain C++, plus maybe a few very 
 obvious ones, like toString) we are fine. More and we'll get weird bug 
 reports, less and programmers will constantly bitch about it.
 
 BTW: you can already implicitly cast QByteArray-QString, so why not allow 
 it through QVariant?

This can be considered an API fail, which is why you can explicitly turn off 
these type of conversions for your applications by defining QT_NO_CAST_TO_ASCII 
QT_NO_CAST_FROM_ASCII (which we e.g. do for Qt Creator).

Br, Eike

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B 

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Olivier Goffart
On Wednesday 16 July 2014 10:06:52 Poenitz Andre wrote:
 Jędrzej Nowacki wrote:
  Eike wrote:
   [...]
   
   We use common sense on a case by case basic.
   
   Either there is no “common sense” common to me, or this rule has failed
   in
   the past already ;)
   bool - string ?
   bytearray - int/long/double ?
   keysequence - int ?
   string - bool ?
   string - bytearray ?
   string - int ?
  
  What is wrong with string - int or bytearray - int?
 
 At the very least, _implicit_ conversions should not lose data,
 i.e. a  A a1;  B b = a1; A a2 = b; round trip ideally should yield
 a1 == a2.
 
 If I am ready to give up information, I'd like to need to say so
 in the code explicitly. (And yes, part of the deed is done in the
 core language, but even there compilers start to nag about it.)

André, QVariant conversions are not implicit, they are explicit.
You have to use qvariant_castT, QVariant::valueT, or QVariant::to*.
That's explicit.

Conversions _to_ QVariant are sometimes implicit, but they are loss-less as it 
just wrap the type into the QVariant.

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Wednesday 16 of July 2014 12:51:36 Olivier Goffart wrote:
 On Wednesday 16 July 2014 10:06:52 Poenitz Andre wrote:
  Jędrzej Nowacki wrote:
   Eike wrote:
[...]

We use common sense on a case by case basic.

Either there is no “common sense” common to me, or this rule has
failed
in
the past already ;)
bool - string ?
bytearray - int/long/double ?
keysequence - int ?
string - bool ?
string - bytearray ?
string - int ?
   
   What is wrong with string - int or bytearray - int?
  
  At the very least, _implicit_ conversions should not lose data,
  i.e. a  A a1;  B b = a1; A a2 = b; round trip ideally should yield
  a1 == a2.
  
  If I am ready to give up information, I'd like to need to say so
  in the code explicitly. (And yes, part of the deed is done in the
  core language, but even there compilers start to nag about it.)
 
 André, QVariant conversions are not implicit, they are explicit.
 You have to use qvariant_castT, QVariant::valueT, or QVariant::to*.
 That's explicit.
 
 Conversions _to_ QVariant are sometimes implicit, but they are loss-less as
 it just wrap the type into the QVariant.

True conversions from QVariant are explicit, but some of Qt API hides that, 
for example QObject::setProperty which tries hard to implicitly convert data,

Ok, so Andre is in favor of ideal conversions (point 1.2). Ideal round trip 
conversion is possible only if A and B represent the same concept using a 
different representation. So it would work for QLinkedListT  = 
QVectorT, but not for int - long. In my opinion it is really limiting 
and kind of opposite to what we have now :-)

We could potentially split all conversions into two groups ideal and best 
effort and disallow usage of the second group in certain cases. I'm not sure 
if it is worth the effort, and definitely It would break existing behavior as 
effectively it would remove some of the conversions (point 3)

Cheers,
  Jędrek
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Jędrzej Nowacki
On Wednesday 16 of July 2014 06:37:25 Ziller Eike wrote:
 I don’t think we have a single place in Qt Creator where we want automatic
 conversions when using QVariant. A search for QVariant(Map) returns 5400
 hits. In the map case, we usually expect the one retrieving the value for a
 key to know the exact type of what was thrown in (that’s usually the same
 class, or related classes), and then we use item models and QSettings which
 we use in the same way.

From performance point of view it is good to avoid any conversions. I would 
say even more, if you know all types in your application there is no point in 
using QVariant. Sometimes it is not possible, and sometimes one just don't 
want be bothered. 

I made an extremely unfair experiment.  I switched off all conversions in Qt 
and I recompiled QtCreator. To be honest I expected that it would crash at 
startup, but no (impressive!). I was able to use menu and open dialogs, 
nothing more. From the stderr I could deduct that a QVariant conversion was 
used in reading xml, qws files and in animations.

Cheers,
  Jędrek
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Poenitz Andre
Olivier Goffart wrote:
 Jędrzej Nowacki wrote:
 [...]
   What is wrong with string - int or bytearray - int?
 
  At the very least, _implicit_ conversions should not lose data,
  i.e. a  A a1;  B b = a1; A a2 = b; round trip ideally should yield
  a1 == a2.
 
  If I am ready to give up information, I'd like to need to say so
  in the code explicitly. (And yes, part of the deed is done in the
  core language, but even there compilers start to nag about it.)

 André, QVariant conversions are not implicit, they are explicit.

I am aware of that. I tried to answer the question of What is wrong 
with string - int or bytearray - int. 

We admittedly left the original context here (and in other parts of the 
discussion), but the question was posed in context that I read an 
example of an conversion that one would always consider convenient
to have, and I started with At the very least, _implicit.. supposedly 
setting the context of the answer.

Anyway. To summarize my position in the original context: QVariant 
is as it is. It is convenient at times, and it is already too convenient 
at times. Easy type conversion is a different use case than Type 
agnostic storage. QVariant does a bit of both, only the second one
has ever been useful _to me_, I have been bitten by the first. As 
there are typically also more direct ways to convert types than to 
pass through QVariant, I consider the possibility to do type conversion
through QVariant a mis-feature, and adding even more conversion 
abilities would be a step into the wrong direction _for me_. This is 
a personal opinion.

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Daniel Teske

 Anyway. To summarize my position in the original context: QVariant
 is as it is. It is convenient at times, and it is already too convenient
 at times. Easy type conversion is a different use case than Type
 agnostic storage. QVariant does a bit of both, only the second one
 has ever been useful _to me_, I have been bitten by the first. As
 there are typically also more direct ways to convert types than to
 pass through QVariant, I consider the possibility to do type conversion
 through QVariant a mis-feature, and adding even more conversion
 abilities would be a step into the wrong direction _for me_. This is
 a personal opinion.

I certainly can't recall any place in Creator where a conversion via QVariant 
was intended. I can though recall several instances where such a conversion 
was the source of bugs. 

daniel
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Bubke Marco
Hi

In the qml designer we are using comparisons of variants quite extensive and 
run in smaller problems like wrong conversions. E.g. color is broken because 
the alpha value is not used in the comparison. We would like to extent existing 
comparisons too because we get the variants from different sources, so the 
value is equal but because the conversion is not working it is not the 
same. Thomas Hartmann was running in more problems like that and if he is 
back in two weeks you should ask him.

Best, Marco

From: development-bounces+marco.bubke=digia@qt-project.org 
[development-bounces+marco.bubke=digia@qt-project.org] on behalf of Jędrzej 
Nowacki [jedrzej.nowa...@digia.com]
Sent: Tuesday, July 15, 2014 8:55 AM
To: development@qt-project.org
Subject: [Development] Converting types in Qt

Hi,

I would like to discuss type conversions in Qt. As you may know, Qt has
the ability to convert a known type to another known type. This works for
trivial cases like, for example, int to long, but also for more complex
ones like QByteArray to QString or CustomType to OtherCustomType. Type
conversion in Qt happens mostly without user interaction, for example in
QObject introspection or in QML, but it also can be used through public API:
  - QVariant::convert - converts wrapped value to target type
  - QVariant::canConvert - fast check if it may be possible to convert
wrapped type to a given target, which is, in my opinion, pretty useless,
unless the real conversion is really heavy
  - QMetaType::registerConverter - allows to register a custom converter
function for a user defined type
  - QMetaType::convert - perform conversion between two types

I would like to agree on some rules, regarding conversions, as the current
approach is chaotic:

  1. Are we allowed to add new conversions?

 The question is tricky because adding a new conversion is a behavior
change, as this code:
 if (variant.canConvert(QMetaType::int)) ...
 may work differently. If we add custom types into the mix, everything is
even more complex.

 1.1 Patch release or minor release only?

 I would say that new conversions may appear only in minor releases,
obvious fixes to existing conversions may appear in patch releases, where by
obvious I mean crash fixes and cases in which the returned value is definitely
bogus.

 1.2 Should conversion be perfect or based on a best effort?

 Some of the conversion API returns a bool value which is a status
of conversion. What should it return if a conversion is not perfect, for
example int(-1) - uint or QVariantList{string, int, myobject} -
QStringList, should such a case be detected? How do we define the perfect
conversion? Sometimes only ideal, data lossless, conversions should be
allowed, for example QtTestLib is quite strict about it and it allows only
safe conversions. So, for example, int - long but not uint - int, but I
guess for normal use cases such strictness is not necessary.
 I think we should base conversions on the best effort and set the
status to false only if a conversion failed completely, that is mainly if a
conversion is unknown or if underlying implementation detected a failure, like
QByteArray - float which uses QByteArray::toFloat(bool *ok)

 1.3 Should we try to support a user's type conversions out of the box?

 Currently a user needs to manually register a conversion function so
Qt can know it and use it. For certain types we can do much better, because we
can automatically convert some types. For example:
 QVectorchar - QLinkedListint
 QListFoo - QVectorFoo
 QPointerFoo - QObject*
 QPointerFoo - void*
 QSharedDataPointerFoo - bool
 MyQObject* - QPointerMyQObject
 Currently we are not doing it for one reason which is behavior
compatibility. What if a user already defined a conversion that we want to add?
It could happen because the conversion was not available in a previous Qt
version. The problem is that the new conversion function may behave in a
different way, especially in edge cases and because of the lack of perfection
mentioned in 1.2. We need to pick only one function. That could be the Qt
version, but then we risk that an existing code will not work anymore. Are we
willing to accept that?
 I believe that we should document the problem, and allow the
conversions.

 1.4 Should a user be able to add Qt types conversion on his own?

 Some conversions are missing, some we consider as not safe. A user,
assuming that he knows what he is doing, could register a conversion; for
example, QString - QChar, how bad is it? Currently, such usage is blocked,
because we are afraid that in the future we may add a conversion that
overrides it.
 In my opinion it is not needed; it is a corner case, because we a)
should have the conversion and then it will appear in a future version b) the
conversion is 

Re: [Development] Converting types in Qt

2014-07-16 Thread Ziller Eike

On Jul 16, 2014, at 1:30 PM, Jędrzej Nowacki jedrzej.nowa...@digia.com wrote:

 On Wednesday 16 of July 2014 06:37:25 Ziller Eike wrote:
 I don’t think we have a single place in Qt Creator where we want automatic
 conversions when using QVariant. A search for QVariant(Map) returns 5400
 hits. In the map case, we usually expect the one retrieving the value for a
 key to know the exact type of what was thrown in (that’s usually the same
 class, or related classes), and then we use item models and QSettings which
 we use in the same way.
 
 From performance point of view it is good to avoid any conversions. I would 
 say even more, if you know all types in your application there is no point in 
 using QVariant. Sometimes it is not possible, and sometimes one just don't 
 want be bothered. 
 
 I made an extremely unfair experiment.  I switched off all conversions in Qt 
 and I recompiled QtCreator. To be honest I expected that it would crash at 
 startup, but no (impressive!). I was able to use menu and open dialogs, 
 nothing more. From the stderr I could deduct that a QVariant conversion was 
 used in reading xml, qws files and in animations.

True, we use QVariant::toString for an easy way to write the value of the 
key-value pairs of basic types in qtversions.xml, profiles.xml, .pro.user, and 
the sessions (.qws)
Even there we keep the type information though, and use that to explicitly 
convert the variants in the map back to the right type when reading the file, 
so type conversion should never be outside the reader/writer in that case. What 
the conversion saves us, is a few case statements in the reader/writer.

  data
  variableQtVersion.0/variable
  valuemap type=QVariantMap
   value type=int key=Id10/value
   value type=QString key=NameQt 5.3/value
   value type=QString 
key=QMakePath/Users/Shared/qt/qt/5.3/64/qtbase/bin/qmake/value
   value type=QString 
key=QtVersion.TypeQt4ProjectManager.QtVersion.Desktop/value
   value type=bool key=isAutodetectedfalse/value
  /valuemap
 /data

No idea what happens in animations, but I’d suppose that any conversions there 
would be accidentally.

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B 

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Thiago Macieira
On Wednesday 16 July 2014 15:01:53 Ziller Eike wrote:
 No idea what happens in animations, but I’d suppose that any conversions
 there would be accidentally.

QPropertyAnimation is based on modifying QVariants, isn't it?
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-16 Thread Ziller Eike

On Jul 16, 2014, at 5:04 PM, Thiago Macieira thiago.macie...@intel.com wrote:

 On Wednesday 16 July 2014 15:01:53 Ziller Eike wrote:
 No idea what happens in animations, but I’d suppose that any conversions
 there would be accidentally.
 
 QPropertyAnimation is based on modifying QVariants, isn't it?

True, but I’d claim that that shouldn’t need automatic conversions between 
types.
If I create a QPropertyAnimation on a “qreal” property, and set “qreal” start 
and end values, then there should not happen any automatic conversions.
If I’d set end value “10.0” (i.e. QString), then I’d consider that very bad 
style. Maybe we have some int/real conversions happening there, which could at 
least argued to not do much harm.

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Anja Wasenius
Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 
144331 B 

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-15 Thread Olivier Goffart
On Tuesday 15 July 2014 08:55:29 Jędrzej Nowacki wrote:
 Hi,
 
 I would like to discuss type conversions in Qt. As you may know, Qt has
 the ability to convert a known type to another known type. This works for
 trivial cases like, for example, int to long, but also for more complex
 ones like QByteArray to QString or CustomType to OtherCustomType.
 Type conversion in Qt happens mostly without user interaction, for example
 in QObject introspection or in QML, but it also can be used through public
 API: - QVariant::convert - converts wrapped value to target type
   - QVariant::canConvert - fast check if it may be possible to convert
 wrapped type to a given target, which is, in my opinion, pretty useless,
 unless the real conversion is really heavy
   - QMetaType::registerConverter - allows to register a custom converter
 function for a user defined type
   - QMetaType::convert - perform conversion between two types
 
 I would like to agree on some rules, regarding conversions, as the
 current approach is chaotic:
 
   1. Are we allowed to add new conversions?
 
  The question is tricky because adding a new conversion is a behavior
 change, as this code:
  if (variant.canConvert(QMetaType::int)) ...
  may work differently. If we add custom types into the mix, everything
 is even more complex.

I'd say yes, for sensible conversion
You are right that it is a behaviour change, but i think it is worth changing 
it.

 
  1.1 Patch release or minor release only? [...]

Minor release only of course.
Path release is only for regressions and critical fixes.  New conversions is a 
feature.

  1.2 Should conversion be perfect or based on a best effort?
 
  Some of the conversion API returns a bool value which is a status
 of conversion. What should it return if a conversion is not perfect, for
 example int(-1) - uint or QVariantList{string, int, myobject} -
 QStringList, should such a case be detected? How do we define the perfect
 conversion? Sometimes only ideal, data lossless, conversions should be
 allowed, for example QtTestLib is quite strict about it and it allows only
 safe conversions. So, for example, int - long but not uint - int, but
 I guess for normal use cases such strictness is not necessary.
  I think we should base conversions on the best effort and set the
 status to false only if a conversion failed completely, that is mainly if a
 conversion is unknown or if underlying implementation detected a failure,
 like QByteArray - float which uses QByteArray::toFloat(bool *ok)

You have to think of the use cases for QVariant::convert.
Most common are things like QVariant::toString and QVariant::toInt and such. 
You usually have a function that expect a string or an int, and you do best 
effort to get that from the QVariant to ease programmer life in the wonderful 
wold of dynamic typing :-)

It is true that it would be good to have a bool *ok in case the conversion 
failed totally.

  1.3 Should we try to support a user's type conversions out of the box?
 
  Currently a user needs to manually register a conversion function
 so Qt can know it and use it. For certain types we can do much better,
 because we can automatically convert some types. For example:
  QVectorchar - QLinkedListint
  QListFoo - QVectorFoo
  QPointerFoo - QObject*
  QPointerFoo - void*
  QSharedDataPointerFoo - bool
  MyQObject* - QPointerMyQObject
  Currently we are not doing it for one reason which is behavior
 compatibility. What if a user already defined a conversion that we want to
 add? It could happen because the conversion was not available in a previous
 Qt version. The problem is that the new conversion function may behave in a
 different way, especially in edge cases and because of the lack of
 perfection mentioned in 1.2. We need to pick only one function. That could
 be the Qt version, but then we risk that an existing code will not work
 anymore. Are we willing to accept that?
  I believe that we should document the problem, and allow the
 conversions.

I think we could try to automatically do conversion when we know how to do it. 
And if there is an user defined conversion, it overrides the automatic one.

  1.4 Should a user be able to add Qt types conversion on his own?
 
  Some conversions are missing, some we consider as not safe. A user,
 assuming that he knows what he is doing, could register a conversion; for
 example, QString - QChar, how bad is it? Currently, such usage is
 blocked, because we are afraid that in the future we may add a conversion
 that overrides it.
  In my opinion it is not needed; it is a corner case, because we a)
 should have the conversion and then it will appear in a future version b)
 the conversion is invalid, and it is a sign of a user's broken code.

I'd say no.

   2. Can we modify an existing conversion?
 
  All modification changes 

Re: [Development] Converting types in Qt

2014-07-15 Thread Poenitz Andre
Olivier Goffart wrote:
 Jędrzej Nowacki wrote:
1. Are we allowed to add new conversions?
   The question is tricky because adding a new conversion is a behavior
   change, as this code:
   if (variant.canConvert(QMetaType::int)) ...
   may work differently. If we add custom types into the mix, everything
  is even more complex.
 
 I'd say yes, for sensible conversion
 You are right that it is a behaviour change, but i think it is worth changing 
 it.

Why? 

On one hand you promise binary compatibility. On the other hand 
behaviour changes are proposed to be done on an nice to have 
base?

Do we really think that's ok to disallow changing some int foo() { return
42; } to some int bar() { return 42; } that's easy to discover at build time,
but it's fine to change int foo() { return 42; } to int foo() { return -1; } ?

 so Qt can know it and use it. For certain types we can do much better,
 because we can automatically convert some types. For example:
  QVectorchar - QLinkedListint

QVectorchar v; v.append(130);
QLinkedListint l = /*someSensibleAutomatedConversion*/(v);

assert(l.first() == 130) ?  Depends ? 

   A conversion may be arbitrary. For example, most of the conversions
  to QString. Should bool(false) - QString return False, 0, false?
  What about precision of, for example, double - QString ?

 We use common sense on a case by case basic.

I tend to believe the common sense in type conversion land is pretty
close to avoid to do it automatically, prefer to make it explicit.

Already now it's far too easy to make mistakes based on the nice
and easy QByteArray - QVariant - QString conversions when 
accidentally writing QByteArrays into QSettings and reading QStrings 
back. There shouldn't be more of that.

Andre'
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Converting types in Qt

2014-07-15 Thread Olivier Goffart
On Tuesday 15 July 2014 10:38:52 Poenitz Andre wrote:
 Olivier Goffart wrote:
  Jędrzej Nowacki wrote:
 1. Are we allowed to add new conversions?
 
The question is tricky because adding a new conversion is a
behavior
change, as this code:
if (variant.canConvert(QMetaType::int)) ...
may work differently. If we add custom types into the mix,
everything
   
   is even more complex.
  
  I'd say yes, for sensible conversion
  You are right that it is a behaviour change, but i think it is worth
  changing it.
 Why?
 
 On one hand you promise binary compatibility. On the other hand
 behaviour changes are proposed to be done on an nice to have
 base?
 
 Do we really think that's ok to disallow changing some int foo() { return
 42; } to some int bar() { return 42; } that's easy to discover at build
 time, but it's fine to change int foo() { return 42; } to int foo() {
 return -1; } ?

It's always a dilemma. We have to look at how likely we are to break 
applications and I don't think adding a conversion is likely to cause 
breakages.

  so Qt can know it and use it. For certain types we can do much better,
  
  because we can automatically convert some types. For example:
   QVectorchar - QLinkedListint
 
 QVectorchar v; v.append(130);
 QLinkedListint l = /*someSensibleAutomatedConversion*/(v);
 
 assert(l.first() == 130) ?  Depends ?

QVariant(char(130)).toInt() already exists. You may argue that it is not 
sensible but that's another issue.
I guess the example is more between QVectorT1 - QLinkedListT2 when there 
exist a conversion from T1 to T2

A conversion may be arbitrary. For example, most of the
conversions
   
   to QString. Should bool(false) - QString return False, 0,
   false?
   What about precision of, for example, double - QString ?
  
  We use common sense on a case by case basic.
 
 I tend to believe the common sense in type conversion land is pretty
 close to avoid to do it automatically, prefer to make it explicit.
 
 Already now it's far too easy to make mistakes based on the nice
 and easy QByteArray - QVariant - QString conversions when
 accidentally writing QByteArrays into QSettings and reading QStrings
 back. There shouldn't be more of that.

What's the mistake here? Wrong encoding? Bad performances?

When one use QVariant, it is because we want to enjoy dynamic typing and nice 
conversions.

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development