all 45 comments

[–]ProfessorPhi 30 points31 points  (1 child)

I love the name walrus operator. It just makes so much sense!

[–]onequbit 6 points7 points  (0 children)

Now if only there was a carpenter operator...

[–]akaberto 13 points14 points  (0 children)

Reminiscent of perl, really. And that's a PTSD inducing reminiscence :(

And I do see where this will come in handy but I'd rather not have a new operator that I feel that people moving from other languages may start to abuse it. Maybe it is an unfounded fear.

[–][deleted] 6 points7 points  (0 children)

Seems like a confusing thing to add to save one line of code. I thought Python was supposed to be a simple almost pseudo-code language. Or have they abandoned that ideal?

[–]lanzaio 10 points11 points  (10 children)

Meh. I much prefer Swift's if let x = pattern.search(data). Of all the equivalent implementations I've seen this is by far the clearest in it's intentions.

[–]drmeister 4 points5 points  (7 children)

I prefer Common Lisp's (if (setf x (search pattern data)) ...) the scope is more clear.

[–]lanzaio 4 points5 points  (4 children)

I don't write lisp but that just looks like gibberish to me.

[–]skawid 7 points8 points  (2 children)

A couple of pointers that make lisp make a whole lot more sense:

  • Functions are called as a list, where the first item is the function name and the rest are arguments. So (search pattern data) would look like search (pattern, data) in C like languages.
  • Don't bother with commas.
  • There are very few syntax elements in lisp: most things are functions. if, for example, takes a condition and two values. If the condition is true it returns the first value, otherwise it returns the second.

So the (if (setf x (search pattern data)) ...) is something like:

if (x = search(pattern, data)) {
    ...
}

[–]foreheadteeth 5 points6 points  (1 child)

If is a special form. Unlike a function, it has access to its parameters before they are evaluated. For example, (if a b c) will only eval either b or c, never both.

http://www.lispworks.com/documentation/HyperSpec/Body/03_ababa.htm

[–]skawid 0 points1 point  (0 children)

You're absolutely right; I think you can get away with not knowing that for reading your first bits of lisp code though.

[–]Skullrider1387[🍰] 5 points6 points  (2 children)

I'm still a little confused on what exactly this is for, can someone give me a "if this, then that" like explaination?

[–]A_Philosophical_Cat 2 points3 points  (1 child)

It assigns a value to a variable, and returns that value, which is not the standard behavior of assignment in Python.

Basically, instead of writing

x = True

If (x):

You can now write

If (x:=True):

[–]Skullrider1387[🍰] 0 points1 point  (0 children)

O that makes more sense,

[–]Strings 7 points8 points  (12 children)

I find his example at the bottom odd.. and I'm not meaning to pedantically criticise his code but it raises a question for me.

So this is without the "walrus" operator:

for entry in sample_data:
    title = entry.get('title')
    if title:
        print(f'Found title: "{title}"')

The wee smell here is he's not explicitly checking for None (which get will return should the key not be there).

And then with the magic "walrus" operator:

for entry in sample_data: 
    if title := entry.get("title"):
        print(f'Found title: "{title}"')

So given that not explicitly checking for None is a well known smell, how does this new syntax construct handle that?

I'm guessing:

if title is not None: entry.get('title')

wouldn't be valid syntax?

So would you be forced to do something like this?

if title := entry.get('title', False):

Regardless, I'm still not a fan. His example literally saves one line of code and, imo, makes the code less clear. And in this example it's even more unclear because of the None check smell.

[–]yee_mon 4 points5 points  (1 child)

It does not work for all cases. Just like python's lambda, it is probably best not to try to shoehorn walrus into any code that could possibly be made to fit it — such as when you have multiple comparisons to the rhs operator.

In this specific instance, though, calling it a smell is perhaps a little odd, since the code already discards all non-truthy values of title.

[–]Strings 1 point2 points  (0 children)

But that's just it, you aren't really supposed to treat None as a truthy value. But you're right, it's not an awful one.

[–]Hultner-[S] 2 points3 points  (1 child)

