Question: When it comes to programming, I don't hold strong opinions about feature x vs feature y. I think all have their appropriate uses.

And I'm always reading everything I can about as many programming languages I can get my hands on so that I can pull the best ideas out and compare them all (from Haskell to Lisp to C to Erlang).

But there is something that's been bothering me a little bit, and basically it's that when I've read about comparisons between static and dynamic typing, one downside for dynamic typing is that "bugs" come in because the compiler isn't able to check the type of the variable.

Now, I have plenty of bugs when I program, but I have *never* had a bug due to something like this, and I'm actually having a hard time visualizing what an example of such a bug would be. Like maybe forgetting you used an integer instead of a string somewhere? This seems so contrived though...

I program for a hobby, not a living, so perhaps these types of bugs only come in when people with different ways of thinking about things get together. I'm really just looking for some real-world examples.

Answer: 
An example would be when you change a variable from one type to another:

```
setType(String type)

```

Then later you decide to change the type to a more efficient enum:

```
setType(SomeEnum type)

```

When you do that in a strongly typed language, you will get errors wherever `setType` is called. That allows you to fix them quickly and to make sure you didn't miss any. In a dynamic typed language, you won't get such errors and will have to look for these instances by yourself.

Strongly typed languages are also generally faster since they can store data in more efficient structures (since the type is known at compile-type). An example are C arrays versus PHP arrays. C arrays are compact but PHP arrays have a rather big overhead to manage the dynamic data they contain.
There is a lot that can be said about types and their value for programming. For example, here is a recent article in CACM discussing (among other things) the anecdotical advantages of the advanced type system found in the functional language OCaml:

<http://cacm.acm.org/magazines/2011/11/138203-ocaml-for-the-masses/>

On a more principled note, the first couple of pages in the following classic paper classify kinds of program errors, and explain a few of the basic merits of type systems:

<http://www.lucacardelli.name/Papers/TypeSystems.pdf>

Since the latter paper is relatively old, let me add two things.

First, there is a difference between a language being typed, and requiring (explicit) type declarations. Some modern languages, especially from the functional camp, have sophisticated type systems that yet don't require you to write down a single type most of the time. All types are inferred by the compiler.

Second, a type system essentially is a logic. A logic that expresses certain properties of a program, which then get checked by the compiler. In principle, there is no limit to how powerful this logic can be made. There are languages whose type systems are powerful enough that you can e.g. express the type of sorted lists, and the type of a sorting function, so that the function only type-checks if it actually is a correct implementation of a sorting algorithm. Obviously, it is immensely useful if the compiler can actually check correctness of your program like that. However, there is a trade-off between expressiveness of a type system and ease of use, so in practice, most mainstream languages end up on the simplistic side. But special domains can benefit from more sophisticated type systems enormously.