Skip to content
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

Python style list comprehensions for gdscript #15222

Closed
wants to merge 2 commits into from

Conversation

poke1024
Copy link
Contributor

See #4716

print([2 * x + 10 for x in [2, 3, 4]])
> [14, 16, 18]

print([[x, y] for x in range(2) for y in range(3) if x + y >= 1])
> [[0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]

No optimizations for preallocating size yet.

@@ -731,6 +731,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s

ArrayNode *arr = alloc_node<ArrayNode>();
bool expecting_comma = false;
expr = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used spaces instead of tabs


expr = cn;
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used spaces instead of tabs with this block

@@ -767,7 +828,8 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
}

expr = arr;
if (!expr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used spaces instead of tabs

This saves one lookup to "append" per item and preallocates the array to the final size in simple cases, both making comprehension lists build 40% faster than through a regular loop
@akien-mga akien-mga added this to the 3.0 milestone Jan 4, 2018
@akien-mga
Copy link
Member

Thanks a lot for your contribution!
We are now entering a strict release freeze for Godot 3.0 and will only consider major bug fixes. We won't merge new features and enhancements anymore until 3.0 is released.

Moving this PR to the 3.1 milestone, to be reviewed once the release freeze is lifted. It could eventually be cherry-picked for a future 3.0.1 maintenance release if it doesn't change the user-facing APIs and doesn't compromise the engine's stability.

@kvanbere
Copy link
Contributor

I came here looking for a way of doing #17268 but I like this suggestion more. Would love to see this.

IMO lambdas might make gdscript too complex for beginners? But this is a really good compromise.

@akien-mga
Copy link
Member

We've discussed this on IRC with many core developers, and the general feeling is that the syntax of list comprehensions makes code quite hard to read, and goes against the design principles of GDScript to have a straightfoward and easy to read syntax.

Most use cases for list comprehensions can easily be replaced with one (or nested) for loops, which are a lot more readable even if a couple lines more, so we don't see a real use case that would warrant the syntactic complexity.

See discussion on http://godot.eska.me/irc-logs/devel/2018-06-20.log from 22:10.

@YBPN
Copy link

YBPN commented Sep 8, 2020

I’d like to contest the “unreadable” argument too. List comprehensions are actually more readable to me. Their syntax is very much like the syntax of natural English language:

Give me the square of every number n in this list if n is greater than 7.

Which in almost-code translates to this (still English-like):

Give me x**2 for every x in this list if x is greater than 7.

The above sentence is eminently readable to me. I sincerely cannot understand why this would be a difficult-to-read sentence. I can actually feel more cognitive load when reading a regular for-loop compared to reading a list comprehension.

It starts to diverge from English syntax with nested comprehensions, where the “English” would be:

“Give me y*3 for every y in this list, then give me x**2 for every x in that new list if x is greater than 7.

Which in code would be:

New_list = [ 
	x**2 for x in [
		y*3 for y in list
	]
	if x > 7
]

— which I would argue is still not any more difficult to read than a nested for-loop. I am of course just speaking for myself, but then again, the detractors of list comprehensions are also just speaking for themselves and extrapolating their experience onto other people.

I'd like to offer the argument that if you read a list comprehension as if it were a natural English sentence (just missing a few bits of grammar), it becomes quite easy to understand.

Referencing #4716 where some people have also made some good arguments for list comprehension.

@kahveciderin
Copy link

kahveciderin commented Jul 10, 2021

makes code quite hard to read

since when is this a design metric? this is a programming language, not something you will write educational papers with. and also that argument is completely wrong as list comprehensions are more readable than three thousand nested for loops. you cant tell me it is easier for you to read this:

newlist = []
for x in fruits:
  if "a" in x:
    newlist.append(x)

than this:

newlist = [x for x in fruits if "a" in x]

@Calinou
Copy link
Member

Calinou commented Jul 10, 2021

Since this repository is now used for bug reports only, feature proposals should now be discussed on the Godot proposals repository.

@godotengine godotengine locked as resolved and limited conversation to collaborators Jul 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants