Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I began coding in in Python primarily where there is no type safety, then moved to C# and Java where there is. I found that I could work a bit more quickly and with less headaches in Python, but then again, my C# and Java apps are at much higher level of complexity so I have never given Python a true stress test I suppose.

The Java and C# camps make it sound like without the type safety in place, most people would be running into all sorts of horrible bugs left an right and it would be more trouble than its worth.

This is not a language comparison, so please do not address issues like compiled vs interpreted. Is type safety worth the hit to speed of development and flexibilty? WHY?

to the people who wanted an example of the opinion that dynamic typing is faster:

"Use a dynamically typed language during development. It gives you faster feedback, turn-around time, and development speed." - http://blog.jayway.com/2010/04/14/static-typing-is-the-root-of-all-evil/

share|improve this question
10  
This question is the opposite of What arguments are there in favor of weak typing?. –  NickC Mar 18 '11 at 18:17
5  
@Prof Plum: may I require a proof that there is a hit in speed of development and flexibility ? Since we are talking about a particular aspect Type Safety, using Java or C# would be inconclusive, their way of providing it is NOT the only one... –  Matthieu M. Mar 18 '11 at 18:49
16  
With diligence in a strict language, you can minimize the "headaches" and then you might even see a speed increase due to IDE auto-completion, code generation, and code hinting. –  NickC Mar 18 '11 at 18:53
7  
@Prof Plum: I understand, I don't expect you (or anyone really) to have fully tested every language ever created ^^ The problem is that most of the people I've seen complaining about some specific aspect of programming languages (Static Typing often comes) generally complain about a particular implementation, and fail to realize it. –  Matthieu M. Mar 18 '11 at 19:01
3  
@Prof Plum, all that blog post really has to say about speed is the bald assertion "Anyone, who has worked seriously with a modern dynamically typed language like Ruby or Smalltalk, know that they are more productive." No actual examples of how, in practical terms, it makes development faster. –  Carson63000 Mar 18 '11 at 20:50

22 Answers 22

up vote 70 down vote accepted

It's sort of a myth that programmers don't have to worry about types in dynamically typed languages.

In dynamically typed languages:

  • You still have to know if you're working with an array, an integer, a string, a hash table, a function reference, a dictionary, an object, or whatever.

  • If it's an object, you have to know what class it belongs to.

  • Assigning one of these types to a variable or function parameter expected to be another type is almost always an error.

  • At a lower level, things like number of bits or signed versus unsigned frequently still must be accounted for if you are populating a TCP packet, for example.

  • You can run into problems where you get a zero where you really wanted an empty string. In other words, you're still debugging type mismatch bugs. The only real difference is the compiler isn't catching the errors.

  • I'd argue that you aren't even saving much typing- , because you tend to want to document in comments what type your function parameters are instead of documenting it in your code. This is why doxygen-style comment blocks are much more popular in practice throughout dynamically typed code, where in statically typed languages you mostly only see them for libraries.

That's not to say that programming in dynamically typed languages doesn't feel more pleasant because the compiler isn't always on your back, and experienced programmers don't tend to make the kind of bugs very often that static typing would catch anyway, but that's a completely separate issue from an alleged increase in efficiency or reduction in bug rate, for which dynamic typing is at best even with static typing.

share|improve this answer
1  
I would have to contest the bit about experienced programmers not making/introducing those kind of bugs. Good developers who are humble and acknowledge the possibility of them making errors(and experienced developers are not always like this) are less likely to create those bugs. –  Jay Jay Jay Mar 4 at 3:32

As the types get stronger, they can help you more — if you use them correctly instead of fighting them. Design your types to reflect your problem space and logic errors are more likely to become compile-time type mismatches instead of runtime crashes or nonsense results.

share|improve this answer
8  
+1! "logic errors are more likely to become compile-time type mismatches instead of runtime crashes or nonsense results": Really good answer! When I take more time to design my types, then the code follows more naturally and it is often correct as soon as it compiles. Designing a type means to understand a domain and its operations. –  Giorgio Feb 24 '12 at 17:01

Disclaimer: I am a type-lover ;)

Your question is difficult to answer: What are those trade-offs ?

I'll take an extreme example: Haskell, it is statically typed. Perhaps one of the most strongly typed languages that exist, in fact.

However, Haskell supports Generic Programming, it the sense that you write methods that work with any type conforming to a certain concept (or interface).

