I love love love almost everything about Python's syntax.
Slices that support negative indexes.
List and dictionary comprehensions are amazing:
{ (X,Y): X2 + Y for X in range(10) for Y in someiter if Y > 5}
I love that they become generators when you use () instead of []. Pure genius.
Generators from a function containing yield or yield from equally beautiful. % for string interpolation was so good they had to bring it back.
Tripple quotes using """ and ''' are hard to beat.
Using func(list) to unpack a list into a functions arguments. Or func(dict) to unpack a map by name. Using args and kwargs to implimentaions variadic functions.
I love indentation based code blocks.
The way 'and' and 'or' can return values is so much better than a ?: terinary.
I think I dumped a third of the Python spec there.
I could use a multi-line lambda but it's not a huge omission. Pipelines like bash | pipe or F# |> would be welcome.
go's select statement is also subtle but smart. Doing multiple waits in one thread is tricky to impossible in most any other language.
Built in regex like perl is always nice when you have it.
I'm sure I missed something gushing over Python, but tapping this out over the phone if already killing my thumb.
Java desperately needs groovys's safe navigation operator a?.getB()?.getC(). It's like a normal method call but returns null if the receiver is null instead of throwing an NPE.
I love Python too (a lot), but I disagree with some of these.
> I love that they become generators when you use () instead of [].
I kind of like this, and I kind of hate it. My second-favorite language is Haskell, where everything is lazy, so to me it almost seems like everything should be generators anyway (except when a value is expected).
> % for string interpolation was so good they had to bring it back.
I hate % for string interpolation. It's ugly. Why do my variables need "variables" in the strings? It's indirect interpolation. I far prefer f-format strings, because `print(f"Correct: {correct}/{total}")` reads much better.
> Tripple quotes using """ and ''' are hard to beat.
Unconvinced. I feel like the syntax for multiline strings could be a bit simplified.
Also, it's a pain to combine multiline strings with indentation. I don't want all the extra whitespace at the fronts of the lines, but I also don't want to process the text immediately afterwards... sigh.
But I totally agree with the other points. Overall, the syntactic sugar is phenomenal! Just these points I disagree about.
Eager lists have their place! Ya can't sort or slice into a generator. I like the choice.
I'm mostly still in Python 2.7 land so I forgot about the new f strings. I've never used them and I'm 50:50 only because I can do "%s %s %s" % (a.b(), z[:4], x2) without binding new variables. Can f strings do that? I don't know.
I agree about the whitespace issues. Have you seen a language do them better? I proposed using | to prefix each line for Java's string literals. At least they're explicit that way. I'm just glad Python used """ instead of backticks or or <<<START style here docs.
> Eager lists have their place! Ya can't sort or slice into a generator. I like the choice.
Something like that could be handled implicitly... hmm but that seems bad. Maybe you're right that having a choice is better!
> I can do "%s %s %s" % (a.b(), z[:4], x2) without binding new variables. Can f strings do that? I don't know.
In 3.x f-string style, `f"{a.b()} {z[:4]} {x2}"` would work just fine! Python just expects any expression inside the curly braces, so as long as you give up a value (and that value is either a string or an object of a class that implements `__str__`, I think), you're golden.
It's particularly useful when you have a lot of interpolation to do. The more arguments there are, the more tedious it is to read through a %-style format and figure out which variables correspond to what markers in the string.
> I agree about the whitespace issues. Have you seen a language do them better?
Not really, unfortunately.
I think a case could be made that all indentation should be based on either (a) the triple-quote or (b) the first non-whitespace character of the first line. But I don't know if that's intuitive enough. Definitely something to think about, though!
Apache Groovy also has shortcut property syntax so you can write `a?.b?.c` to get the same effect. Of course, all the syntactic sugar mixed together becomes quite confusing quite quickly. Some Groovers want to write the `?` once only and have it ripple through so you'd only need write `a?.b.c` in Groovy 3. But then, what if you actually want an NPE if `getB()` works but `getC()` doesn't? Perhaps `a?.b¿.c` would do the trick!
My favorite from python are decorators, especially the built-in ones like @property. They can improve readability immensely, so the don't feel extraneous.
Slices that support negative indexes. List and dictionary comprehensions are amazing: { (X,Y): X2 + Y for X in range(10) for Y in someiter if Y > 5} I love that they become generators when you use () instead of []. Pure genius. Generators from a function containing yield or yield from equally beautiful. % for string interpolation was so good they had to bring it back. Tripple quotes using """ and ''' are hard to beat. Using func(list) to unpack a list into a functions arguments. Or func(dict) to unpack a map by name. Using args and kwargs to implimentaions variadic functions. I love indentation based code blocks. The way 'and' and 'or' can return values is so much better than a ?: terinary. I think I dumped a third of the Python spec there.
I could use a multi-line lambda but it's not a huge omission. Pipelines like bash | pipe or F# |> would be welcome.
go's select statement is also subtle but smart. Doing multiple waits in one thread is tricky to impossible in most any other language.
Built in regex like perl is always nice when you have it.
I'm sure I missed something gushing over Python, but tapping this out over the phone if already killing my thumb.
Java desperately needs groovys's safe navigation operator a?.getB()?.getC(). It's like a normal method call but returns null if the receiver is null instead of throwing an NPE.