Live data from Hacker News

Stop writing lambda expressions in Python

treyhunner.com

181–190 of 202 posts

Re: Stop writing lambda expressions in Python

#181

Earlier quoted context omitted.

There's real readability and clarity to positioning an anonymous function right at the point in the code that it will be used. When you name and define a function some other place and use it elsewhere, you have increased the overall complexity. What is this named function? Where is it used? Is it accessed by other bits of code? Should it be? All these questions come up when you see a named function. It is in fact les…

I actually think that positioning an anonymous function at the site where it’s used is extremely unreadable and unintuitive. I work in Scala and Haskell a lot so I see it all the time and I’m usually forced to write code that way to stick to local conventions, and I despise it. It makes no sense at all to break up the wonderful conceptual flow of functional components like map, fmap, filters, folds, monadic operation…

It comes down to a preference thing.

I want to read code like an essay. I don't want to have to jump to a function definition to figure out what `thingExtractor` does. To me, that's like taking a book and rearranging the chapters in alphabetical order. No, put them in chronological order. Don't define a function three "chapters" ago in your code and then expect me to remember it if you're only going to use it once. I wouldn't read Ikea instructions that way, why should I read code that way?

But again, personal preference. And you don't have to choose either/or -- I love that Javascript's anonymous and named functions are so similar because it means you can switch between the two styles with basically zero cognitive overhead.

I will say, having worked in large enterprise before, I have seen bugs come out of people not inlining code and instead attaching it to classes or leaving it otherwise accessible. Specifically, people will use functions that are intended to be method-specific in other places. Even if those functions are well-written and don't have side-effects (which is often not the case), the original author still doesn't know that other people are now depending on them as an API.

So later on the code gets refactored and those methods get changed or removed, and suddenly you have a broken build. That's something you can partially mitigate by making a function private (although not entirely, because I've also seen it happen in code within the same class/scope). Python doesn't have true privates, but you can also mitigate that problem by just using code reviews to force people to respect `_`. In practice, I often found that it was easier to make the function anonymous, so everyone knew 100% that it was only being used in exactly one place.

Re: Stop writing lambda expressions in Python

#182

Earlier quoted context omitted.

Private functions do not restrict the usage of that function to one point in the code. There's a world of difference between a coding convention - essentially a comment to say "please don't access this function from outside the current class" versus it simply being impossible to do so. And the "private" convention does not say "don't use this function at any other point except one", it says "please don't access this…

As a user of JavaScript and es6, fat arrows are only necessary if you haven't started using async and await syntax, and I found myself almost never using fat arrows after moving to async/await. Indeed naming my functions resulted in more testable and clearer code.

Getting rid of fat arrows is one thing, but I use async/await pretty much all the time, and I still use anonymous functions in my code.

  await (async function () {
    //Do a thing
  }());
I don't think async changes anything about how useful or problematic an anonymous function is.

Re: Stop writing lambda expressions in Python

#183
post #85

Earlier quoted context omitted.

There's real readability and clarity to positioning an anonymous function right at the point in the code that it will be used. When you name and define a function some other place and use it elsewhere, you have increased the overall complexity. What is this named function? Where is it used? Is it accessed by other bits of code? Should it be? All these questions come up when you see a named function. It is in fact les…

Python has a convention for "private" functions, which is to prepend "_" to the name. > It's hard to make a strong case just in words, but once you really understand the power of the fat arrow syntax for anonymous inline functions then you use it more and more and it becomes second nature and the programs you write have a completely different style, oriented towards neatly positioned inline anonymous functions everyw…

> Python also believes that you do not need to defend against this possibility, as long as you make it clear to other developers that they should not call your "private function".

Python has apparently never worked in a large, corporate environment with a multinational team.

Yes, in theory you can just not call private methods. And in my own personal code I don't care much about restricting variable access, because I trust myself. However, it is a tremendous amount of work to get a company culture to start respecting privates if they aren't already. I've had so many phone calls trying to explain why "yes, you can technically call this function, but in reality you can't, and I don't care that your deadline is tomorrow, you still can't. And yes, I know that technically you're on a separate team and not under my jurisdiction, but you can't just remove me from the code review and call all of my library's private functions anyway."

It's taking the path of most resistance. True privates are very helpful on large teams.

Re: Stop writing lambda expressions in Python

#184

Earlier quoted context omitted.

As a user of JavaScript and es6, fat arrows are only necessary if you haven't started using async and await syntax, and I found myself almost never using fat arrows after moving to async/await. Indeed naming my functions resulted in more testable and clearer code.

