Invoking .Net methods that have “out” or “ref” parameters

The latest release of Essence# introduces the ability to invoke .Net methods that have “out” or “ref” parameters. This post will explain what those are, why supporting them is a technical challenge, and how to pass such parameters to .Net methods that use them.

Conceptually, there are only two ways to pass parameters to functions: By value or by reference. Although there are (usually rather old or even ancient) programming languages that pass all parameters “by reference,” most programming languages pass parameters “by value” in the default case. And some languages, such as Essence#, pass all parameters “by value.”

The following example will be used to illustrate the difference in the semantics:

var x = 3;
var y = f(x);

If the variable x is passed to the function f as a “by value” parameter, then it will be impossible for the function f to change the value of the variable x. However, if the variable x is passed to the function f as a “by reference” parameter, then the function f will be able to change the value of the variable x (although it may nevertheless refrain from doing so.)

Although there is more than one way to implement the two different ways of passing parameters, conceptually the difference is that, when arguments are passed “by value,” only the value of the argument is passed in to the function being called, whereas when arguments are passed “by reference,” the address of the argument (typically, the address of a variable) is passed in to the function being called. In the latter case, the called function may use that address to assign a new value to the variable–although it need not do so.

In fact, many languages implement “pass by value” semantics by physically passing in the address of the arguments that are passed “by value,” but nevertheless disallowing assignment to function parameters. As Peter Deutsch famously said, “you can cheat as long as you don’t get caught.” However, neither the CLR nor the DLR’s LINQ expression compiler cheat in that way: Unless a parameter is declared to require “pass by reference” semantics, arguments are passed by copying their values into the activation frame of the function being invoked.

So the problem for languages implemented on the CLR, such as Essence#, that have no syntax for specifying that parameters will be passed “by reference,” is that there’s no straightforward way to invoke the methods of CLR types that have any “pass by reference” parameters, where the intended usage is that the called method will, as part of its normal operation, assign a new value to an argument that is passed by reference.

And there’s an additional complication: Some methods that use “pass by reference” parameters will neither need nor use the initial value of the parameter, because they only set its value, and never “read” it. Conversely, others will use the initial value to compute and set a new value for the argument. And yet others may do one or the other with the same parameter, depending on the state of the receiver and the value of other parameters.

The C# language attempts to reduce the ambiguity regarding the usage model of “by reference” parameters by requiring that the method definer use different syntax to declare parameters, depending on whether the method will or will not use the initial value of a “by reference” parameter to compute and then set the argument’s new value. In the C# syntax, a parameter that is passed by reference must have one of two keywords as a prefix: out or ref.

The C# out keyword causes the compiler to require that the method that declares the parameter must first assign a value to the parameter before the parameter can be used–and before the method can return. That makes it impossible to use or access the initial value of the parameter. In contrast, the C# ref keyword causes the compiler to require that whoever invokes the method must first assign a value to the parameter.

But C# is not the only language used on the CLR, and the CLR itself does not enforce any constraints on the usage of “by reference” parameters. A .Net language’s compiler may do so, but such is not required by the CLR. That means there may exist .Net types that have methods that use “pass by reference” parameters that do not abide by the rules of C#.

The reflection metadata provided by the CLR does reveal, for each method parameter, whether it is a “pass by value” or a “pass by reference” parameter.  It may also reveal whether the intended usage of a “pass by reference” parameter is as a C#-style out parameter. But compilers are not required to provide that particular piece of metadata. The parameter may be used as an out parameter even if the reflection metadata makes no such claim. The only information provided by the reflection metadata that must be accurate is whether or not the parameter requires that its corresponding argument be passed “by value” or “by reference.”

So for now, Essence# deals with .Net method parameters that require that arguments must be passed by reference in one of two ways:

