Everybody knows that dynamic typing offers dynamic behaviors (runtime behaviors). It is little known that static typing can offer dynamic behaviors, too. With the advent of Component-Based Object Extender (CBO Extender), an object extensibility framework for .NET, behaviors can be added to objects at runtime.
It is good news for .NET developers or maybe for all developers using static programming languages. However, with this option, it becomes more complicated to decide on using a static programming language or a dynamic programming language for your development. Here, I try to discuss the differences between static typing and dynamic typing in terms of dynamic behaviors, and hope it will make the decision process a little easier.
Dynamic Behaviors With Dynamic Typing
There are two kinds of dynamic typing: prototype-based programming and class-based programming. In prototype-based programming classes are not present, and behavior reuse is performed via a process of cloning existing objects that serve as prototypes. JavaScript is an example using prototype-based programming. In class-based programming, a class is defined prior to an object is created out of it and used. Ruby is an example using class-based programming.
Regardless of using objects only or both classes and objects, dynamic behaviors are achieved by changing object types, i.e., adding, deleting or altering methods of object or class without a validation step (compilation). A dynamic behavior is resolved to a method of object at runtime.
Dynamic Behaviors With Static Typing
Static typing is class-based programming with a validation step (compilation). Prior to .NET 4, C# is a static typing language. Now, it is mixed with both dynamic typing and static typing. It still needs compilation step with intentionally omitting validation of certain types.
Unlike dynamic typing, in static typing dynamic behaviors are achieved by decorating methods of object without changing object types. A dynamic behavior is resolved to a decorator, which itself is a method independent of the decorated object.
Comparison of Dynamic Behavior between Dynamic Typing and Static Typing
First, let’s use an example to see how dynamic behaviors are achieved in dynamic typing and static typing. In the following sections, a Hello World! application is written using dynamic behaviors with three programming languages: Javacript, Ruby and C#.
Dynamic Behaviors in JavaScript
The following code is written using JavaScript:
function doAnything() {
}
doIt = new doAnything();
doIt.hello = function () {
alert("Hello!");
}
doIt.bye = function () {
alert("Bye!");
}
doIt.hello();
doIt.bye();
The doAnything
function is empty, which is used to create doIt
object. The, two properties, hello
and bye
are added to doIt
. Last, the doIt.hello();
and doIt.bye();
are called to output “Hello!
” and “Bye!
”.
Note that the behaviors of doIt
object can be changed anytime by adding, removing or altering its properties.
By uncommenting the code...
...the output will be “Hello!
” and “Not bye yet!
”.
By uncommenting the code //delete doIt['bye'];
you get a runtime error.
Imagine that in a big project, these lines of code are buried deeply inside dozens of files with multiple million lines of code. You’re screwed! It is too flexible to be safe and predictable.
Dynamic Behaviors in Ruby
The same example is rewritten in Ruby as follows:
class DoAnything
end
class DoAnything
def Hello
puts "Hello!"
end
def Bye
puts "Bye!"
end
end
#class DoAnything
# def Bye
# puts "Not Bye Yet!"
# end
#end
doIt = DoAnything.new
doIt.Hello
#def doIt.Bye
# puts "Bye from instance"
#end
#class << doIt
# remove_method(:Bye)
#end
doIt.Bye
The above code outputs “Hello!
” and “Bye!
”.
By uncommenting the code...
#class DoAnything
# def Bye
# puts "Not Bye Yet!"
# end
#end
...the output will be “Hello!
” and “Not bye yet!
”.
By uncommenting the code...
#def doIt.Bye
# puts "Bye from instance"
#end
...the output will be “Hello!
” and “Bye from instance
”.
By uncommenting the code...
#class << doIt
# remove_method(:Bye)
#end
...the output will be “Hello!
” and “Not bye yet!
”.
It suffers from the same problems as JavaScript: too flexible to be safe and predictable!
Dynamic Behaviors in C#
The example is rewritten using C# as follows:
using CBOExtender;
namespace HelloWorld
{
public interface IDoAnything {
void DoThing();
}
public class DoAnything : IDoAnything {
public void DoThing() { }
}
class Program
{
static void Main(string[] args)
{
IDoAnything doAThing = new DoAnything();
doAThing = ObjectProxyFactory.CreateProxy2<IDoAnything>(
doAThing,
new string[] { "DoThing" },
new Decoration2(SayHello, null),
new Decoration2(SayBye, null)
);
doAThing.DoThing();
}
public static void SayHello(AspectContext2 ctx, dynamic parameters)
{
System.Console.WriteLine("Hello!");
}
public static void SayBye(AspectContext2 ctx, dynamic parameters)
{
System.Console.WriteLine("Bye!");
}
}
}
The code...
doAThing = ObjectProxyFactory.CreateProxy2<IDoAnything>(
doAThing,
new string[] { "DoThing" },
new Decoration2(SayHello, null),
new Decoration2(SayBye, null)
);
...decorates the original object and returns a proxy of it. The above code outputs “Hello!
” and “Bye!
”.
Dynamic decorating retains object types in terms of interface instead of implementation and does not change original object behaviors. It just attaches extra behaviors to object. Therefore, it is type-safe and predictable. It is flexible in a way of loosely-coupling not in a way of dynamic typing.
In summary,
- Both dynamic programing languages and static programming languages can have dynamic behaviors.
- Dynamic programing languages achieve dynamic behaviors by dynamic typing while static programming languages achieve dynamic behaviors by dynamic decorating.
- Dynamic decorating retains types of object and its functionality, and is safe and predictable while dynamic typing alters types of object and its functionality, and is unsafe and unpredictable.
Conclusions
It is safe to say that applications except most trivial ones benefit from dynamic behaviors, but not every application needs dynamic typing.
If you need dynamic behaviors, and type-safety and predictability is important, you should choose .NET with dynamic decorating. If you need dynamic behaviors, and type-safety and predictability is not important, you can choose dynamic typing.
At this time, dynamic decorating supports only .NET.