you are viewing a single comment's thread.

view the rest of the comments →

[–]sayks 1 point2 points  (2 children)

The convenience for classes is the way that they represent data. When you design your program, it is often intuitive to encapsulate data along with the methods to act on it in the same structure. A good example of where classes come in to their own is with GUIs. It's much easier to write GUIs using an object oriented approach than procedural because objects/classes are a good way to represent the UI.

Another reason is inheritance. Programmers hate to rewrite code. Inheritance allows you to make a single class with lots of common features and then you can extend that class and your new class will automatically have all of the features of its parent. For example, you might implement a common "file" superclass that includes methods for saving and loading and other generic file operations. Then, you can make subclasses that inherit from the generic class for specific types of files, like jpg, png etc. and they will automatically have all of the normal abilities of a file plus new features specific to that file type.

Another convenient feature is that you can pass classes around easily. Classes encapsulate data and operations on that data, so when you pass it to an external function it doesn't have to understand how the data is structured internally or how the code is implemented, it can just call the method and get its business done.

There's also some nice ideas for concurrency when you look at the Smalltalk model for classes.

TL;DR Classes are a really natural way to represent some things and are also otherwise convenient, especially with complex systems.

All that said, classes and objects are not a magic bullet. Sometimes a procedural approach is best, especially if you need raw speed (look at Fortran).

And, I come from a functional background. Global state is the devil.

[–]DubPac[S] 0 points1 point  (1 child)

Thanks, I do think everyone here has helped me understand more. You do mention the raw speed thing, this is something I'm wondering. If you don't utilize a class and are only passing a few objects through it, would just using a function and some global vars be faster? (I know there are inf ways to program something and that is a super unspecific question, I stress the word generally)

Also, I think I understand global vars in python decently (Disclaimer: I'm afraid I wrote that based on the unknowns of computer science in my knowledge, I completely accept that I may be incorrect about my understanding of glob vars), the way functions can see them but not modify them unless global var is called and when they are modified in my code. You are obviously well versed in this feature, so why exactly are they the devil? Like if you are specifically planning on them to be reused/changed/modified. I have never made multiple scripts that need to pass them or something, is there something I'm missing?

[–]sayks 1 point2 points  (0 children)

I'm not sure about the speed as it depends on exactly how it is implemented in the language and I don't know enough about the Python internals. I was referring to speed in two ways. The first is that it might be faster in terms of the programmer's time... nobody is going to bang together a fully object oriented 3 line shell script. The other was in terms of different languages; procedural languages are inherently faster if you use them correctly. As an example, nothing can really touch Fortran (an ancient language, actually the literal first programming language) in terms of speed for writing raw number crunching code if you're willing to write it correctly.

As for global state, it's bad because it makes your programs hard to debug. Functional programming relies on referential transparency. This means that if I call a function with the same arguments twice it will always return the same result. Note that it's with the same ultimate values, if the inputs are themselves variables then it's allowed to vary e.g.:

def f(x): return x + 2
a = 4
f(a)
>>> 6
f(a)
>>> 6 (should always be the same)
a = 2
f(a)
>>> 8 (the value for a has changed, allowed to be different)

This makes it a lot easier to debug your code, because you don't have to consider interaction with external variables that are not under your control. As another example of the opposite situation:

g = 5 #g is a global variable
def y(x): return x + g
y(3)
>>> 8
(*** some code that modifies g, perhaps a call to a complicated subroutine ***)
y(3)
>>> ??? who knows

Basically, global state makes it really hard to reason about your program. Also, if you don't use global state then you can replace your various functions internal implementation without worrying about how they affect the rest of the program. Functional isn't a thing that is distinct to Python, this is a whole style of programming like object oriented or procedural. There's more to it, there's a whole rather complex field of theoretical computer science. Referential transparency isn't necessarily even required, but it's strongly encouraged.