
Dynamic languages are an anti-pattern - DanWaterworth
I'm starting to think that it's much more difficult to write maintainable dynamically-typed code than it is to write maintainable statically-typed code. Many of the bugs I've been fixing lately would have caused type errors in a statically typed language.
======
ajuc
IMHO it depends on the part of the project.

When you are building infrastructure (buisness logic independent), static
languages are better, because most things are clearly defined, and change
rarely, so overhead is small, and the code is general (few special cases).

When you build the real thing, that includes business logic, dynamic languages
are better, because it's much easier to change business logic and add special
cases on the fly. And there are always special cases.

That's why big projects written in static languages often have implementations
of some dynamic language embedded, and when they don't, they use unholy mess
of configuration files and dependency injection to achieve the same goal.

I much prefer intentionaly designed embedded dynamic language to writing
implementations of factories and changing xml files.

To see how much dynamic your static code is count all the casts from Object,
and all template classes instanced for Object (especially common are
List<Object>, Map<String, Object>).

Writing infrastructure code in dynamic languages - I agree - it's harder to
get right than with staticaly typed languages, and the benefits aren't
obvious.

------
DanWaterworth
Thanks everyone, reading through your answers and thinking through the bugs
I've solved has lead me to some interesting conclusions.

(The language I'm using is Ruby).

The problem is not that Ruby isn't statically typed. It's that what I think of
as type errors in Ruby pass without incident. The most irritating example of
this is that if you don't pass enough arguments to a proc object the other
parameters get filled in with nil. In my mind this should throw a type error,
but in Ruby it doesn't.

Perhaps this is why Rubyists are so keen on testing, because their language is
full of implicit behaviours.

~~~
haven
Proc doesn't check arity. That is just how proc and Proc.new are expected to
work. If you want to check the arity, use lambda or ->.

x = ->(a, b) { puts a, b }

x.call #ArgumentError: wrong number of arguments (0 for 2)

x = lambda { |a, b| puts a, b }

x.("just one argument") #ArgumentError: wrong number of arguments (1 for 2)

------
DrinkWater
I experienced the same, but its more the fault of the programmer. Dynamic
languages are easier to enter ("learn") and thus attract more mediocre
developers who deliver inferior code.

------
secoif
You had bugs because you didn't have adequate tests, not because you were
using a dynamic language. That's the anti-pattern.

~~~
DanWaterworth
The problem is that to find the most annoying of these bugs using testing
alone would have meant that so much time would have been spent writing tests
that the productivity gains that you get writing in a dynamic language would
have been nullified.

------
theshadow
Which is why the importance of unit testing is underscored in the communities
around dynamic languages.

~~~
vetler
Really? In my experience, it's the Java community that has the most focus on
unit testing.

~~~
theshadow
Compared to dynamic language communities? Not even close. Just look at the
almost cult like devotion to writing tests in the Ruby community.