If the actual argument at runtime is anything other than a block or delegate, the dynamic binding subsystem will create and initialize a new variable that will be passed as the argument. Unless the reflection metadata claims that the parameter is an “out” parameter, the variable will be initialized to have the same value as the argument specified by the invoking code. The method will then be invoked with that new variable as the argument corresponding to the “by reference” parameter. When the method completes, the value of the created variable that was passed in as the actual argument will be assigned to the expression that represents the originally-specified argument. That assignment may cause an exception, and it may fail to update the original variable. I’m researching improvements, perhaps using the DLR’s Meta Object Protocol.

However, if the actual argument at runtime is a block or delegate, then the dynamic binding subsystem will create and initialize a new variable that will be passed as the argument (just as it does for the other case.) The method will then be invoked with that new variable as the argument corresponding to the “by reference” parameter (still essentially the same procedure as in the other case.) But when the method completes, the procedure is different: The one-argument block or delegate that was the originally-specified argument will be invoked, with the newly-created variable as its argument. That permits the caller to access the value of the “out” parameter, because its value will be the value of the block (or delegate) argument. Note, however, that the block or delegate must have an arity of one, and if it’s a delegate, its parameter type must be assignable from the parameter type of the invoked method’s parameter.

Example Usage

Let’s assume that we want to invoke the method Get as defined in the C# class named ValueModel shown below:

class ValueModel {
        private static readonly Object notAValue = new Object();

        protected Object value = notAValue;

        public bool HasValue {
                get {return value != notAValue;}
        }

        public void Set(Object newValue) {
                value = newValue;
        }

        public bool Get(out Object value) {
                if (HasValue) {
                        value = this.value;
                        return true;
                }
                return false;
        }
}

If we have an instance of the above ValueModel class in a variable named model (in an Essence# block or method,) we can invoke the Get method as follows:

[:model |
        | value |
        (model get: [:v | value := v])
                ifTrue: [value doSomethingUseful]
]

Or more simply, we could just do:

[:model | model get: [:value | value doSomethingUseful]]

Important: If the .Net method being invoked returns a boolean value, then the block will only be invoked if the .Net method returns true. But if the .Net method has a return type of void, or has a return type other than Boolean, then the block will always be invoked.

Static Typing And Interoperability

Static typing inhibits interoperability. It does so between class libraries and their clients, and also between programming languages.

The reason is simply because static typing violates encapsulation in general, and improperly propagates constraints that aren’t justifiable as architectural, design or implementation requirements in particular. It does so either by binding too early, or by binding (requiring) more than it should.

The reason that static typing violates encapsulation is because it fails to permit the object itself from being the sole arbiter of its own behavior, and the sole arbiter of the semantics of any operations that may be applied to it. It does that by forcing the programmer to break the veil of encapsulation of the object by directly referencing its class or type as the static type constraint of variables that will be permitted to contain objects of that type, instead of respecting the privacy of that information, which should remain hidden behind the wall of encapsulation that objects are supposed to provide. And then that information is used by the compiler to force the behavior of objects based on the static type constraint of the variables that reference them, as well as the semantics of the operations applied to them, thus violating encapsulation even more profoundly.

As usually implemented by widely-used programming languages, and therefore as typically used by program developers, static typing confuses the distinction between a class and the type that the class implements. And even in an ideal implementation in some language that almost no one will ever actually use in anger, it violates encapsulation by confusing the variables or parameters that reference a value with the class of the referenced value, the type of the referenced value, or (usually) both.

A class is not a type. It’s an implementation of a type.  Therefore, any system built on that false assumption is intrinsically broken at a very deep level. If you write code based on the idea that classes are types, you need to transform your thinking.

And a variable is not the value it references. Therefore, any system built on that false assumption is intrinsically broken at a very deep level.  The semantics of a variable is the architectural role(s) it plays in the algorithm that uses it. It is not the class of the value of the variable that the variable may be referencing at any particular time, nor the type that that class may be implementing at that particular time (the type that a class implements is not necessarily a static property of the class.)

As a concrete example, consider the usage of an array object in a statically-typed language which must hold objects of different types (or different classes, it makes no difference in this case,) and therefore must use Object as the static type constraint for the array’s element type (assuming there is no less-general common superclass.) Putting elements into such an array is easy, and raises no issues.  However, although it is equally easy to fetch elements from such an array, using the retrieved values for other than the most trivial purposes typically requires the programmer to over-constrain the retrieved value: The programmer is forced to constrain such values to being instances of some predefined type (which often also means constraining them to be instances of some predefined class,) before such values can be used in application-specific or domain-specific ways. The programmer must impose such constraints by casting the value to a specific type or class–which will fail if the programmer misjudges the type of the object, even though there would have been no failure had the programmer been allowed to use the value in the operations that were needed without having to cast the value to some specific type (because those operations would be valid for all the elements of the array, regardless of their type or class.)

Typically, one only needs to send one or two messages to values retrieved from a variable or from a collection. One usually does not need to send every message (or apply every operation) defined by a particular type or class. Therefore, requiring that a value must be an instance of a particular type or class is almost always requiring more than is necessary–and usually, far more. Imposing such unnecessary constraints inhibits interoperability because it reduces the generality of the code, reduces the generality of the entities the code defines, and reduces the generality of the the entities that the code can make use of.

And the violation of encapsulation bubbles up to higher-level entities: Classes, modules, packages, assemblies, class libraries and entire frameworks–which is how it inhibits interoperability, not only between class libraries or application frameworks and their clients, but even between different programming languages.

Static typing dramatically increases the coupling between components, because it not only exposes the specific entities that define and/or implement all the behavior of a value, it also requires that clients use precisely and only those specific defining or implementing entities, and typically prohibits the use of functionally/semantically equivalent alternatives that would have worked as desired. This is true even when interfaces are pervasively used as static type constraints (which is rarely the case in practice, and so should in all fairness be dismissed as a moot point,) and because clients must in any case use only the specific interfaces used and/or defined by the component providing the service they’d like to use.

Pervasively using interfaces as static type constraints, although it definitely helps, nevertheless remains a problem a) because interfaces typically require behavior that just is not needed every time one of their instances is used (which is almost always the case,) b) because interfaces defined by third parties–and the classes and methods that use them–generally cannot be changed in any way by their clients, and c) because it is possible (and even likely) that the various providers of “reusable” (ahem) components will separately define what are conceptually “the same” interfaces for the same purposes, which nevertheless won’t be type-compatible even if they have exactly the same names and require precisely all the same operations (messages, operators, etc.)

