I
think it is always a good idea to learn languages that make
<your-favorite-paradigm> hard. There are a lot of "Aha" moments
to be had from forcing your brain to come at a problem from another
angle.
As for things to watch out for.
There is a very
strong duality between TypeClasses and existential polymorphism in OO.
Both require a way to dynamically look up the correct implementation for
the type you are operating upon. In Haskell we use Typeclasses which
place this lookup table on the functions that have existential
constraints on them.
> mconcat :: Monad m => [m] -> m
> mconcat = foldl mappend []
We
can think of `mconcat` having a little lookup table inside of itself,
and whenever we pass it a concrete `[m]`, `mappend` gets looked up and
we get the implementation for `m`. Typeclasses are just mappings from types to functions
In OO on the other hand, the lookup table is attached to the datastructure. We can think of the Object as a mapping from function names to functions that operate on that Object. Python, Javascript, Ruby, and of course Smalltalk make this quite explicit.
Aside from Object Orientation, it is probably a good idea to learn some C for a bit too. C is a good language to play in and try and implement more advanced language features. Once you reallize that objects are just lookup tables of functions bound with a data-structure, you can implement your own in C, or you can make closures as functions bundled with (some) of their arguments, or you can implement interesting datastructures, or so many other fun things. A good understanding of tagged unions has helped me in many a convo with an OO head.