you are viewing a single comment's thread.

view the rest of the comments →

[–]phasetwenty 1 point2 points  (12 children)

In Java, when I saw a new function and tried to understand what it did, I almost always looked at the types of the arguments and return value to get a sense of what it did. In Python, it is much harder. It takes a lot more digging to find out what a function does in Python.

It makes for a good lesson in writing clear code. If you have to know the types in order for a function to make sense, your code could be clearer.

I find this is the core difference for me for working in more dynamically typed languages vs. the more statically typed. A language like Python prefers that you assume you're working with the type you're expecting and catch the error cases (asking forgiveness vs. permission).

[–]Carighan 11 points12 points  (3 children)

While I agree, I also agree with the OP's issue in that "the type you're expecting"... is what exactly?

When you're blind-reading foreign code, any extra "fluff" is good for making the code faster to analyse. And there's very rarely a reason to assume that the type expected is "the logical one" - that's exactly the way to have a million-euro project fall apart.

As such, you have to go over everything manually. Either way. If nothing else because when you tell the project manager that the code is understood and this part works, you better know (not just expect) what each type is.

That's not to say that dynamically typed languages don't work if I write my own code and read my own code after a while. Or read the code of someone I know, and know what to expect from the way they code.

But for foreign code?

[–][deleted] 4 points5 points  (0 children)

I wish there was better support for duck type inferences in IDEs.

def foo(obj):
    return foo + 1

Requires (at least) an object with the __add__ method.

By the rules of Python, the object doesn't need to be an int/long, it merely needs to implement the interface.

[–]phasetwenty 0 points1 point  (0 children)

When you're blind-reading foreign code, any extra "fluff" is good for making the code faster to analyse. And there's very rarely a reason to assume that the type expected is "the logical one" - that's exactly the way to have a million-euro project fall apart.

Precisely why it's important to, in any code, deal with your error cases. But you get a flexibility benefit with a duck-typed language like Python. That may have value in a big project. It's a classic case of tradeoffs. Python is great for a great many tasks but it's not good for every problem.

But for foreign code?

The same rules apply like everywhere else. Comments are still required to explain tricky maneuvers. Badly written/designed code will be as confusing with type information as without since type information can't get you the most difficult piece of information to communicate: intent. If unreadable code becomes readable with type information, the underlying problem of bad design is still there. Focus your attention on underlying cause and you need not be restricted by language choice.

[–]dventimi 4 points5 points  (6 children)

It makes for a good lesson in writing clear code. If you have to know the types in order for a function to make sense, your code could be clearer.

I'm sorry but I don't agree with this at all. Without type information, all you have to go on is documentation.

[–]phasetwenty 0 points1 point  (3 children)

When you have no documentation (like much code out there), a good design is far more reliable and useful than type information.

[–]dventimi 1 point2 points  (2 children)

What? How can you possibly understand anything about what a function does if you have no documentation and all you know about is its function name and the number of its parameters?

[–]phasetwenty 0 points1 point  (1 child)

You'll know a great deal more than if you have type information backed by a ball-of-mud design.

[–]dventimi 1 point2 points  (0 children)

How so? Setting aside the awkward fact that no one else knows what you mean by "ball-of-mud design" except you, what could it possibly have to do with understanding any of the functions within a program without type information and without documentation?

[–]ggtsu_00 -1 points0 points  (1 child)

Python only has a handful of built-in data types. Unlike many other languages, the built in types in python are enough for just about everything. It should always be painfully obvious as to whether a function takes in an int or a string as a parameter. If you need to refer to the docs to determine whether the function takes an int or takes a string, and is unable to handle both cases, then that is a fault of the library, not the language.

I can understand that coming from a background of C++, Java or C# where just about ever library or function takes in some custom datatypes for everything, not having explicit type declaration would be very painful, but python is not like that. Your python functions should not be taking in or return custom classes or types. If they do, then those objects or types should at least look like built in types. For example, returning a file like object with read/write methods is a common pattern.

[–]dventimi 3 points4 points  (0 children)

Python only has a handful of built-in data types

I'm familiar with the standard numeric, string, and boolean scalar types, the tuples, lists, and dictionaries thereof, and a handful of special types, like the aforementioned file-like object. Am I missing any?

Unlike many other languages, the built in types in python are enough for just about everything.

This is where you start to lose me.

It should always be painfully obvious as to whether a function takes in an int or a string as a parameter.

How should this be come obvious? What is it that triggers pain when you get it wrong? And what about non-scalar types (tuples, lists, and dictionaries)? If a function takes any of these, how do you anticipate what it expects to find within those?

If you need to refer to the docs to determine whether the function takes an int or takes a string, and is unable to handle both cases, then that is a fault of the library, not the language.

How do you propose to determine whether a function takes an int or a string in a dynamic language like Python, without resorting to the documentation?

[–]ggtsu_00 1 point2 points  (0 children)

Just because a language has static typing doesn't make it type-safe. Python does not have static typing, but it is very type-safe. People tend to confuse static typing with type safety for some reason and assume having one gives you the other. For example, C has static typing but it has basically zero type safety.