Getting rid of fat arrows is one thing, but I use async/await pretty much all the time, and I still use anonymous functions in my code. await (async function () { //Do a thing }()); I don't think async changes anything about how useful or problematic an anonymous function is.

That feels like a weird pattern (for one because you can have async fat arrows), but also because in general I find

    await request_some_data()
much clearer than

    await (async () => {
        // just make the async request inline
    })()

Re: Stop writing lambda expressions in Python

#185

Earlier quoted context omitted.

Getting rid of fat arrows is one thing, but I use async/await pretty much all the time, and I still use anonymous functions in my code. await (async function () { //Do a thing }()); I don't think async changes anything about how useful or problematic an anonymous function is.

That feels like a weird pattern (for one because you can have async fat arrows), but also because in general I find await request_some_data() much clearer than await (async () => { // just make the async request inline })()

When arrow functions were first released, they didn't support the `async` keyword. I guess that wasn't fixed until ES2018? Maybe earlier - I think Babel would compile them pretty early on. Regardless, some people who adopted async patterns early got into the habit of avoiding arrow functions entirely, so it wouldn't be crazy to me to hear someone say, "I used arrow functions before I learned async."

Otherwise, this is just restating the same arguments people already made above.

There's no practical reason why

  (() => {
  
  }());

would be useful but

  await (async () => {
  
  }());
wouldn't be. The scenario you're talking about where async code removes the need to have an anonymous function only makes sense if you were only using anonymous functions for callbacks. In practice, that's not the only (or even primary) use case for people who advocate inlining code in Javascript. They're specifically advising against the pattern where single-use functions are given names and removed from program flow.

Re: Stop writing lambda expressions in Python

#186

Earlier quoted context omitted.

Getting rid of fat arrows is one thing, but I use async/await pretty much all the time, and I still use anonymous functions in my code. await (async function () { //Do a thing }()); I don't think async changes anything about how useful or problematic an anonymous function is.

That feels like a weird pattern (for one because you can have async fat arrows), but also because in general I find await request_some_data() much clearer than await (async () => { // just make the async request inline })()

[deleted]

Re: Stop writing lambda expressions in Python

#187

Earlier quoted context omitted.

That feels like a weird pattern (for one because you can have async fat arrows), but also because in general I find await request_some_data() much clearer than await (async () => { // just make the async request inline })()

When arrow functions were first released, they didn't support the `async` keyword. I guess that wasn't fixed until ES2018? Maybe earlier - I think Babel would compile them pretty early on. Regardless, some people who adopted async patterns early got into the habit of avoiding arrow functions entirely, so it wouldn't be crazy to me to hear someone say, "I used arrow functions before I learned async." Otherwise, this i…

Correct, and I fundamentally disagree with that pattern. If it's more than a single expression, it's doing something complex enough to deserve a name or to be mocked in tests, etc.

Re: Stop writing lambda expressions in Python

#188
post #116

The crippled nature of Python's lambdas are a big weakness of Python. They sit in a no-mans land of providing half a solution but being too crippled to actually to clarity / improve programming style. I much prefer languages that go all the way and give you full integration like Ruby, ES6 and Groovy. For example, in Groovy closures just blend completely into the language: [1,2,3,4,5].grep { it > 3 }.collect { it * 5…

Your Apache Groovy example doesn't work in Jenkins Pipelines, which cripples Groovy so the functional methods such as `collect` don't work.

You wrote elsewhere that

> I won't miss Grails because I think that, a bit like Gradle, it is an antipattern use of Groovy - needlessly applying its dynamic features where they are not even required

Groovy was designed as a dynamic language to complement Java. Its static compilation was tacked on much later, whereas Kotlin and Scala, like Java, were designed to be statically typed from the ground up, and they, unlike Groovy, also run on other platforms besides the JVM. If you're not going to use Groovy's dynamic features, you might as well use Java, Kotlin, or Scala.

Re: Stop writing lambda expressions in Python

#189

Python really needs much better anonymous functions - Lambda expressions just don't cut it. To be clear, what Python does need is multiline, inline anonymous functions. In JavaScript/ES2015, the fat arrow function syntax is just remarkably powerful in its ability to simplify code. I would go so far as to say that the ES2015 fat arrow syntax completely changed the way my programs are written, increasing power and redu…

Python is fundamentaly flawed, since it's based on lines (and significant indentation), and foremost, since it's based on statements, and not only on expressions. Lambda expressions look in python like a sore spot, because Python stresses so much statements, and procedural programming. IIRC, recently we've seen passing a paper in hacker news, that let beotians write programs, and only ~10% IIRC (or less) of their ute…

beotians?

Re: Stop writing lambda expressions in Python

#190

Python really needs much better anonymous functions - Lambda expressions just don't cut it. To be clear, what Python does need is multiline, inline anonymous functions. In JavaScript/ES2015, the fat arrow function syntax is just remarkably powerful in its ability to simplify code. I would go so far as to say that the ES2015 fat arrow syntax completely changed the way my programs are written, increasing power and redu…

How exactly does not naming your functions make your code more powerful and less complex?
Post reply on HN