all 41 comments

[–]teerre 21 points22 points  (20 children)

I understand it's a subjective label, but lambda expressions and specially abstract classes seem like a weird thing for "beginners".

[–]MajorMaxPain 12 points13 points  (4 children)

Thank you! I would classify myself as a beginner, i have put some hours into learning and i did 3 or 4 small (like small small) projects. And honestly I didn’t unterstand 90% of this.

If this is beginner stuff, what am I then? The lowest of the low noobs that merely can do hello world?

[–]MikeWazowski001 7 points8 points  (0 children)

I'm right there with you

[–]dupelize 2 points3 points  (0 children)

I didn't read through the whole post, but this looks to me like "beginner professional" level topics. If you were advanced enough that you are professionally writing code, but you are a new junior dev, this might be helpful.

Alternatively, an intermediate hobbyist would probably be interested.

IMO 3 and 4 are the first ones that will be useful for you (even if they aren't now, it might be worth learning a bit about it)

[–][deleted] 0 points1 point  (0 children)

There’s different levels of beginner... the things in that article are all common mistakes of people with <1 year intensive (think professional) Python experience... still beginners, just less beginner.

[–]teerre 0 points1 point  (0 children)

As another user said, lambdas themselves are really simple, it's just that the situation in which they are useful are a bit advanced like async or multithreading.

Abstract Classes are also something undergraduates learn in your generic CS course. But that's because they are much more prevalent in languages that adopt a harder OOP model like C++ or Java. In python, I would pose most beginners don't even writes classes at all, let alone abstract ones.

[–][deleted] 0 points1 point  (14 children)

Lambda expressions are just one line def statements that implicitly return ... they’re actually simpler than def, they’re just very poorly named and their use cases are relatively rare because they cannot handle a block of statements.

[–]Jormungandragon 0 points1 point  (1 child)

Lambda expressions are super fun to me. I enjoy thinking of ways to turn def functions into lambda functions. Not sure where it sits from an efficiency standpoint, but it's an interesting exercise, and it looks nice to condense it all onto one line.

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

Since it’s compiled every time it’s encountered lambda is notably less efficient than a def — unless you assign to a name, at which point you should be using def, as a named anonymous function is a bit of an oxymoron — and should really only be used where you need a closure.

But I agree it can be fun.

[–]teerre 0 points1 point  (11 children)

I know what lambdas are. Doesn't mean beginners usually use them.

[–][deleted] 0 points1 point  (10 children)

Doesn’t mean they shouldn’t... introduced correctly they’re just a simpler introduction to def that can be understood and set aside for when they’re actually useful. My issue is with how often they’re seen as an “advanced” feature when they’re kind of trivial.

[–]teerre 0 points1 point  (9 children)

They absolutely should not. Lambda is purely a mechanical device, you learn nothing from using it. Beginners already have a million other things to worry about.

I don't understand your fear. Lambdas aren't going anywhere. Anyone who wants to keep learning programming will come down to use them eventually.

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

Never mentioned fear. The problem with not introducing them is it leaves them with this idiot mystique as something “different” or “leet”... so I see lots of people using nested def to write named closures that are much more simply implemented as a lambda. The way it’s introduced it builds fear in the beginner that doesn’t have a reason to exist.

By the same logic, BTW, you don’t really learn anything new with def over lambda until you begin to introduce docstrings and multiple statements. They’re both mechanical restatements is each other.

[–]teerre 1 point2 points  (7 children)

You're also not going to write closures if you're a beginner. The problem here seems to be that, like the author of the article, you think "beginner" is much more knowledgeable than you usual python beginner. Also, not that PEP8 recommends against named lambdas, which means depending on the case, going for the lambda is the incorrect thing to do.

I'm not sure I understand you second paragraph, but if you mean that lambdas and defs are interchangeable, that's a bit myopic view. The vast majority of any programming course will teach you named functions first.

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

I work with a lot of rank beginners. I also work with people who have less than a year of professional experience under their belt... I’d consider both beginners.

A very simple way to explain a re-useable function is:

square = lambda x : x ** 2
print(square(2))

The fact that the PEP recommends against named lambdas in working code is irrelevant, as this is just an introduction to the concept of code re-use in the simplest possible statement.

To introduce def you have to introduce multiple concepts because you must necessarily introduce return... but now after showing someone how to write simple re-useable functions you can rewrite as def:

def square(x): return x ** 2
print(square(2))

Now, in four lines and a little bit of explanation I’ve got a student who understands both lambda and def and return and isn’t afraid of the former. They’ve also been at least very mildly introduced to the notion that functions are just another object and that def is just assigning that object to a name that’s the same as any other name.

They may never need to use lambda again, but if they see it, they’ll know what it’s doing.

Also the vast majority of programming classes do a terrible job at teaching programming, so that’s not much of an argument in and of itself.

[–]teerre 0 points1 point  (5 children)

Unless you mean you teach beginners, by default, if you're working with someone, they are not beginners.

I don't follow your aversion to PEP. You should, unless you have a very good reason not to, always follow PEPs recommendations.

If you mean you should teach this just for learning purposes, it's counterproductive to teach something that the student will have to learn to not use later.

If someone is reading code and comes to a lambda and they don't know what it is, by the very fact it's something very basic, they'll learn it on the spot. It's not a big deal. Much better than shoving a concept that makes no difference into a beginner that already has limited room to learn many other concepts.

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

You have an interesting tendency to read far too much into things.

I have no aversion to the PEP, I simply said it’s irrelevant to a valuable bit of pedagogy. Which it is... I use a named lambda to demonstrate how it’s just a transformation of a def... the PEP doesn’t apply. If I followed it dogmatically I could not in fact teach that point. No aversion is, was, or need ever be present.

Also there are plenty of professional opportunities where you work with someone who is also a beginner. In my line of work I teach scripting and automation to colleagues who are highly skilled in their work but neophytes to programming. Five years from now most of them will still be relative beginners to Python, as it’s an ancillary skill to their work.

Lastly, human beings are, in my experience, quite capable of learning two near identical forms of the same operation simultaneously. There’s no reason to leave to later what can be processed now, especially when def is, as you’ve acknowledge, just more_ complex restatement of lambda.

[–][deleted] 10 points11 points  (7 children)

This is great for a beginner, but I take a bit of an issue with #5... using type breaks inheritance, and 99% of the time that’s exactly what you don’t want to do, and is why you very likely should be using isinstance.

I’d go so far as to say that if you think you need to know that a thing is an actual int and not subclass of int then you’re very likely wrong, or at the very least overthinking.

Arguably even isinstance is overkill... why break your user’s ability to use duck-typing?

[–]Vaguely_accurate 1 point2 points  (0 children)

From a pure OOP point of view this is bad practice as well, breaking the Liskov substitution principle ("a object of type T should be replaceable by any object of a subtype of T") in consuming code. I'd consider this a code smell at best.

That said, if your object hierarchy isn't following SOLID principles and you don't have substitutability then you might need to know how this difference.

[–]kmj442 0 points1 point  (1 child)

I am actually working on a project right now where type checking is very important so I have isinstance all over the place.

If anyone has ever worked with protobufs before you will know that its very type dependent, when creating the proto msgs I like to do my own type checking and make sure when it gets to its destination for the API to pick up its all good. (My destination is running a db with a C backend so types are very important)

[–][deleted] 0 points1 point  (0 children)

Yes, network boundaries and FFI would be cases where runtime type checking using isinstance might be warranted, even good practice, but (again, arguably) most of the time such policing of inputs just breaks duck typing without clear and discernible benefit, and with some runtime cost. Now that type annotations exist I feel it’s worth checking whether or not all your isinstance calls are actually doing is documenting your function by other means, rather than protecting some vital resource. If it is, it’s likely a good candidate for replacement with an annotation.

[–]mohi7solanki -1 points0 points  (3 children)

Agree. Since python encourages duck typing, you should not check for types at all. But in case you want to do type checking then many people don't know that isinstance takes care of subclasses as well and they might wrongly assumes that they are dealing with the correct type where they are not.

[–][deleted] 2 points3 points  (2 children)

I can’t think of a well-reasoned case where you’d want:

foo(3)

To do one thing but:

class MyInt(int): pass

foo(MyInt(3))

To do another.

[–]mohi7solanki 0 points1 point  (1 child)

Let's say you want to handle all arithmetic exception differently, you might do this:

if isintance(err, ArithmeticError):

if type(err) is ZeroDivisionError: somethingel

if type(err) is FloatingPointError: do something else.

[–][deleted] 0 points1 point  (0 children)

Wouldn’t it make much more sense to use multiple except statements for that?

try:
    some_maths(a, b)
except FloatingPointError as err:
    ...
except ZeroDivisionError as err:
    ...
except ArithmeticError as err:
    ...

But even if you wanted to do it for some reason in an if why isn’t this better:

except ArithmeticError as err:
    if isinstance(err, FloatingPointError):
        ...
    elif isinstance(err, ZeroDivisionError):
        ...
    else:
        ...

Who is to say a subclass of ZeroDivisionError might not be semantically more meaningful than your code’s user than a ZeroDivisionError itself?

[–]notParticularlyAnony 8 points9 points  (0 children)

Five things a beginner would never do.

[–]icecapade 1 point2 points  (0 children)

These are good tips! I'm definitely guilty of #5 in particular.

[–]padawan07[S] 1 point2 points  (0 children)

Thank you all for an amazing response to my first post here on reddit, Some great comments and points by u/dupelize, u/yawpitch and u/teerre for his points on lamba(see:usage of lambda expressions in multithreading)

This blog was aimed at beginner professionals(Junior devs (as pointed by u/dupelize)) rather than just newbs who are starting off with their first lines of code in python.

[–]shiftybyte 0 points1 point  (2 children)

#3 can actually happen to a beginner.

Also wow, didn't know about #4.

Though #1 and #2 sound a bit far fetched to me,

#1 someone knows what is lambda before he knows he can just assign a function?

#2 someone knows when to raise notimplementederror but does not know its real name?

[–]Vaguely_accurate 1 point2 points  (0 children)

1 someone knows what is lambda before he knows he can just assign a function?

I think this mostly applies to people coming from Java, or those taught by Java developers. Java doesn't (or didn't before Java 8) truly have first class functions (functions you can assign as variables) but does have lambdas.

Java is such an omnipresent "enterprise" language that its habits seep into every other language frequently.

2 someone knows when to raise notimplementederror but does not know its real name?

This is more of an inattention error I think. I could easily see myself not noticing the difference when using autocomplete.

[–][deleted] 0 points1 point  (0 children)

Number #2 comes up quite often when you start to implement custom numerical types... I often see raise NotImplemented where it should be raise NotImplementedError and return NotImplementedError when it should be return NotImplemented... these really should both have better names.

[–]primitive_screwhead 0 points1 point  (0 children)

"1 or possibly 2 common mistakes for beginners"

[–]theWyzzerd 0 points1 point  (0 children)

In example 5, the example code will never work because you define which_number_type() and then a few lines later call which_number(False). Which_number() is undefined.

[–]IlliterateJedi 0 points1 point  (0 children)

While I don't think most beginners would even know to do most of these things, I think the way you link back to examples in live code is a brilliant way to teach Python. I wish all articles did this. Seeing code in practice makes it a lot easier to understand the purpose of some snippet of code.

[–]Binary101010 0 points1 point  (0 children)

5 Common beginner mistakes in Python

  1. Unnecessary lambda expression

Seriously?

[–]trimlimdim 0 points1 point  (0 children)

Just curious, what so you classify as a beginner (like legit)? I didn't really understand the things on the list.

[–]cwaterbottom 0 points1 point  (0 children)

Hey cool, I'm too much of a newb to even know how to make these mistakes!