Thanks for writing this up, Ulf! Working on porting Qt Location to Qt 6 right now, I’m looking very much forward to the improved support for value types :)
> On 20 Sep 2022, at 18:13, Ulf Hermann <ulf.herm...@qt.io> wrote: > > Hi, > > I'm currently trying to transform QML value types, such as font, rect, > size, etc, into something less random and more predictable. On that > occasion I'm wondering what semantics people actually expect from value > types. […] > 1. Value types are passed by value > ————————————————— […] > However, since we've never implemented value type references for lists, > lists of value types behave exactly this way. The following does in fact > not modify the list, but only a copy of the object at index 10: > > property list<font> fonts: [ ... ] > Component.onCompleted: fonts[10].pointSize = 33 > > The same holds for nested value types. Assume a value type "outer" that > has a property "a" of another value type, which has an integer property > "b". The following does not write back: > > property outer o > Component.onCompleted: o.a.b = 10 Not a fan. Within a scope, or at least within a statement, operating on copies is unexpected and confusing. Esp with nested lists of structured value types, ie. o.a[1].b[10] = 10 That turns into a lot of code when write-back has to be done explicitly. > 2. Everything is a reference > ---------------------------- > > JavaScript doesn't really have value types. The doEvil() function thus > receives a reference to the original 'f', not a copy. The modification > of pointSize is written back to the original property. > > With font you might still wrap your head around it because font "looks > like" an object with all its properties and internal logic. However, you > can also pass a point or a rect around through various functions, and > whenever you modify it, the result would be written back to the original > place where it was retrieved from, possibly in a different file half an > hour ago. I personally find that rather confusing. Agree. It might be more natural for a Python, Ruby, or JavaScript developer, but I’d much prefer functions not to have implicit side effects by default. With EcmaScript 6 we can use destructuring assignment syntax to work with functions that return multiple values through an array or object, which makes it reasonably convenient to return multiple values from a function. > A middle ground would be that value types are passed by value when > calling or returning from a function, but are treated as references and > written back on modification inside a function. Inside the same function > qmlsc and qmlcachegen could keep track of where a value was loaded from > and write it back when it's modified. I've played with the concept a > bit, and it's possible to support nested value types and lists of value > types this way. All the writing back would still be inefficient, though. I like that approach, it’s easily defined when the value is copied, and I think it does the right thing in most cases. Taking this one step further, could we treat lvalues as references: // o.a.b gets modified o.a.b = 10 But always copy rvalues: // o.a.b does not get modified var old_b = o.a.b // copy of rvalue old_b = 15 // call_function gets a copy of o.a.b, which then gets modified explicitly o.a.b = call_function(o.a.b) ? > In addition to whatever course is chosen, we might add a detach() method > on the JavaScript prototype used for all value types. With that you > could intentionally detach a value from the property it was loaded from. Makes sense. It would solve the problem that modifying several attributes of a value would require many (slow) write-backs. Volker _______________________________________________ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development