Though personally I really like itertools and list comprehensions. (And list comprehensions are pretty functional as well, they were inspired by haskell I blieve.)
- Annotating nested JSON objects is a pain in the ass. You need a bazillion intermediary classes.
- Sometimes you need a 3ish line lambda, because you have an beefy if-condition or a try-catch. Too bad multi-line lambdas aren't a thing.
- Function hoisting in JS is actually really nice, not just for the previous scenario. You can define utility functions at the bottom of a function and they'll be available to anything before that definition
- I wish python had a more succinct way to destructure dicts / objects like JS does, outside the new switch statements. (ie doesnt require imports, doesn't require typing the object name over and over.)
- Code completion doesn't work for list comprehensions because the for x in xs comes last :(
apply(lst, () => {
...
...
})
instead of def naming_is_hard():
...
...
apply(lst, naming_is_hard)I've had to deal with too much shit code where lambdas within lambdas are considered hot.
Added bonus, the names are useful (naming is hard because if you do it right you are adding valuable information).
I'm sure there are cases where doing it your way are better, but I can't think of them.
@apply(lst)
def naming_is_hard():
...
I came to python after working in JS fulltime for years, and used to complain about the exact same thing. After I started using decorators, I stopped complaining about the single-line lambdas.For any non-python devs looking at my example, it's equivalent to
def naming_is_hard():
...
naming_is_hard = apply(lst)(naming_is_hard)
It's a nice way to pass functions into other functions, much like how you'd do with a lambda.edit: s/list/lst/g because autocorrect "fixed" the variable name.
In all seriousness I do like them a lot. But like all things one can abuse them and make code unreadable.
Take Kotlin:
result = myList
.filter { it.myValue > 5 }
.groupBy { it.myKey }
.mapValues { entry -> entry.value.sumOf { it.myValue }}
In python: result = {
key: sum(el["myValue"] for el in elements)
for key, elements in groupby(
sorted([el for el in my_list if el["myValue"] > 5], key=lambda el: el["myKey"]),
key=lambda el: el["myKey"],
)
}
to me that's incomprehensible. You have to read it the wrong way, and it's not really clear what the intention behind each step is. Like, the filter is in the middle! keyOf = itemgetter("myKey")
valueOf = itemgetter("myValue")
filtered = (item for item in myList if valueOf(item) > 5)
grouped = groupby(sorted(filtered, key=keyOf), keyOf)
result = {key: sum(valueOf(item) for item in group) for key, group in grouped}From https://docs.python.org/3/tutorial/datastructures.html#id2
> You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. [1] This is a design principle for all mutable data structures in Python.
> Footnotes > [1] Other languages may return the mutated object, which allows method chaining, such as d->insert("a")->remove("b")->sort();.
`import {foo} from ‘bar’;`
This makes reading code really really hard as I can’t tell where some symbol is coming from.
There also seems to be a general aversion against using classes to model types. Instead we have a host of functions that manipulate JSON/dataclasses, which means business logic is scattered around 10 different places!
That's why you use Typescript then you can just hover something or ctrl-click it.
Anyway Python is exactly the same in my experience. Sometimes people `import numpy as np` or whatever but most of the time they `from foo import X, y, z`.
I love JavaScript (yes, I'm one of THOSE people) and like what TypeScript brings to the table but it quickly becomes hard to read as the code becomes more complex.
Python has always had a readability advantage... up to the point where people start doing code golf and nesting multiple comprehensions together.
What would you say it is about TypeScript that makes the code harder to read as it becomes more complex? Just the additional type annotation syntax, extra concepts like generics and/or the accompanying more exotic features of TS, the type definitions physically adding many lines of extra code, something about TypeScript that encourages code to be written in a certain way that is different and more complex?
Note that I haven't touched TS in about two years now, so my memory is a little fuzzy.
Can't really say that for most programming languages with the exception of Go.