Why? Because “reusable” components from independent sources that use what are conceptually “the same” interfaces nevertheless cannot easily interoperate with each other, since two (or more!) interfaces that aren’t defined in the same namespace will be classified by the static type system as different, incompatible types, no matter how identical they are otherwise. That means that, for example, the function provided by class library A from source Alpha that transforms a video stream by applying a user-supplied function to the color of each pixel cannot be used with the function that performs the desired color transformation provided by class library B from source Beta, because the two class libraries each use their own “Color” interface, which is not type compatible in spite of having the exact same name and defining the exact same set of required operations with the exact same semantics.

And that’s a short–and incomplete–example of why and how static typing substantially reduces a programmer’s degree of freedom in combining and reusing code components from different, independent sources, relative to what it could be if programming languages used the open-world assumption instead of the closed-world assumption regarding which operations are valid. Operations should be assumed valid until that assumption is proven false, for reasons that are analogous to those that justify the assumption that a person accused of a crime is innocent until proven guilty, or those that motivate the assumption that the null hypothesis is true until proven false by actual experimental observation.

Most of human progress over the past few centuries is directly attributable to discarding the prior obsession with being able to present absolute proofs, and replacing that paradigm with what we now know and love as the scientific method, which is based on falsifiability instead of being based on provability. Our modern technology only exists because we gave up the idea that our models of the world must be provably correct, and instead started using the paradigm of falsifiability, as embodied by the scientific method.

The programming world is in severe need of a Copernican Revolution so that we can discard the ever-more complicated epicycles and contortions that the static typists go through to try to match the generality, reusability and productivity of dynamic programming languages.

Note: You can vote on this essay on Reddit

How To Develop Code For Essence# Using Your Favorite Smalltalk’s Development Tools

