In my January 9 column ".NET Framework Basics: the Common Language Runtime" ( http://www.winnetmag.com/articles/index.cfm?articleid=37657 ), I examined the role of the Common Language Runtime (CLR) in the .NET Framework and how CLR's developers intended CLR to make .NET development language-agnostic. The CLR has this capability because of the Common Language Specification (CLS), a set of rules that languages must follow for full compatibility with .NET. The CLR and the CLS are not synonymous. This column will explain the relationship between these two parts of the .NET Framework's support for language diversity.

The CLR is the runtime environment for executing .NET applications. As all runtime environments do, the CLR manages the way applications execute by providing services that the languages in which the programs are written expose. The syntax that accesses runtime environment services varies with the language, but the services themselves don't change. Not all languages can use all the functionality in the CLR because getting optimal functionality from the CLR would entail writing the languages with CLR compatibility in mind.

However, a language doesn't need to support all the features in the runtime environment. The CLS's role is to define a minimum subset of features that languages must support to work with .NET applications. For example, although the CLR supports both signed and unsigned integers, languages conforming to the CLS are required to support only signed integers. (In binary notation, an unsigned integer's most significant bit is data, not a positive or negative sign; a signed integer's most significant bit is its sign. Therefore, unsigned integers are always positive. End of digression.) The rules defined in the CLS apply to features visible outside the assembly (or, if you'll recall, equivalent to a DLL or EXE), where they're defined. For example, the CLS requires that public names--names visible outside their assembly--be case insensitive because some languages don't distinguish between FILENAME, Filename, and filename. These rules keep .NET assemblies from conflicting with one another. (For a complete list of CLS compliance rules, go to http://dotnet.di.unipi.it/EcmaSpec/PartitionI/cont10.html#_Collected_CLS_Rules_1 .)

Again, CLS compliance rules apply only to public features. Features contained within an assembly and not directly addressable by other assemblies don't have to follow these rules.

CLS-compliant languages are either consumers or extenders. Consumers can use any CLS-compliant type: They can call methods, create instances of CLS-compliant types, read and modify fields, and so forth. Extenders are consumers that can also extend base classes, define new types, and otherwise extend the framework. Of Microsoft's CLS-compliant languages, Visual Basic .NET, C#, and C++ with Managed Extensions are extenders, and JScript .NET is a consumer. Not all languages that you can use in .NET applications are, strictly speaking, .NET languages. For example, a third-party tool that creates a .NET component from a Perl class lets .NET applications call Perl modules, but Perl is neither a consumer nor an extender.

In short, the CLR defines all the capabilities available to applications and modules written for the .NET Framework. The CLS defines the set of rules to which languages must conform to work in this framework.