Furthermore, Haskell uses Type Inference, so that you never have to declare the type of your variables. They are statically computed during compilation, much as a Python Interpreter would compute them running the program.

I've found that most people harshing on static typing, were actually complaining about something else (verbosity, pain of switching one type in favor of another), but Haskell exhibits none of those issues, while being statically typed...


Example of brevity:

-- type
factorial :: Integer -> Integer

-- using recursion
factorial 0 = 1
factorial n = n * factorial (n - 1)

Apart from built-in support, it's difficult to get briefer.

Example of Generic Programming:

> reverse "hell­o" -- Strings are list of Char in Haskell
=> "olleh"
> reverse [1, 2, 3, 4, 5]
=> [5,4,3,2,1]

Example of Type Inteference:

> :t rever­se "hell­o"
:: [Char]

which can be computed simply:

  • "hello" is a list of Char (expressed as [Char])
  • reverse applied to a type [A] returns a type [A]

Try it out in your browser

share|improve this answer
7  
+1: What trade-offs? –  S.Lott Mar 18 '11 at 19:44
2  
To play devil's advocate, one trade-off in favor of dynamic languages (at least while prototyping) is that insofar as type declarations can serve the same purpose as some unit tests, they can also solidify interfaces in the same way that unit tests do (though certainly with less overhead). Also, statically typed languages without coercion, while safer, require explicit type casting (particularly when a type isn't generic enough), which can detract from terseness. –  T.R. Mar 18 '11 at 21:08
3  
I don't know Haskell but +1 for "were actually complaining about something else (verbosity, pain of switching one type in favor of another)" –  NickC Mar 18 '11 at 22:08
4  
@Matthieu: WRT "Perhaps one of the most strongly typed languages that exist, in fact.", I'll see your Haskell and raise you Agda and Coq. (I will grant that it's probably the most strongly typed practically useful language.) –  geekosaur Mar 19 '11 at 4:51

Personally, I find that type safety helps me develop faster in my current job. The compiler does a lot of the sanity checking for me almost as I type, allowing me to focus more on the business logic that I'm implementing.

Bottom line for me is that although I lose some flexibility, I gain some time that would otherwise be spent tracking down type issues.

share|improve this answer

I like both statically-typed and dynamically-typed languages. The two biggest advantages of type safety to me are:

1) You can often pretty much deduce what a function does purely from its type signature (this is particularly true in functional languages like Haskell).

2) When you do significant refactor, the compiler automatically tells you everything you have to do to keep everything working. When I refactor something in C++, my procedure is often simply a) change the one part I know I want to change, then b) fix every compile error.

share|improve this answer

When you're maintaining code where every function takes an array blob of data written by someone who didn't believe in documentation, you'll know why.

share|improve this answer

Is type safety worth the hit to speed of development and flexibility?

So really this comes down to what you are doing. If you are programming say, the backup systems for airplanes, type safety is probably the way to go.

Dynamic language vs Static language programming are really two different animals. They both require a fundamentally different approach from each other. You can mostly port a method of approach between static and dynamic, but you'll lose out on the advantages of the other.

It's a mindset really. Is one better than the other? That really depends on who you are and how you think. Most of the people I work with would never touch a dynamic language if they didn't have to, because they feel there is too much room for error. Are they wrong to think this? No, of course not, but it does mean that they have realized that they're approach of applying their coding style won't work in a dynamic environment. Other people I go to user groups with are the exact opposite. They find static typing too cumbersome, because it limits their approach to solving certain types of problems.

I can honestly say, I jump between JavaScript and C# a lot. Now, knowing and working in both languages does influence the other to some extent, but in truth, the code I write in each look entirely different from the other. They require a different approach, because they are fundamentally different. What I've found is that if you find yourself thinking, "Man this is so much harder to do this in X language," your approach is probably off a little. Here's an example, people talk about the "Pythonic" way of doing things. What it means is that there is a way the Python language works to make a problem easier. Doing it some other way is generally harder, and more cumbersome. You have to get over the hump of knowing how to a language works to really it work for you. It's the exact same thing with dynamic vs static languages.

share|improve this answer

Speed of development and flexibility is relative. Skilled developers can avoid the pitfalls either way. Working quickly can catch up with you if you're not careful.

Many have mentioned project complexity. Sorry, can't specify the cut-off from simple to complex projects, but know it when they kick you in the pants.

