-
-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add with(instance)
with constructor syntax in GDScript
#623
Comments
This was discussed previously in godotengine/godot#18345 and godotengine/godot#6300 (and godotengine/godot#1736). So far consensus has been that such a feature would not be necessary in GDScript. Consider that it is mostly sugar for a variable assignment: with some.thing:
property = 4
# - can also be written as ->
var x = some.thing
x.property = 4 And it will behave the same. And at times, it can be confusing to someone unfamiliar with the semantics: with $node_a:
$node_b.position = position
# Does it mean this:
get_node("node_b").position = get_node("node_a").position
# Or does it mean this?
get_node("node_b").get_node("node_a").position = get_node("node_a").position
# Or even one of those?
get_node("node_b").position = position
get_node("node_b").get_node("node_a").position = position var a = 5
with b:
c = a
# Does it mean this:
b.c = 5
# Or does it mean this?
b.c = b.a
# Likewise
with x:
y = z
# Does it mean this:
x.y = z # which is an error if z is undefined
# Or does it mean this?
x.y = x.z In addition it might result in some nontrivial code changes to autocompletion (since it has to be told how This is a proposal, however, so feel free to discuss it, if you consider that the feature can be beneficial in an object-oriented language such as GDScript. |
The way I envision it (and remember it in GML) is that it is effectively a writing a method in the class of the instance being "withed" But it doesn't always make sense to organize that method in that class. Sometimes it makes more sense to organize it somewhere else. Take for example a ball. Suppose this ball is used for many sports. And in each sport the ball behaves differently depending on how it is used in each sport. So rather than writing a function
you'd write in the baseball class
Note that the methods would actually be written there I just wrote as if they are being called there as a shorthand. Its not a perfect example. But I think its enough to illustrate what I'm imagining. Its an effective way to put what would normally be methods of another class in a different class for organizational purposes. Mostly I don't like having to write otherObject.property over and over. But I also want to keep by code organized in a way that isn't cluttered and weird. |
At least that's a demonstrable number of feature requests I'd say, including this one. See discussion in godotengine/godot#25669. In there people suggest adding By the way, the collision = {}
collision["point"] = result.point
collision["normal"] = result.normal
collision["rid"] = result.rid
collision["collider_id"] = result.collider_id
collision["shape"] = result.shape
collision["linear_velocity"] = result.linear_velocity
collision["metadata"] = result.metadata vs: collision = {}
with collision:
point = result.point
normal = result.normal
rid = result.rid
collider_id = result.collider_id
shape = result.shape
linear_velocity = result.linear_velocity
metadata = result.metadata Alternatively, var a = Vector2(0, 0)
scope:
var a = Vector2(1, 1)
print(a) # prints Vector2(0, 0) var a = Vector2(0, 0)
scope a:
x = 1
y = 1
print(a) # prints Vector2(1, 1) |
Dart has so called cascade notation, which does the thing being described (acting on an object in sequence).
|
@katoneko I'm afraid that particular syntax doesn't save any meaningful amount of space (horizontal or vertical). However, it makes refactoring harder as you may have to move the initial In general, I think we should be optimizing for easier refactoring rather than aiming to type the lowest amount of characters possible. Many other modern languages seem to be going in that direction. Also, explicit is better than implicit 🙂 |
If everything is explicit, nothing becomes explicit, so we get unnecessary verbosity over explicitness at the end of the day, which doesn't allow the developer to focus on things that really matter: algorithms. Also, making a language explicit makes more sense for languages with static typing rather than dynamic, which is implicit. I'd like GDScript to remain its implicitness to some extent, but with the advent of static typing in GDScript people tend to choose being "explicit" by annotating each and every variable/method almost religiously, without considering the practical aspect of doing so. Following the principles which are never questioned is the worst thing a person can do in terms of individuality and the problem at hand. Mentioning general development principles just signifies that there's no certainty over the feature being useful or not. But thinking in terms of collective, mass development which is so inherent in open-source software development, I'd say that yeah explicit may be better than implicit and may be the actual reason for those languages adopting such principles, because that seems to be the bulletproof way of ensuring readable, self-documenting code which can connect developers on the mental map level, and because a lot of people don't seem to document the features in the first place due to laziness/lack of resources/time/motivation, you name it. It all boils down to the human factor as I say.
Bold IMHO. 🙂 |
in gml it can be used with a instance or a type for example if you do..
it only works on that instance. but it you do..
it does it to all Sprites instances that exist in the game |
Working with all instances of a type sounds dangerous to me, so I think it is better to make it work for arrays, and ask users to use groups. In this case it would become something like this for loop: for x in get_tree().get_nodes_in_group("Sprite"):
x.h_frames = 1 But I find a bit less reason to make for sprite in get_tree().get_nodes_in_group("Sprite"):
with sprite:
h_frames = 1
# Alternatively, with less indent:
for sprite in get_tree().get_nodes_in_group("Sprite"): with sprite:
h_frames = 1 |
I think that allowing the user to add logic to every instance of a type could be slow but it might also have be good for sorting nodes. maybe there could be a optional argument to the with statement like so..
|
with(instance)
with constructor syntax in GDScript
This would be really useful for component oriented design. |
Describe the project you are working on:
I am working on a puzzle game which works similar to Rubik's cubes and combination locks
Describe the problem or limitation you are having in your project:
One of my objects is changing the effect of another in a lot of ways and it is tedious to keep doing otherobject.property1.dosomething()
otherobject.property1.dosomethingelse()..etc
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
if we had a with(instance) method like game maker then it would be less tedious an easier to read.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml%20language%20overview/401_18_with.html
If this enhancement will not be used often, can it be worked around with a few lines of script?:
Either tediously or by writing a method in another class when organizationally it might not fit as well there
Is there a reason why this should be core and not an add-on in the asset library?:
Its used fairly often in gml I don't see why it wouldn't be in here.
The text was updated successfully, but these errors were encountered: