What is a strongly typed language? Are dynamic languages like Python and Ruby automatically weakly typed? Is strong just another word for static and weak just another word for dynamic? I’m lost… help me Fleebie!
#1 Dynamic Vs Static
First step to avoid confusion : Don’t mix Dynamic/Static typing with Strong/Weak typing. Ruby, for example, is dynamically and strongly typed at the same time (more on that later).
Example of a language statically typed :
int x;
x = 3;
x = "hello"; //ERROR!
Example of a language dynamically typed :
x = 3
x = "Transformers seems to be a boring movie"
x = :why_are_we_here
x = /is this a reg ex/
x = "enough already... I think we understand"
When we talk about dynamic typing, we talk about a mechanism where the type of a variable can change and be resolved on the fly at the exact moment it gets parsed by the interpreter.
When we talk about static typing, we talk about a mechanism where the type of a variable is resolved in advance by the interpreter/compiler. With statically typed languages, you cannot say that x is a string and, a few lines after, that it is an integer. That’s all there is to say about it.
As you already know, Ruby is dynamically typed. Javascript falls in the same category as well.
#2 Strong Vs Weak
Question : Why Ruby is a strongly typed language?
Answer : Because once it knows the type of an object, it expects you to do something that makes sense with it.
In ruby, you CAN do :
x = "3"
y = x + "ho!" #result : "3ho!"
but you CANNOT do :
x = "3"
y = x + 3 #Wooo! Ruby won't like that
What do you want to do with the string “3” ? Append the Fixnum 3? What? Are you crazy? Hey look everyone, that guy want to append the string “3” to the Fixnum 3! Let’s make fun at him!
(Python and PHP are looking at each other and Python says : You knew that Ruby was still on medication?)…
Oh sh**! My geek meter just exploded…
You see, It’s not because Ruby lets you change the type of an object as many times as you want that it doesn’t care about what you do with it. If you start mixing several types together in an expression, it won’t try to understand what it means, nah… that is too complicated. Instead, ruby will throw an exception… end of story. This is why we say that Ruby is a strongly typed language.
Javascript however is dynamically but weakly typed because it lets you mix types together in your expressions without throwing an exception. The danger? If you’re not careful you will get weird results.
x = call_function_that_returns_the_number_3_in_the_string_form;
y = x + 1 //The programmer expect that "y" will equal 4 (Tee hee hee!)
after that instruction, y will contain “31”. Hmm, that could be a bug hard to spot. Javascript is being more hippie than Ruby on this level. It’s like : relax man… do watcha want with your types, I don’t care. I’ll mix them all and we will have a good laugh watching the results. It will be like “art”! For this reason, Javascript is a weakly typed language.
So, to conclude :
A dynamically typed language is a language where the type of a variable can be altered at any time. (It is a string, now it is a Fixnum, now it is a Time object, etc.)
A statically typed language is the opposite. (Decide what x is once for all and don’t change your mind!)
A strongly typed language is a language that is being strict about what you can do with your typed variables. (Don’t mix them… or I will throw you an error in the face!)
A weakly typed language is the opposite. (Do what you want with your different types. Mix them all! We’ll see what happens!)
Bad example. Noone in their right mind returns numerical values as strings from functions. If the function should return a number, then return a number, not a number as a string.
If in a particular case the programmer knew that the value was going to be a number contained in a string, then he/she would make sure that the value is cast to the right type before proceeding.
What can happen in a language, and what does happen when people are using the language are not always the same thing.
1.
x = “3”
2.
y = x + 3 #Wooo! Ruby won’t like that
Won’t y = “33” ?
Hmmm it appears not 🙁
class Fixnum
alias_method :old_plus, :+
def new_plus(other)
return self.to_s + other if other.kind_of? String
self.old_plus(other)
end
alias_method :+, :new_plus
end
x = “3”
y = 3 + x # y now equals “33”
The fact is, that ruby is so dynamic (and I use the term not in its official context) in nature, that strong typing loses much of its punch. Granted, the default operators will act in a strongly typed manner, but if you took the time to override these operators on the basic primitives (which are really objects/classes), you’d end up with something that looked pretty weakly typed.
It’s the best of both worlds, from a coders standpoint.
Strong vs weak typing is a very strange and opinion-based argument. There’s no real one definition of strong vs weak typing, except that I think most people agree C is weakly typed. For example, you bring up Javascript. Javascript isn’t necessarily weakly typed, it just has certain coercion rules so that in certain contexts certain types will be converted to others for compatibility purposes.
To be honest, I think in Ruby, as Shalev pointed out, strong vs weak typing isn’t particularly important because of the dynamic nature of the language.
x = ‘3’
x = x + 3 # Error!
but:
Class Fixnum
def to_str
self.to_s
end
end
x = ‘3’
x = x + 3 # x = ’33’
Most of those discussions are wrong.
The key concept to grasp in strong versus weak typing is that there is a distinction between reference typing and object typing. Java has static typed references and static typed objects.
Person me = new Person(“me”)
Both the reference and the object are static typed. People usually call this strong typing.
me = Person.new
Here the reference is dynamic typed and the object is static typed (although in Ruby objects can change their appearance during run-time). Dynamic typed references with static typed objects people usually call weakly typed.
Groovy is makes the distinction more difficult. It support both dynamic and static references, just as needed.
def me = new Person(“me”)
and
Person me = new Person(“me”)
are both legal Groovy code. The first with dynamic typed references and the second with a static typed reference.
I’ve written extensivly about the distinction more than a year ago.
Peace
-stephan
—
Stephan Schmidt :: [email protected]
Reposita Open Source – Monitor your software development
http://www.reposita.org
Blog at http://stephan.reposita.org – No signal. No noise.
Excellent explanation of a easily misunderstood concept!
@yriafelc — yes, but in that situation, you’ve changed the `unmentioned’ semantics of +to_str+ — namely, that an object that has that method is, for all intents and purposes, a string, while +to_s+ means that it can be represented as one. Personally, I think String#+ should use +to_s+ rather than +to_str+. But then again, that’s what string interpolation is for, so whatever.
So from some of these comments (the guy who overloaded Ruby + and the guy who said C is weakly typed) – it seems like we can classify strong/weak as being a property of the OPERATORS themselves, not the type system! (For the most part).
I wouldn’t classify C as having a particularly weak type system. It lets you implicitly cast numbers around (eg. (int)3 + (float)4.7 => (float)7.7), but that’s about it. For instance, C won’t let you go “3” + 4 and give you 7 – which a truly “weak” type system will give you.
Oh no, C is far worse – it isn’t _weak_, it’s _unsafe_! The 3rd classification after dynamic/static and weak/strong is safe/unsafe. In C if you do “3” + 4, you get … a pointer 3 bytes past the end of the string! This is usually unacceptable in modern languages so it doesn’t happen in most. But just a point, I wouldn’t consider that “weakness”.
Sorry for getting off-topic. Oh, a very good article though!
But that’s often what’s meant with weak. Weak means that there is a weak distinction between the types (more or less). In C, that’s particularly evident because you get virtually no distinction between pointer types — they’re all integers at the end of the day, and you can do whatever you want with them. Casting lets you achieve just about anything, with no checking until you get a segfault in your running program 🙂
A = “This is a number”
What would be the result for A = A + 7 in a Dynamically typed language?
Dilruk,
in your example dynamic/static doesn’t apply. It’s the Strong/Weak aspect of typing that is affected. In ruby, your example would throw out an exception. In a weakly typed language, it would try to mix the two types… In most cases I guess it would give something like “This is a number7”
Thanks for your comments everyone (I’m just 2 years late) !
Very nice!
ex.:
x = 100
(1..4).each{ x = x * 100 ; puts “#{ x.class} #{x}” }
result:
Fixnum 10000
Fixnum 1000000
Fixnum 100000000
Bignum 10000000000
Very nice!
ex.:
x = 100
(1..4).each{ x = x * 100 ; puts “#{ x.class} #{x}” }
result:
Fixnum 10000
Fixnum 1000000
Fixnum 100000000
Bignum 10000000000
Not Working in Ruby 1.9.3, Just try yourself in irb mode
x = “3”
y = x + “ho!” #result : “3ho!”
Very nice. Love the way you explained the differences of both static vs. dynamic and strong vs weak typed concepts.
Thanks for this!
Hey man! Thanks for the article. It was a real pleasure to read about complicated things in such a joyfull manner.
Love that!
Hello. excellent job. I did not expect this. This is a great story. Thanks! agckceadgeed
Thanks to that joke, I will never confuse dynamic-static and stonglyTyped-looselyTyped.
“Hey look everyone, that guy want to append the string “3″ to the Fixnum 3! Let’s make fun at him!” Lol 😀