My question is, and I've wondered this back when I was learning Ruby and Python. Can you really say you are passing the wrong variable type into a function with languages that aren't strongly typed? I mean, at that point, the language is doing it all for you, so if the wrong thing is going into the function, wouldn't that be a fault of the language and not the programmer?
I'm learning this strictly because I want to broaden my skillset. I agree, dynamically typed languages seem just silly, but at the same time I can't argue that they are widely used.
And I just want to get into web development since I've never dabbled in that.
But yeah, at work we have a piece of software running mostly on Python, and I've been assigned to maintain and upgrade this software. Trying to read through that code is such a pain in the ass. I can't ever trace back to see what exactly is supposed to be in this variable. For example, I kept seeing errors in the logs about something not being a member of this variable. So I go look at the code, find the line in question, but the variable is not named to identify the type it should be, and of course there's no explicit type system so I had no idea how to figure out what object was being pointed at by this variable.
It shouldn't be that difficult. But I see what you guys are saying. To work well with dynamic code, think of a variable as a box containing something. Now in C++ that box would be labeled 'int' and you would know what is inside. But in dynamic code you can have anything inside that box.
When I was programming in JS I would use... alert(someVariable);
In this way I could peek inside the box before shipping it to a function.
Not that big a deal, really.
It's not that it's hard to grasp, it's that it's unsafe, and to make it safe, you have to do ridiculous unwieldy things like:
1 2 3 4
def foo(a, b, c):
if type(a) is not int or type(b) is not int or type(c) is not int:
raise TypeError('foo only accepts integral types')
whereas in a statically-typed language, you rarely need to do anything like that. In C++, on those infrequent occasions where I need to check the type passed to a template, I do so at compile time:
1 2 3 4 5
template <typename T>
void foo(T a, T b, T c)
static_assert(std::is_integral<T>::value, "foo only accepts integral types");
there's no checking done at runtime. It's easier, it's safer and it runs faster. Imagine if foo were to be called in a tight loop? It's a waste of time. Even a managed language with static typing, like C#, doesn't have that problem.
I can agree that duck typing generally isn't safe and it is a pain in the ass sometimes to make it safe (Like in your example). That is why you should always know what you are passing around and what goes where.
For example if you don't know what goes into a certain function parameter read the documentation on it. In python this can be as easy as using help() or browsing the online documentation (Which sucks in my opinion).
So yes there are some problems with dynamically typed languages but then again there are some things that only dynamically typed languages can do or can do much better.
Basically in the end to me it comes down to what I need to do. If I building a large project like a full scale game project then yes I am not going to choose a dynamically typed language like Python for the base language most likely.
But if I am just building a little program to help me do a specific task like managing all my updates I need to run every week, or managing my daily backups to my server then yes I am probably going to use a dynamically typed language like Python.
For example lately I have been delving into security related programming and Python has been amazing as putting together simple little tools that would have took me a lot longer to accomplish in a statically typed language.
Each language will have it's pros and cons and each language is naturally suited for certain tasks. They are all just tools to accomplish a task in the end and it would be a bad choice in my opinion to rule any of them out just because they are unfamiliar or they don't work the same as what you are used to.
It's just a different approach to OOP; it's called prototype-based programming. The short of it is that you use existing objects as prototypes for new ones, like inheritance in a "normal" object-oriented language.