Godot: Adding python's array * operator

Created on 17 Oct 2017  路  11Comments  路  Source: godotengine/godot

Wanted to ask if there was interest in getting python's array * operator ported to GDScript, a la [0] * 4 => [0, 0, 0, 0]

I kept typing this out and then going back to doing the good ol' for i in range(number) so thought I'd ask. If theres enough interest, I'll take a stab at adding it!

archived feature proposal gdscript

Most helpful comment

I think the proposal itself is bad.

Next week we will probably get a proposal for "I want that [1, 2, 3, 4] * 2 is [2, 4, 6, 8]" and it would be just as valid and also confusing as this one. I mean after all, what does multiplying an array with a number mean? There are many things that could happen there, all of which would be equally surprising.

If we don't want to end up a JavaScript situation then I think we should try to not add ambiguous operator behaviours which are, when considered sober, not really clear in itself.

Would this apply to strings too, since they are kinda like arrays as well. Should "1" * 4 be "1111" or should it be "4" (like in PHP or what language it was)?

I think that if we ask "If you mutliply an array with a scalar, what does that produce?" and people don't answer like a cannonball it's probably a weird and wacky thing to do in the first place.


I'm not saying that those operations are bad or those features are bad, but I think it's bad to hide those things behind an operator that already has a well understood behaviour.

If you want to repeat a container n times then I'd say it needs to be an instance of a monoid and a repeat(container, n) function that works equally for all containers that are monoids. (with the behaviour of repeat(a, 1) = a and repeat(a, n) = monoid_append(a, repeat(a, n - 1)))
That would work on strings, on arrays and maybe even custom data types.

While if we had a map function for types that are an instance of a Functor then people that want [1, 2] * 2 to be [2, 4] could use that.

So all in all I think we should not add those operators "just because it could be interpreted that way".


Another thing is that we plan to add complete static typing (which will be optional but as advanced as possible) to GDScript. We want to have a good type inference algorithm that does not require you to write out types most of the time.

If operators are overloaded "just because" then that inference will become harder, making a * 4 a hard thing to interfere. a could be of any numeric type, but now it can also be an array and a string and a ..... That would harm the autocompletion abilities if there is not enough context. If there is, then great, but it's still a thing to consider.


TL;DR: let's not become JavaScript, keep the operator semantics clean 鉁岋笍

All 11 comments

+1 for me, i wrote a polyfill method in gdscript to fill / resize arrays so having one done natively would be awesome!

Obligatory and maybe slightly cheeky "Just because $language has $feature, doesn't mean that GDScript needs it either". GDScript, as far as I know at the very least, is meant to be (relatively) small and not include a giant slew of syntactic sugar.

I'm not strictly against it, personally, even though I can't quite imagine seeing myself use it. Still, syntactic sugar like that is just like regular sugar, you shouldn't have too much of it, and GDScript is already getting a fair bit of it in 3.0 (the $ operator, match statements, probably something else I'm forgetting).

Just my 2垄 on the matter.

@NullConstant - totally agree, I'm just so used to having the ability to make a sized array for copying up front that it seemed the most strait forward way to do it (unless I messed the ability to use the underlying resize ability!)

Without going too off-tangent, whats the $ operator for?

var some_array = []
some_array.resize(4)

# now the array has 4 elements, initialized to null

Without going too off-tangent, whats the $ operator for?

get_node("SomeNode").some_property = some_value

can be written as

$SomeNode.some_property = some_value

I think the proposal itself is bad.

Next week we will probably get a proposal for "I want that [1, 2, 3, 4] * 2 is [2, 4, 6, 8]" and it would be just as valid and also confusing as this one. I mean after all, what does multiplying an array with a number mean? There are many things that could happen there, all of which would be equally surprising.

If we don't want to end up a JavaScript situation then I think we should try to not add ambiguous operator behaviours which are, when considered sober, not really clear in itself.

Would this apply to strings too, since they are kinda like arrays as well. Should "1" * 4 be "1111" or should it be "4" (like in PHP or what language it was)?

I think that if we ask "If you mutliply an array with a scalar, what does that produce?" and people don't answer like a cannonball it's probably a weird and wacky thing to do in the first place.


I'm not saying that those operations are bad or those features are bad, but I think it's bad to hide those things behind an operator that already has a well understood behaviour.

If you want to repeat a container n times then I'd say it needs to be an instance of a monoid and a repeat(container, n) function that works equally for all containers that are monoids. (with the behaviour of repeat(a, 1) = a and repeat(a, n) = monoid_append(a, repeat(a, n - 1)))
That would work on strings, on arrays and maybe even custom data types.

While if we had a map function for types that are an instance of a Functor then people that want [1, 2] * 2 to be [2, 4] could use that.

So all in all I think we should not add those operators "just because it could be interpreted that way".


Another thing is that we plan to add complete static typing (which will be optional but as advanced as possible) to GDScript. We want to have a good type inference algorithm that does not require you to write out types most of the time.

If operators are overloaded "just because" then that inference will become harder, making a * 4 a hard thing to interfere. a could be of any numeric type, but now it can also be an array and a string and a ..... That would harm the autocompletion abilities if there is not enough context. If there is, then great, but it's still a thing to consider.


TL;DR: let's not become JavaScript, keep the operator semantics clean 鉁岋笍

Looks like its a no-go then, thanks for the feedback!

On a similar note, what about having [0].repeat(4) -> [0, 0, 0, 0] and "a".repeat(4) -> "aaaa"?
This would be cleaner than the operator overload, while still allowing for repeating strings and arrays.

@bojidar-bg what about repeat(what, count)? It seems to be more consistent to len(what) but IMO more confusing. I don't know.

@Noshyaar I don't think we should fill the global GDScript scope with such functions.

What would it mean in GDScript for a container type to be a monoid instance? Are typeclasses or traits a planned feature?

@raymoo Necrobumping old threads is hardly a good idea. If you feel that what you are proposing is a useful feature for GDScript, you might open another issue discussing it.

Just make sure to explain what a "monoid" or a "typeclass"/"trait" is for the general public.

Was this page helpful?
0 / 5 - 0 ratings