Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'m writing a framework which describes the concepts within static high-level l

ID: 642838 • Letter: I

Question

I'm writing a framework which describes the concepts within static high-level languages (like C#, VB.NET, et cetera). As a part of that, it involves synthesis of the structures that describe those concepts.

One question I had was about what's called Structural Typing, which I aim to implement through type-parameters (constructors with parameters would be a definite addition.) It's a concept that neither C# nor VB.NET implement.

The question I have today is: is structural typing in a hierarchical model necessary?

One small example that I can think of is models developed that rely on patterns, but don't necessarily have an interface to specify this pattern. This is useful in instances where you want to use the code for multiple base types without a common ancestor, but with similar structure.

If you wanted to display a list of items to the Console via their name, you'd need to write one method for the lowest common ancestor that defines that name property. Person, Control, and Type would all use different methods, as an example.

If implemented, the resulted code would look something like:

public static void DisplayNames<T>(IEnumerable<T> namedItems)
    where T has
    {
        ///<summary>Returns the item's name</summary>
        string Name { get; }
    }
{
    foreach (var namedItem in namedItems)
        Console.WriteLine(namedItem.Name);
}
The '[' and ']' are used for disambiguation reasons (it'd be difficult to try to discern the body of a type-parameter's structure from an interface's structure otherwise.)

Suggestions welcome.

Explanation / Answer

It looks like you are trying to combine compile-time safety with duck-typing.

C++ templates already do this automatically - you can attempt to call anything on a template's parametrized type and it will fail to compile if the template type does not support that call. Things are kept generic by another template feature: if you do not use a specific feature of a specific template instantiation (implying a specific parametrized type), then it doesn't matter that a definition exists which does not compile. If you don't use it, it's not an error. Example:

class MyClass
{
public:
MyClass() {}
std::string GetName() const { return "MyClass"; }
};

template<typename T>
class TMyTemplate
{
public:
TMyTemplate()
{
std::cout << myClassInstance_.GetName();
}

void ConceptMemberFunction()
{
std::cout << myClassInstance_.ConceptFunction()
}

private:
T myClassInstance_;
};


int main(void)
{
TMyTemplate<MyClass> myTemplate; // Compiles just fine.
// myTemplate.ConceptMemberFunction(); // Compile-time error
}
This feature of templates can be used for compile-time "concept checking" (see boost::concept_check) - create and instantiate a template that "uses" the specific features that the concept requires - compilation will fail if the class does not support all the required features.

Are these the concepts you are referring to in your question?