.NET goes
much further:
A routine written in a language L1 may call another routine written in a
different language L2.
A module in L1 may declare a variable whose type is a class declared in
L2, and then call the corresponding L2 routines on that variable.
If both languages are object oriented, a class in L1 can inherit from a
class in L2.
Exceptions triggered by a routine written in L1 and not handled on the L1
side will be passed to the caller, which—if written in L2—will process
it using L2's own exception-handling mechanism.
During a debugging session, you may move freely and seamlessly across modules
written in L1 and L2.
I don't know about you, but I've never seen anything coming even close to this
level of interoperability.