Essence# currently provides no support for any sort of GUI. Nor does it provide any code editing or code browsing tools. You might think that that means that the only way to develop code in Essence# is to use generic text editors, but such is not the case.

You could develop–and debug–your code using, for example, Squeak, Pharo or VisualWorks. That can be done because, unless your development environment’s Smalltalk compiler accepts (or worse, requires) non-standard syntax, the Essence# compiler can and will compile it. It will also accept/compile many of the common non-standard syntax extensions, such as qualified (“dotted”) names (VisualWorks, Smalltalk-X,) dynamic array literals (Squeak, Pharo) or even dynamic dictionary literals (Amber.)

So the heart of the issue is the differences in the standard libraries supported by other Smalltalk implementations. But that issue can be addressed by adding Essence# compatibility classes and methods to the environment where you develop your code, and by adding foreign-environment compatibility classes and methods to your suite of Essence# libraries/namespaces when you port your code to Essence#.

I expect a large body of such inter-Smalltalk compatibility code to be developed over time–some by me, and some of it contributed by others. In Essence# such special-purpose code modules don’t have to be installed by default. They can be partitioned into separate libraries that are only loaded when and as needed. So if you don’t need either the VASmalltalk or the Dolphin compatibility library, just don’t load them.

However, there is one obstacle in the path of this strategy: The file-out formats of other Smalltalk development environments are not at all the same as the Essence# class library format. Given that, it would actually be a lot of work to port code from VisualWorks, Squeak or Pharo to Essence#.

Or more correctly, it used to be a lot of work, because I’m using this post to publish and explain a solution to the problem: Code that will file out a class or class category from VisualWorks, Pharo or Squeak into Essence# class library format. The code can be obtained from the Essence# Tools Repository on GitHub. Although at present only those three development platforms are supported, it should not be too hard to figure out how to port one of them to another Smalltalk development platform. If you do so, please contribute it to the community.

The version of the code export tool for each of the three development environments is named EssenceClassLibraryExporter, and each has the same external API–which will be explained below. The one for Squeak is located here, the one for Pharo is located here, and the one for VisualWorks is located here. Warning: Don’t export code that you do not own, or that is not open source, unless you have the appropriate permission(s.) The VisualWorks class libraries published by Cincom are not open source, although the “Contributed” code may be (don’t assume; verify.)

After you’ve filed in EssenceClassLibraryExporter.st into Pharo, VisualWorks or Squeak, you use it by writing code in a workspace and executing it as a “do It.” Here’s what you need to know in order to do it correctly:

There are two key issues: 1) What code should be exported, and 2) what Essence# class library and namespace should it be exported to.

Because of the way the EssenceClassLibraryExporter works, it’s best to answer the second question first.

Selecting the target Essence# namespace

When exporting from VisualWorks, you probably should use the same namespace name in Essence# that you use in VisualWorks. But when exporting from a Smalltalk development environment that doesn’t have (or doesn’t typically use) namespaces, you’re faced with an architectural decision that you didn’t have to make until such time as you needed to export your code to Essence#. You can, of course, simply export your code to the Smalltalk namespace. But best practice would be to define and use a namespace in Essence# that’s specific to your project (unless you are deliberately extending a namespace authored by someone else.)

Namespaces in Smalltalk have always been controversial. There is a vocal and influential subset of the Smalltalk community that opposes them. So I am going to address that issue upfront:

