Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Quite a fundamental change to the way how we handle arrays, which should also fix #727. Still an early draft version and up for discussion.
This PR adds a third array type to the 2 existing ones:
Array<T>
, typed arraysVariantArray
==Array<Variant>
, untyped arraysOutArray
, a possibly typed arrayOut variance
"Out" here means out variance. In short, this means that such a type supports all operations where data flows out of the array, because those are covariant:
However, it does not allow any data flow in to the array:
As you see in the 2nd example, this would otherwise ruin type safety. This is btw a problem that GDScript is fighting with.
It is important to understand that "out" does not mean "read". It's perfectly fine to perform write operations, as long as they don't involve data flow in to the array.
Engine APIs
One area where more research is needed are the Godot class/method APIs. So far, we have used either
VariantArray
orArray<T>
in the signatures, and I think it has worked quite well. One commit changesVariantArray
toOutArray
, but I'm not yet sure if we should really do this.Some thoughts:
OutArray
is more flexible when you have to provide it, because you can now passArray<T>
(typed arrays) and convert them. Today, one has to use an untyped array.OutArray
is more limiting when receiving it, as one first needs to (fallibly) convert toVariantArray
.OutArray
when returning, andVariantArray
when receiving.Array
, could it technically point to a (runtime-)typed array or are we guaranteed that it's untyped?Drawbacks
While it does solve some type-safety problems, an extra
OutArray
also brings quite a bit of mental overhead. It can also require conversions in more places. We should consider that GDScript doesn't have this, and few people are complaining about the covariance problem.This feature could pull in more APIs just to be useful. Something like
impl AsArrayArg
orimpl Into<OutArray>
, similar toAsObjectArg
, may be necessary. Then there'sarray!
/varray!
macros, etc.As soon as Dictionaries become typed (which will happen), we'll have the same situation there, with both key/value variance. An
OutDictionary
would be the pendant.A lighter way to address this would be to allow converting from
Array<T>
toVariantArray
. If we do this, we can still panic on "in data flow" operations forVariantArray
. This would have less strict guarantees, but might be more ergonomic for gamedev code.