3 ms·
I have had a somewhat unearned distaste for Python for the last decade or so. I mostly just don’t like some of the design decisions it made. I don’t like that
by tombert 1y ago
I have had a somewhat unearned distaste for Python for the last decade or so.
I mostly just don’t like some of the design decisions it made. I don’t like that lambdas can’t span multiple lines, I don’t like how slow loops are, I don’t like some functions seem to mutate lists and others don’t, and I am sure that there are other things I missed.
But it really comes down to the fact that my career hasn’t used it much. I occasionally have had to jump into it because of scripting stuff, and I even did teach it for a programming 101 course at a university, but I haven’t had a lot of exposure otherwise.
For scripting stuff for myself, I usually end up using Clojure with GraalVM (yes I know about babashka), or nowadays even just a static linked compiled language like Rust.
I don’t really understand why people think that compiled languages can’t be used for scripting (or at least task automation), honestly. Yes you have to add a compilation step. This involves maybe one extra step during development, but realistically not even that. With Rust I just do cargo run while developing, I don’t see how that’s harder than typing Python.
- Joker_vD 1y agomsedit main.py && ./main.py !! !! But indeed, pressing F5 solves that for both Rust and Python
- dec0dedab0de 1y agowhy would you want a lambda to span multiple lines? How would that be any better than a function?
- tombert 1y agoBecause sometimes I want to have logic that spans multiple lines and I don't want to assign it a name. An easy example might be something with a `map` or a filter. For example, in JavaScript [1,2,3,4].filter(x => { let z = x * 2; let y = x * 3; let a = x / 2; return (z + x * a) % 27 == 2; }); Obviously I know I could name this function and feed it in, but for one-off logic like this I feel a lambda is descriptive enough and I like that it can be done in-place. You're free to disagree, but I think there's a reason that most languages do allow multi-line lambdas now, even Java.
- frutiger 1y agoOff topic: you didn’t use y.
- tombert 1y agoYou are right! Obviously this is just an ad hoc thing I wrote to show a point but I shouldn't be using superfluous variables.
- ddejohn 1y ago> Obviously I know I could name this function and feed it in, but for one-off logic like this I feel a lambda is descriptive enough and I like that it can be done in-place. FWIW, you'd also have the benefit of being able to unit test your logic.
- tombert 1y agoI mean, maybe, that's why your lambdas shouldn't be too long. I have done a lot of Haskell and F#, and I'm very familiar with the concept of "lifting", and yeah being able to individually test the components is nice, but even within Haskell it's not too uncommon to use a lambda if the logic doesn't really need to be reused or is only a couple lines. If you have a huge function, or you think there's any chance of the logic being reused, of course don't use a lambda, use a named function. I'm just saying that sometimes stuff that has 2-4 lines is still not worthy of having a name.
- dec0dedab0de 1y agoHonestly, I don't really see the appeal of unnamed functions in general. I so rarely use lambdas that I wouldn't really miss them if they were gone. Just occasionally as a sort key, or in a comprehension. I have seen people do this in JavaScript quite often, but I always assumed there was some kind of underlying performance benefit that I didn't know about. As I think about it I guess it makes sense if you're passing a function to a function and you just want it to be concise. I could imagine using something like that off the top of my head, but then pulling it apart and giving it a name the moment I had to troubleshoot it. Which is how I currently use nested comprehensions, just blurt them out in the moment but refactor at the first sign of trouble. I think maybe I just have trouble seeing some of the braces and stuff, and it's easier for me to reason about if it's named. I guess that's why we have 32 flavors. Thanks for answering me honestly I really do appreciate it, even if my tone came off as dismissive. Sometimes I don't realize how I sound until after I read it back.
- rs186 1y agoIf your style is doing a lot of functional programming, multi-line lambda is a very natural thing to do. Other times you want to use a variable or several variables without actually passing it around as an argument. It makes sense especially if you are already used to it in Java/C++/JavaScript/Go. Is it "better" than a named function? No, of course, they work mostly the same. But we are not talking about better or not. We are talking about syntax just for the sake for syntax, because some people prefer to write code in a way you don't necessarily care about.
- dec0dedab0de 1y agoThis makes a lot of sense, I got to a similar conclusion in my other reply. I always thought the appeal of functional programming was more about test-ability and concurrency, it never occurred to me that people actually preferred the syntax.
- tombert 1y agoCan't speak for anyone else, obviously, but part of the reason that I got into functional programming is specifically because I found the syntax very expressive. I felt like I was able to directly express my intent instead of describing a sequence of steps and hope that my intent comes to fruition. Different strokes and whatnot, not everyone likes functional programming and of course there are valid enough criticisms against it, but I've always appreciated how terse and simple it feels compared to imperative stuff. Even with regards to testability, if your function is pure and not mucking with IO or something, then even using a multi line lambda shouldn't affect that much. You would test function calling it. Keep in mind, Haskell doesn't really have "loops" like you'd get in Python; in Python you might not necessarily need the lambda because you might do your one-off logic inside a for loop or something. In Haskell you have map and filter and reduce and recursion, that's basically it.
- internet_points 1y ago> Haskell doesn't really have "loops" weeell, you can still do stuff like this in Haskell: import Data.Vector.Mutable ... let n = length vec forM_ [0 .. n-1] $ \i -> do next <- if i < n-1 then read vec (i+1) else pure 0 modify vec (+ next) i -- increase this value by next value it's just in many cases the functional machinery is so accessible that you don't need to reach for for-loops.
- bko 1y agoThe most insane python feature is that for loops keep their intermediate variable. for x in [1,2,3]: print(x) x sticks around! So you'll always have these random variables floating around, and hope you don't use the wrong one. And to add insult to insult to injury, if you're using mypy for type checking you'll get a nice error if you try to reuse x with a different type: for x in ['a', 'b', 'c']: print(x) << Incompatible types in assignment (expression has type "str", variable has type "int") [assignment] And the types I can never trust. I've used all the tooling and you still get type errors in runtime. It's also ridiculously slow. I would also like optional chaining (e.g. foo?.bar?.baz) and a million other features that other high level programming languages have.
- nickdrozd 1y ago> The most insane python feature is that for loops keep their intermediate variable. "Insane feature" is a generous way of describing this behavior. I would say it is just a stupid bug that has managed to persist. Probably it is impossible to fix now because of https://xkcd.com/1172/ https://xkcd.com/1172/ How typecheckers and linters should deal with this is a tricky question. There is how the language ought to work, and then there is how the language actually does in fact work, and unfortunately they are not the same.
- ActorNightly 1y agoComments like this basically should say "I want as much handholding as possible" Lucky for you, LLMs are pretty good at that these days. >And the types I can never trust. I've used all the tooling and you still get type errors in runtime. It's also ridiculously slow. IDE integrated mypy checking does this in the background as you type. As for errors, it all has to do with how much typing you actually use. You can set the IDE to throw warning based around any types or lack of type annotation. Again, handholding.
- deleted 1y ago[deleted]