First, I must point out that all ST80-compliant Smaltalk implementations that support “shared pools” actually do have and use namespaces. That’s precisely what a “shared pool” is: a namespace. Shared pools could be used to do all the things that namespaces do, but for the fact that the ST80-style compilers and code browsers generally used (with the notable exceptions of VisualWorks and Smalltalk-X, and soon Essence#) haven’t been designed to make such usage elegant and easy. But they could be.

And Smalltalk classes also act as namespaces, in that they can define “class variables” that can be used to change the meaning of references to variables defined in the SystemDictionary. And “shared pools” can have the same effect. Consequently, having formal support for modern, first-class namespaces adds no code comprehension or interpretation issues that were not already present even in Smalltalk-80 ca. 1983, as distributed by XSIS.

But the bottom line is that computer science long ago learned that different name binding scopes are necessary–and become ever more necessary as the size of the code base increases, and as the number on independent contributors increases. That’s why objects provide their own “namespaces” for their instance variables, so as to keep each object’s set of named instance variables separate and distinct from that of all other objects, even when the names of the variables are the same. It’s why each method defines and uses its own “namespace” of parameters and local variables–and why blocks do the same. The bottom line is that Essence# (and VisualWorks, and Smalltalk-X, and .Net, and most modern languages) provide namespaces that localize and encapsulate references to non-local variables for analogous reasons, to solve problems that are essentially the same, using a very similar solution, justified by issues and logic that are also largely analogous.

To the extent that multiple name binding scopes cause problems of comprehension or interpretation with respect to the meaning of named variable references, they do so universally for named variable references of all types and in all contexts: Block and method parameters, block and method local variables, function parameters and local variables, the fields of records/structs, the named instance variables of objects, the class variables and shared pools of ST80, the static variables of C++, C# and Java, and modules/assemblies/programs that contain multiple classes and/or functions.

If, on balance, programmers and the code bases they write get more benefit than harm from having separate name binding scopes for class variables, instance variables, parameters and local variables, why would that not also be the case for classes?  Is that not one of the key benefits provided by having separate program files in the case of file-based languages, and separate images in the case of image-based Smalltalk systems? If separate name binding scopes are bad when provided by formal, first-class namespaces, why are they not also bad when implemented by having different images, or by having different program files?

For those reasons, opposition to formal namespaces as first-class objects has always seemed to me to be the equivalent of opposition to compilers by old-school assembly-language coders, opposition to structured-programming by old-school FORTRAN and COBOL coders, opposition to OO by old-school procedural programmers and opposition to dynamic typing by those who think a variable is semantically equivalent to the object it references, and/or that a class is semantically equivalent to the type (concept) it implements.

I’ve used VisualWorks with namespaces for a decade and a half, and have never encountered the issues that opponents of namespaces say they fear.  Not once, not ever. That’s one reason it reminds me so much of opposition to dynamic typing.

Get over it. Move on: Formal namespaces as first class objects solve more problems than they cause. The proof is in the experience of those who’ve been using them for one or more decades now, and in the ever-increasing adoption of them in modern programming systems and languages.

Selecting the target Essence# class library

Conceptually, an Essence# class library is an independently-loadable code module. It roughly corresponds to what other languages/platforms call a “package,” “module,” “parcel” or “assembly” (and these, too, were historically opposed by some; thankfully, they “got over it.”)

It’s important to note that an Essence# class library can contain one or more Essence# namespaces, that the same Essence# namespace can occur (be defined and/or modified by) more than one Essence# class library, that namespaces are an essential and foundational aspect of the .Net platform, and that Essence# namespaces were designed to deal with the fact that namespaces are so central to the way that the .Net framework operates.

You partition your code base into one or more class libraries so that your code modules can be loaded when and as needed as logically-consistent and cohesive units of functionality. You partition your code into one or more namespaces in order to isolate the named entities in your code base from unwanted name clashes with other parts of your own code base, or from unwanted name clashes with code from third parties (of which you may have no knowledge or even interest.) That’s two separate concerns solved by two separate mechanisms (“objects,”) which is proper OO design.

Key point:  You probably should not export your code to the Essence# Standard Library, for the reasons explained in the Essence# documentation section on CodePlex, under the heading Handling multiple releases of Essence#. For one thing, it puts your work at risk of being overwritten when you merge with a new release of Essence# using the Essence# installation program. Using your own private Essence# class library avoids all risk of that happening, and provides several other important benefits that I won’t go into here.

Using the EssenceClassLibraryExporter

The following code snippet will export the class named MyClass to the Essence# class library MyClassLibrary in the Essence# namespace MyNamespace, assuming that MyClass is locally defined in the namespace Smalltalk (i.e., that’s the namespace in which the class is defined in the Pharo, Squeak or VisualWorks image you’re using):

EssenceClassLibraryExporter libraryPath: #('MyClassLibrary').
(EssenceClassLibraryExporter 
        exportingTo: 'MyNamespace' 
        from: Smalltalk)
                exportClass: MyClass

By default, the exported code will be placed in the current working directory of your Smalltalk image. So in the case of the example above, the folder representing/implementing the target Essence# class library would therefore be the current working directory of your Smalltalk image, and the target namespace would be implemented/represented by the folder MyNamespace, which would be created as a direct subfolder in the image’s current working directory.

To use a different folder as the target Essence# class library, send the message #libraryPathPrefix: aPathnameString to the class EssenceClassLibraryExporter before exporting your code, as in the following example:

EssenceClassLibraryExporter libraryPathPrefix: 
        '/Users/myUserName/Documents/Developer/EssenceSharp/Source/Libraries/'.

To export to a nested Essence# namespace, use a qualified named (“dotted notation”) for the target Essence# namespace name, as in the following example, which would export to the nested namespace MyRootNamespace.MyNestedNamesapce, at the absolute path ‘/Users/myUserName/Documents/Developer/EssenceSharp/Source/Libraries/MyClassLibrary/MyNamespace/MyNestedNamespace/’:

EssenceClassLibraryExporter libraryPathPrefix: 
        '/Users/myUserName/Documents/Developer/EssenceSharp/Source/Libraries/'.
EssenceClassLibraryExporter libraryPath: #('MyClassLibrary').
(EssenceClassLibraryExporter 
        exportingTo: 'MyNamespace.MyNestedNamespace' 
        from: Smalltalk)
                exportClass: MyClass

To export all the classes in a class category, replace the message #exportClass: aClass as in the examples above with the message #exportClassCategory: aSymbolNamingAClassCategory, as in the following example:

EssenceClassLibraryExporter libraryPathPrefix: 
        '/Users/myUserName/Documents/Developer/EssenceSharp/Source/Libraries/'.
EssenceClassLibraryExporter libraryPath: #('DevelopmentTools').
(EssenceClassLibraryExporter 
        exportingTo: 'SystemTesting.SUnit' 
        from: Smalltalk)
                exportClassCategory: #'SUnit-Core-Kernel'

If you use the Pharo version of EssenceClassLibraryExporter (in a Pharo image, of course,) then Traits will be handled correctly.

The next release will introduce “Traits” into Essence#

Seminal paper on Traits: Traits: Composable Units of Behaviour.

Traits are even more useful, and more needed, in Essence# than they would be in a typical programming language because of Essence#’s primary mission: interoperability with other languages, and especially with the .Net Base Class Library.  That’s because the .Net BCL was designed and implemented for statically-typed languages, where it is often either impossible or greatly inconvenient to use a common inheritance hierarchy for conceptually similar constructs. Traits provide the right mechanism to rectify that flaw. They also make it easier to provide an identical API for both native Essence# objects and for those provided by the .Net BCL.

The Essence# Standard Library source code is now available from GitHub

Link to GitHub repository: https://github.com/EssenceSharp/Standard.lib

It will probably often be the case going forward that the only changes in a new release of Essence# are in the source code of the Standard Library, because they won’t involve changes to the C# code of the compiler and/or run time system–which is the only version-controlled code available from the Essence# Codeplex site.

There may also be versions on GitHub that are later than any version published on the Essence# Codeplex site

‘Babel’ – The new release of Essence# which focuses on integration issues

Unlike the situation with most programming languages, an Essence# programmer is expected to add to and even change classes and methods in the language’s standard library. And the same would be true of any classes or methods defined (owned) by those who publish class libraries meant to be shared with and used by others (whether “open source” or otherwise.)

But that creates a problem whenever the time comes to acquire and integrate with a later version of a class library for which the programmer isn’t the principal author, but which he nevertheless extends or even modifies. The Essence# Standard Class Library is one example, but certainly not the only one.

A perfect solution to this problem would automagically merge all changes made by the publisher of the class library and the clients who extend or modify it. Perhaps in times to come, artificial intelligences will take care of that for us without us having to worry our inferior wetware brains about it, but that time is not yet. Nevertheless, Essence# does have a somewhat unique solution to this problem, and I’m going to use this “release announcement” to describe and explain it.

To understand the Essence# solution, it is first necessary to understand how class libraries work in Essence#:

An Essence# class library is a container of namespaces, which in turn are containers of classes and/or other namespaces. Of course, that’s pretty much the definition of both of those terms in most modern programming languages, so nothing new there. So here’s where Essence# diverges from the norm:

  • An Essence# class is also a namespace. It has all the same behavior, capabilities, features and functions as an Essence# namespace. And Essence# namespaces and classes are objects. They can be sent messages at run time. And those messages can modify or even totally redefine the namespace or class to which they are sent.
  • It’s possible for the same class (or namespace) to reside in multiple namespaces–even under different names–because the identity of a class or namespace at runtime is a function of its identity as an object, and not a function of its name.
  • And it’s also possible for the same classes and namespaces to be defined/declared in different class libraries. Two different Essence# class libraries may define completely different namespaces, classes and methods, or they may define all the same ones, or (far more likely) they may mostly define different namespaces, classes and methods, but have some (usually small) overlap. This is possible because namespaces, classes and methods are not created and grouped together declaratively, but instead by means of message sending. If namespaces, classes and methods were defined declaratively, then any differences between how they are declared in one class library and the way they are defined in another would create a logical contradiction, because logical declarations are universal invariants which must hold everywhere for all time. Since Essence# namespaces and classes are intrinsically dynamic, differing definitions do not create a system panic: The system is designed to permit such things to change over time. So, if “the same” class can differ from itself from one moment to the next as the program runs, then it can certainly differ from itself with respect to how it is defined in various and sundry class libraries. Therefore, such differences need not–and do not–cause any errors at compile time.
  • An Essence# code base can and does contain what would, in a static language where classes are defined declaratively so that their name, form and behavior are invariants of the system, have to be treated as “logical contradictions,” and so disallowed as compilation errors. In Essence#, one dynamically specifies which class libraries will be loaded into the execution environment, and in what order. That is how different class libraries are merged together into a unified whole for a specific invocation of a program, where the last library loaded “wins” any disagreement over the definition of a namespace, class or method. Even better, a class library that merely wants to extend a class by adding a method can do so without a) knowing all the methods defined for the class by any other class library, and b) without thereby deleting all those methods it knows nothing about. The same is true for any methods it modifies. To put it another way, Essence# does not operate using the “closed world assumption” that if a class library does not assert a fact about a class, then that fact must be false. The messages a class library sends that construct or modify a class are never interpreted by the system as the final and complete definition of the class, to the exclusion of the “declarations” made in other class libraries about the same class.
  • Finally, Essence# class libraries are always stored separately from each other. That means they can change independently of each other, even when they define, or modify the properties of, the same namespace, class or method. That also means that that a new version of one library has no effect on the code of another, ever–even if they define the same class or method. Yes, they still may conflict with respect to the form, structure or behavior of a class, but such conflicts would only matter when both are loaded into the same execution context. More importantly, such conflicts can be resolved by yet another class library whose sole purpose and function is to modify the namespaces, classes and methods that have been loaded into the execution environment so that they operate together usefully, and as intended by whoever put them together into a unified solution.

So Essence# handles integration conflicts by a) keeping the “(source or object) code of record” of class libraries distinct from each other permanently, and not just as a necessity of packaging and/or distribution, b) enabling full dynamic control over which class libraries are loaded into the execution environment created when a program is launched, and providing full control over the order in which the class libraries will be loaded, and c) using and embracing the dynamic malleability of objects, including those that are namespaces, classes and methods, instead of fighting against it.

The ‘Babel’ release can be downloaded from the Essence# site on Codeplex.