Posts in Category "programming languages"

Declarations, Logic, and Macros in Class Definitions

While nearly every current programming language has classes and objects, they have some radically different ideas about how one goes about defining classes.

In strongly-typed languages like C++ and Java, classes are declared. This means compilers (and other tools) have essentially complete information about the class during compilation, which in turn allows for certain classes of errors to be found and various optimizations to be applied. It can also be convenient for developers, in that it’s fairly straightforward to read declarative syntax and understand its meaning.

In script-oriented languages like JavaScript and Ruby, classes are defined by executing program logic at runtime. This is a powerful approach in that it may be much simpler to write a program to generate a given definition than to create the declarative version of it. On the other hand, it can defeat the application of analysis at compile time: some analysis can typically still be performed, but short of executing the class definition logic, it is impossible to fully analyze it.

Macros, such as those implemented by the C preprocessor, provide an interesting balance between the two approaches. The result of the macros is a class declaration, and it’s the declaration that’s available to the compiler. However, the macros can simplify class declarations by providing for generation of those declarations when the preprocessor executes. This is frequently used, for example, to generate declarations for class members that are used repeatedly across a set of (related) classes.

C++ provides another take in this space via its template facility. Unlike the generics capability in Java, C++ templates are themselves programs that are executed by the compiler at compilation time, and resulting typically in new class declarations. (This is referred to as “template metaprogramming.”) It’s an odd sort of programming language based primarily on recursively matching type patterns, but it’s still a programming language.

None of these techniques is necessarily better than another, but they certainly provide a different set of tradeoffs. With a more comprehensive view of the various approaches, one can hopefully be more effective in leveraging the strengths of whatever language is in use.


Class Declarations as a Transformation of Closures

In JavaScript, one can go about creating objects with private state by hiding it in a closure made at object creation time. Something along the lines of:

var myObject = (function() {

    var privateVariable = ...;

    return {
        publicGetter:function() { return privateVariable; }

Here, shielding the private state occurs at execution time; that is, it’s a result of the execution of the program.

Here’s the equivalent in using class declarations in ActionScript:

class MyClass {
    private var privateVariable = ...;
    public function publicGetter():* { return privateVariable; }

Here we can take the “declarations” part of “class declaration” literally: The private state is now private because it’s declared that way, rather than as a side effect of program execution.

Thus, class declarations provide a declarative transform of one particular thing that can be achieved via closures. As a mechanism, closures are of course more powerful and widely applicable. For purposes of writing and reading maintainable code, it’s preferable to have declarative support for common patterns like this.