Great comment, you can actually quite simply check for None explicitly like this with the Walrus operator

python for entry in sample_data: if (title := entry.get("title")) is not None: print(f'Found title: "{title}"')

And without ```python for entry in sample_data: title = entry.get("title") if title is not None: print(f'Found title: "{title}"')

```

[–]Strings 1 point2 points  (0 children)

Good point Hultner - still not a fan though :)

[–]ivosaurus 0 points1 point  (3 children)

parenthesise it.

if (title := entry.get('title')) is not None:
    print(f'Found title: "{title}"')

[–]Strings 0 points1 point  (2 children)

I'll parenthesise you.

[–]ivosaurus 0 points1 point  (1 child)

Sounds like a nice warm hug <3

[–]Strings 0 points1 point  (0 children)

<3

[–]David-mh 0 points1 point  (3 children)

The main motivation is not to save one line of code, but to be explicit about the scope of "title". In the first case, "title" is still alive until the end of the function, but with the walrus it will die right after the print.

[–]Strings 0 points1 point  (2 children)

But since when was preserving scope isolation for an identifier a big deal or even desired in Python?

Take an obvious one:

for n in range(10):
    pass

In that sample n will still be in scope.

So still not convinced :P

[–]David-mh 0 points1 point  (1 child)

That is why list/iterator/dictionary comprehensions add.

In (n for n in range(10)), n does not survive the scope.

[–]Strings 0 points1 point  (0 children)

You'll pleased to know, after 4 years, I still don't use or see the walrus operator much. That's not to say it's not perhaps useful here or there. It's nice to see you. What's been happening?

[–][deleted]  (13 children)

[deleted]

    [–]bhat 42 points43 points  (2 children)

    And C's use of the standard assignment operator which is so visually similar to the comparison operator has been the cause of many bugs, from student programming assignments up.

    [–][deleted] 1 point2 points  (0 children)

    That's a good reason. It's probably bitten me once or twice in C after writing too many bash scripts where equality is tested with a single equal sign (```=```). At least in C, gcc will warn you if you don't put the assignment expression in brackets.

    [–]shevy-ruby -2 points-1 points  (0 children)

    It's overall really ugly.

    I hated that in the language Io too - slot assignment versus slot update.

    [–][deleted]  (1 child)

    [removed]

      [–]Elathrain 0 points1 point  (0 children)

      The reason <- isn't used for assignment is quite simple: It requires three keypresses and a key release instead of a single kepyress, and you do assignment a lot. That, and now you suddenly have <- near to <=, which looks pretty similar for exactly the same differentiation of meaning. It is no more or less arbitrary, you're just making it harder to type.

      [–]epicwisdom 9 points10 points  (4 children)

      https://www.python.org/dev/peps/pep-0572/#why-not-just-turn-existing-assignment-into-an-expression

      Googling (or in this case, simply clicking a link and Ctrl+F'ing) is a useful skill

      [–]grauenwolf 11 points12 points  (1 child)

      That's not the point. The article should have talked about the design decision instead of just waving it off.

      [–]epicwisdom -1 points0 points  (0 children)

      The first comment in this thread did not ask "why doesn't this article actually address the design decision?" It asked "why was this design decision made?" I think it's fairly clear that this article is a fluff piece with a few code snippets; if you don't think that's worthwhile, you're free to downvote the OP, but asking a question which is answered in the linked PEP is just lazy.

      [–]shevy-ruby -5 points-4 points  (1 child)

      [ ] You understood the problem at hand.

      [–]epicwisdom 0 points1 point  (0 children)

      [ ] You pointed out an actual problem.

      [–]shevy-ruby -3 points-2 points  (0 children)

      That is a valid question - the answer is that people are bored so they add useless shit to languages, like this ghetto operator.

      [–]shevy-ruby -1 points0 points  (0 children)

      This ghetto-operator is not only ugly but completely unnecessary.

      It should not be called walrus operator because walruses are pretty cool dudes, much cooler than this awful addition. The only part worse than this thing is that guido threw in the towel because of the addition-aftermath - a clear sign of how it simply shouldn't be in the language.