An uneducated child can learn their native language, why can't adults in the rest of the world?

share|improve this answer
6  
"Working quickly can catch up with you if you're not careful." Something that has bit me before for sure. –  justkt Mar 18 '11 at 19:34

For whatever reason, I don't make errors related to the type of an object that often anymore. In languages like C#, I am more likely to make errors related to runtime casts than I am likely to make a compiler-detectable type safety error, which, I grant, is usually caused by the occasional need to work around the staticness of a statically typed language. When I write ruby, the code tends to hint pretty strongly at the type of an object and the availability of a REPL means that I've already experimentally verified that the desired method/attributes exist, or I'll have a unit test that does basically the same thing, so I also rarely run into type safety problems in ruby.

But that's not to say statically typed systems can't be better than they are.

Within statically typed languages, the type system actually matters a lot as well. As an example, with something like the the Some monad in functional languages (type<Some> := yes x | no ), you gain compile-time checks that essentially prevent the dreaded NullReferenceException common in most type systems; when pattern matching code runs, you get compile time errors telling you that you failed to handle the null condition (if you use that mechanism to declare the type). You also reduce similar types of errors when you use things like the |> pipeline operator in F#.

In the Hindley–Milner tradition of static typing, you can build things that give you far more than a guarantee that a type claims to support interface X, and once you have those things, I'd say that the statically typed system becomes a lot more valuable.

When that's not an option, Design By Contract extensions to C# can add another set of mechanisms that increase the value of the static type system, but they still require more discipline than some of those functional paradigms.

share|improve this answer

An important thing to keep in mind here is that Java and C++ have really terrible type systems that just get in your way half the time -- they are not very expressive. (Community wiki so that people who are more familiar with expressive type systems can expand on this.)

share|improve this answer

There was a similar question just asked recently: Dynamic vs Statically typed languages for websites

To restate the core of my answer:

As systems grow bigger, statically typed languages ensure robustness at component level and thus flexibility at system level.

Yes, Java is strictly typed and yes, Java sucks (no offense. it's awful. great platform & ecosystem, but one of the worst languages ever (actually being used)).
But infering from that, that strict typing sucks is just a fallacy. It's like pointing at PHP and infering dynamic typing sucks (again, no offense. it's slowly improving, I give you that).

Personally, I do most of my development in haXe, which has a static type system. Not only is it signifficantly more expressive, than that of Java and does it require much less effort due to type inference, but it's also optional. Should it ever get in your way, you just bypass it.

