19
hitko
1y

Today on "How the Fuck is Python a Real Language?": Lambda functions and other dumb Python syntax.

Lambda functions are generally passed as callbacks, e.g. "myFunc(a, b, lambda c, d: c + d)". Note that the comma between c and d is somehow on a completely different level than the comma between a and b, even though they're both within the same brackets, because instead of using something like, say, universally agreed-upon grouping symbols to visually group the lambda function arguments together, Python groups them using a reserved keyword on one end, and two little dots on the other end. Like yeah, that's easy to notice among 10 other variable and argument names. But Python couldn't really do any better, because "myFunc(a, b, (c, d): c + d)" would be even less readable and prone to typos given how fucked up Python's use of brackets already is.

And while I'm on the topic of dumb Python syntax, let's look at the switch, um, match statements. For a long time, people behind Python argued that a bunch of elif statements with the same fucking conditions (e.g. x == 1, x == 2, x == 3, ...) are more readable than a standard switch statement, but then in Python 3.10 (released only 1 year ago), they finally came to their senses and added match and case keywords to implement pattern matching. Except they managed to fuck up yet again; instead of a normal "default:" statement, the default statement is denoted by "case _:". Because somehow, everywhere else in the code _ behaves as a normal variable name, but in match statement it instead means "ignore the value in this place". For example, "match myVar:" and "case [first, *rest]:" will behave exactly like "[first, *rest] = myVar" as long as myVar is a list with one or more elements, but "case [_, *rest]:" won't assign the first element from the list to anything, even though "[_, *rest] = myVar" will assign it to _. Because fuck consistency, that's why.

And why the fuck is there no fallthrough? Wouldn't it make perfect sense to write

case ('rgb', r, g, b):
case ('argb', _, r, g, b):
case ('rgba', r, g, b, _):
case ('bgr', b, g, r):
case ('abgr', _, b, g, r):
case ('bgra', b, g, r, _):

and then, you know, handle r, g, and b values in the same fucking block of code? Pretty sure that would be more readable than having to write "handeRGB(r, g, b)" 6 fucking times depending on the input format. Oh, and never mind that Python already has a "break" keyword.

Speaking of the "break" keyword, if you try to use it outside of a loop, you get an error "'break' outside loop". However, there's also the "continue" keyword, and if you try to use it outside of a loop, you get an error "'continue' not properly in loop". Why the fuck are there two completely different error messages for that? Does it mean there exists some weird improper syntax to use "continue" inside of a loop? Or is it just another inconsistent Python bullshit where until Python 3.8 you couldn't use "continue" inside the "finally:" block (but you could always use "break", even though it does essentially the same thing, just branching to a different point).

Comments
  • 5
    Yeah, the fact that python lambda can't take statements infuriates me, because like, every other language in the goddamn world can do it... But not python.

    The switch vs match or lack thereof make me question if those deciding the "pythonic" ways had an actual python causing reduced oxygen flow to their brains...

    Alas, I have to deal with python everyday nowadays, so I'd rather not think much about it cuz otherwise I'll get mad, and I'm trying to get drunk instead 😂
  • 1
    Why would you have match statements that can't have a return value? Why? They were so close to making the first step towards a semi-usable functional scripting language but no, they just had to invent something that can't be used without mutating locals.
  • 2
    I'm still pissed that lambdas can't have a block body. Everyone else could do it. Every other language. Python alone had to miss out, because delimiters are bad and therefore so is everything that can only be effectively parsed using delimiters.
  • 4
    TBH it's a major pet peeve of mine with *all* indent-sensitive languages, python, yaml, name it.

    I mean, we can't even resolve the tabs vs spaces war (spoilers: tabs win) and we want syntaxes to be defined by it.
  • 1
    I am quite glad that lamdas can't have more than one statement/line,

    otherwise I can guarantee that the clowns I work with would define ridiculous 20-line lamdas directly in function calls i.e. myFunc(a, b, <some monstrosity>), and it would be an unreadable mess.

    But I do agree that using "case _" as the default case for match is insane
  • 0
    it's like someone decided to take brainfuck, and remove the elegance of simplicity with the unneccessary complexity.

    oh.

    wait.

    i was thinking of javascript.
  • 0
    @tosensei JavaScript is only usable if you pretend it's a variant of lambda calculus. Browsers are pretty good at eliminating copies as well so it's not even that slow.
  • 0
    @lorentz javascript is only usable if you replace with something else.
  • 0
    I see Python hate, I upvote.
  • 0
    @tosensei my brain is wired in a different way towards it vastly preferring JavaScript over Python. I use Python for a lot of cli utilities at work only because it is simple enough for everyone else to pick up. But recently I have been replacing Python with Golang, I tried doing so with Scala, but apparently that one was far too complex for everyone else. So golang and Python it is.
  • 1
    What a load of bull. Python Lambdas don’t support multiple statements who the fuck cares..if you code to a decent level, you shouldn’t be writing anonymous functions anyway
  • 1
  • 0
  • 2
    @jazznoodler

    Anonymous functions make sense when they are supposed to be used in a limited scope, for a very specific purpose.

    They don't needlessly pollute the namespace, and they improve locality.
  • 1
    @AleCx04 I also prefer JS over Python, both are awful systems which somehow make a feature out of making invalid programs not only representable but practically impossible to distinguish from valid ones, but JS is at least understood to be a shit language and there are tools to fix the problems, whereas Python has this tragic attitude problem where people who invested lots of time in it are convinced that the shortcomings are actually features and accentuate them in their own Python libraries.
  • 0
    Python was supposed to be simplicity and less code
  • 0
    @CoreFusionX I don’t believe you ;)
  • 2
    @Ohiorenua simplicity and less code aren't the same thing. Adding delimiters to a sequence is simpler because it eliminates hidden information. Adding types to variables does the same. At optimal simplicity, everything you need to know is explicitly written in the code in front of you. Complexity grows with implications and indirectness.
  • 3
    @Ohiorenua Actually, I'd argue that simplicity is often in conflict with DRY in the case of highly context dependent processes with lots of variation and value components, and the choice of solution is a careful optimization against hidden relations and indirection.

    A function call is always a level of indirection.which moves the answer to the reader's questions one step away from them. On the other hand, a function presents a small interface which enables the reader to ascertain that the behavior isn't dependent on any values that aren't explicitly passed to that function.

    Copying code on the other hand creates a hidden relation between the two instances of the code; the behavior must remain shared and when one is modified the other must be synchronized as well.

    Code quality is a difficult question, but minimizing the number of printable characters is definitely not a productive approach.
Add Comment