Page 5 of 6
True dynamically typed languages
The most famous example of dynamic typing is Perl where a scalar value variable can hold any type of value. The following are all legal in Perl:
my $a = "this is a string"; #string
my $a = 11; #number
my $a = \&mysub;
#reference to subroutine
You don't declare a type on the variable thus the variable is 'untyped' and, as you can see, the value that the variable points to can be of any type and can change during runtime, since the variable can hold any type. In essence it behaves like a Variant in VB6 or as an Object in C# which, rather than meaning 'no type' or 'untyped', more correctly means 'can hold any type'.
A variant can hold values of any type but also keeps an internal flag on the type it currently holds. A Variant data type is self-describing data – it contains the actual value of the data and metadata.
An example in VB6
We can use the GetType method to retrieve the internal representation of the variable:
Dim MyVar As Variant
MyVar = "my string"
In this case MyVar.GetType.ToString would be tagged as System.String
MyVar = #10/02/2009#
Here it holds an internal flag that shows that the contained type is a System.DateTime
In fact you can identify the internal representation of a Variant using the VarType or TypeName functions. These functions return the internal type kept by the Variant: TypeName returns it as a string and VarType returns it as an integer.
Perl scalar value internals
Perl shares the same notion; it uses the scalar type which can hold any value and tags it internally
but the difference is that a scalar can hold multiple representations of the same value, i.e. as a string and as a number at the same time, for reasons of caching; when the next operation requires a string or a number the appropriate representation is retrieved fast enough.
The scalar can contain an :
string ("PV" for pointer value)
a reference ("RV"),
special object ("magical")
Using the Devel::Peek 'Dump' module you can find out what type the scalar holds:
use Devel::Peek 'Dump';
$x = 10;
SV = IV(0x182a918) at 0x182a91c
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 10
$b = "aa";
SV = PV(0x2379b4) at 0x182a9bc
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x23fbcc "aa"\0
CUR = 2
LEN = 4
Variants and COM automation
In Visual Basic 6 there are 11 different data types, amongst them Currency, Date, Integer, Object, String, and Variant. As noted before the Variant can hold any of those types but also the IDispatch interface type.
Note that the Object type in VB6 is not like the Object type in VB.net. In VB6 the Object refers to the IDispatch interface type. As a matter of fact the IsObject Function returns a boolean value indicating whether an expression references a valid automation object.
IDispatch and the Variants are the building blocks of MS windows Automation (OLE,Active X,COM) and the IDispatch interface uses the Variant to marshal the arguments from the client to the COM server.
Variant implementation and discriminated unions
A variant type is in essence a tagged union. A VB Variant acts like a C style union. It can hold many types but its size is the size of its biggest member, and since it can hold any type it also is not type safe; this means that on the other end when trying to get at the contained value and/or convert it, a wrong representation might be used as you don't know the exact type stored.
The problem is augmented with weakly type languages where conversion from type to type is happening implicitly. For example the client passes a string as parameter but at the server side the string is being converted to an int because the method expects an int; the same implicit conversion would happen when you pass a float and the method expects an int so the value is converted and truncated.
So to denote the type contained in the union, the discriminated union was introduced which is capable for holding next to the actual value an internal flag denoting the type. So the value is no longer generic, but it does have an attribute which shows what type it is.
In C then you would check when extracting by using a bif if..then clause.
In pseudo code:
if TAG is int then 'treat value as int' else
if TAG is string then 'treat value as string' else
An example in VB6
Dim var1 as Variant:
var1 = 5.4
The same variable takes multiple forms where the next form overwrites the previous one. So this way you get no compile time type safety but you get runtime type safety.