Type safety is a feature (this is something many supposedly high level languages don't get right) to help you prevent shooting yourself in the foot.
And about any succesfull dynamically typed language would be simply better, if you had the option have your code type checked at will.
For example, I certainly enjoyed experimenting Ruby, but that was mostly because Ruby is fully object oriented, which is entirely orthogonal to the presence of a compile time type system.

I think the claim, that static type systems are obstrusive is merely based on lack of knowledge of good static type systems. There's a number of languages that do it right, haXe being one of them, and arguably not even the best in that regard.

Example haXe code:

class Car {
    public function new();
    public function wroom() trace('wroooooooom!')
}
class Duck {
    public function new();
    public function quack(at) trace('quackquack, ' + at + '!')
}

function letQuack(o) o.quack();
letQuack(new Car());
letQuack(new Duck());

This will produce a compile time error:

Car should be { quack : Void -> Unknown<0> }
Car has no field quack
For function argument 'o'
Duck should be { quack : Void -> Unknown<0> }
Invalid type for field quack :
to : String -> Void should be Void -> Unknown<0>
For function argument 'o'

You can't really claim I had to put a lot of effort into type safety.

Saying that you don't need type safety, because you have tests is even more idiotic. Writing tests is boring and repetitive. And I really don't want to write a test, just to find out, that an instance of Car won't quack and a Duck needs someone to quack at.

At the end of the day, you will find, no matter how much overhead type safety costed you, it is eventually ammortized (even in Java - although maybe not that soon).

share|improve this answer

It depends.

Human failure modes are often statistical. Strong type checking reduces the likelihood of a few certain types of human failures (causing buggy code). But just because you can fail doesn't always mean you will (Murphy non-withstanding).

Whether this reduction in potential failure odds is worth the cost depends.

If you are writing code for a nuclear power plant or ATC system, any human failure mode reduction might be extremely important. If you are rapid prototyping some website idea that has no spec and with near zero failure consequences, then the reduction in failure modes or probabilities may or may not buy you anything, but may cost you in development time (more keystrokes, etc.), and in brain cells distracted by memorizing the current type(s) required.

share|improve this answer

Yes, definitely. One thing you'll find as you use both strongly typed languages and Python(Python is strongly typed) more is that most well-written code in dynamic languages tends to follow a lot of the same conventions as strongly-typed code anyway. Dynamic typing is very useful for serialization and deserialization, but for most other things it really doesn't contribute much of an advantage. And unless most of your code is serialization-related, why throw out the free error-checking?

share|improve this answer
3  
Strongly-typed languages such as Java and C# handle deserialization automatically through the use of Reflection. –  Matthieu M. Mar 18 '11 at 18:31

You're not going to get a truly objective answer to that, but my experience is that type-safety is invaluable until you master TDD. Once you have heavy unit-test coverage, where the tests have been written before the code, the compiler-checking becomes a pain and actually starts getting in your way.

share|improve this answer
1  
Anyone care to explain the down-votes? –  pdr Mar 18 '11 at 18:26
3  
I didn't downvote as you made a valid point, although no offence intended, but your post comes across as a little TDD fanboyish, which is probably why the downvotes. –  Karl Bielefeldt Mar 18 '11 at 22:19

Interpreted languages have lost a big advantage now that we have incremental compilation. My workflow programming java in Eclipse is as fast as programming an interpreted language. I never actually perform a compile. There's continuous compilation and the compiler is giving me continuous feedback on errors in my code which is invaluable.

share|improve this answer

There have been a lot of very complicated systems written in Lisp, and I haven't heard any Lisper complaining that they wanted static typing. When I worked with it, I don't remember any problems that slowed me down much that a static type system (and you can specify types statically in Common Lisp) would have caught.

Moreover, mainstream statically typed languages don't seem to be well suited for catching errors. In designing a layout, what's important is that a certain number is a vertical measurement on the page, not whether it's int, unsigned, float, or double. The compiler, on the other hand, will often flag type conversions it deems unsafe, and happily let me add a vertical measurement and the number of characters in a string. This weakness of the static type system was the original idea behind Simonyi's Hungarian notation, before it was bastardized into ugly uselessness.

share|improve this answer

Types are constraints on interfaces, so they're a subset of what you may want to test with unit tests, and so a lot of the trade-offs are similar:

  • Static types give earlier feedback on whether or not the code meets the requirements that can be expressed by the type system, in exchange for delaying feedback from building something minimally functional (like customer feedback or higher level tests).
  • Knowing that the code meets certain requirements can ease refactoring and debugging, but it also adds overhead to changing interfaces and changing requirements.
  • Particularly if a statically typed language lacks coercion, it provides added security against code being used on data that would cause bugs (reducing the need for conditionals and assertions), but overly restrictive constraints require the user to write more code to massage their data into an acceptable form (such as explicit type casting).
  • Explicit type annotations can aid understanding when reading code, or it can clutter code with redundant or unnecessary information.
  • Depending on implementation, it can detract from terseness. This depends on things like whether type annotations are required or inferred, how well the type system can express generic types/interfaces, the syntax, and whether or not you intended to test for constraints that can be expressed by the type system (i.e., the same test is likely more terse as a language feature than as a unit test, but you may not have intended to test it).
  • Additionally (but unrelated to TDD), static types can aid compile time optimization, at the expense of requiring that types check (and taking the time to check them and perform the optimizations), and better optimization can be done if data is restricted to types that map well to hardware. This eases development on code with performance requirements, but can cause trouble for code that doesn't fit these constraints well (as per point 3).

To summarize, I'd argue that dynamic languages are particularly useful for prototyping, whereas if you need to be sure that your code is correct, you should favor a strong type system.

share|improve this answer

The benefits of languages like Ruby, or Python on the front end are hard to ignore. I still prefer type-safe languages for any back-end coding, web services, etc. I think they can live happily together, just use whatever will solve your current needs the best.

share|improve this answer

I see this question come up alot, and I think that your software quality (and lack of bugs) has more to do with your development process, how your system is architected, and the commitment of you and your peers to code quality.

My last job was mostly python development. I worked for a large, international web hosting company and we had dev teams in the US, Canada, and South Korea. Custom python web framework for front end customer app that allowed the users to manage their domain names and web hosting accounts. Backend: all python too. Python web service to talk to individual servers to do things like provision a new web hosting site, create a new blog, create dns entries in our name service system; etc, etc. In my current job, client apps our all in java; our main product is a mixture of java and flash. Custom java web framework for our older apps, wicket for our newer internal tools.

Having worked in both, I have to say this question bugs me every time I see it. If you are using a dynamically typed language and actually test your code you'll be fine. If the system is designed well, and you follow standards, you will be fine. There were never a lot of bugs that came up due to lack of a compiler checking types. Most bugs were logical errors, just like my java job today.

share|improve this answer

YES.

I have worked in PHP applications, where types are not as "strong" as in Java or C#. Usually I finished "simulating types", because, in order to avoid bad automatic conversions, or validating data.

Dynamic Type Languages are good for O.S. scripts and quick small apps., not complex apps.

Summary: If I have to choose between an "Weak Type" or "Dynamic Type" Programming language, or a "Strong Type" Programming Language for a complex, business application, I choose the "Strong Type" Programming Language.

share|improve this answer

Morgan, I got an interesting idea for you to try: static + dynamic typing. You mentioned Python, C# and Java. Were you aware that there are some pretty good ports of Python to both .NET and Java? In both cases, the ports let you use the libraries of those platforms and/or interoperate with existing code. This gives you several possibilities:

  1. Keep legacy code in static, inflexible language. Use Python for new stuff.
  2. Use Python to prototype new stuff on top of mature platforms. Re-code the components you want to keep in the more mature language.
  3. Use the dynamic language for portions you change often.
  4. Possibly use the dynamic language to play with ideas like modifying running code.
  5. Do everything in the dynamic language except for the critical parts where you use the strongly typed language.

I used these approaches as far back as the late 90's to get around the pain of developing in C/C++. I needed the native libraries and sometimes performance. Yet, I wanted the better syntax, flexibility, safety, etc. So, the trick was carefully combining them to get the right tradeoffs. It was often better in practice than throwing the whole language and legacy code out for another language/platform.

(Note: An answer already said it, but I also want to re-emphasize that dynamic typing != no/weak typing. Many dynamic type systems use strong typing on the inside. The way I think about what makes a type dynamics is that a variables type is determined at runtime, doesn't need a type annotation, and/or might change at runtime.

share|improve this answer

This is just my own opinion, but no, I don't think that type safety is worth it. Not even for a second.

I've been a developer for long time. Starting off with c++, c#, then moved to javascript (frontend and backend via node.js). Since I've been developing in javascript my productivity has sky-rocketed, to the point that I actually get aggravated using type-based languages. I'm also against compiling, I want everything to be in run-time now. Interpreted languages is really where I found my love for programming.

As far as types, I just don't see any benefits. I see types now the same way I see memory management. Completely unnecessary. The languages of tomorrow should completely shield the developer from knowing anything about types. The computer should understand types and leave the developer out of it.

Here's an example. I was just using Swift (Apple's new language) hoping it'd actually live up to its name a day ago and tried to do: var n = 1/2 didn't work. I was like, what's going on here. and then sadly realized I had to do var n: Float = 1/2. This reminded me how much I hate type systems and how much of an unnecessary aggravation they are.

I'd even go another mile to say that I don't even want user defined types (such as Classes). I don't want types at all. All I want is var and objects. Where any object can be used as any object. And objects are dynamic and constantly changing. Where it becomes a runtime issue as to what works and what doesn't.

Developers love to say how loosely typed languages aren't good for big projects. But I'd say it's the opposite. Strongly typed languages are horrendous for large projects. And if you say javascript doesn't work for big projects, ask Uber a 40billion+ company that runs all it's backend on node.js/javascript, or Facebook that started with PHP.

As far as statically typed languages it's not good for today's quick iterations. here's a simple example, you have 10 developers working on a .net project with a continuous integration server, one developer submits a mistake and the entire build is broken, even though the 10 developers are working on different things they are now all stopped and waiting for the offending developer to correct his mistake. Talk about efficient huh? Type system / static languages are interdependent in that way and make your code interdependent. However, script files are never interdependent. If there's a problem with one of the scripts it doesn't halt production, all the problems you'd see are left to the runtime. And the runtime never stops. It never breaks. It might produce wrong output but it doesn't just halt the entire process the way type systems do.

share|improve this answer

protected by gnat Dec 23 at 7:18

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.