Thursday, 28 July 2011

Const- a library feature

The question here is quite simple. How do you implement const as a library feature, allowing users to introduce arbitrary attributes?

The solution here is TypeReference, and it's parallel, FunctionReference. Const is really a type thing, but pure and threadsafe are function things (maybe threadsafe is an object thing too?) I already said that types were references, and now it becomes explicit with type_reference. Type references will not just be pointers, they will also store attributes and, critically, function hooks. When you access data about a type through a type reference, then the results will be influenced by the hook. In the case of, for example, member variables, then they will become const recursively. In this case, we will need a structure to define an attribute.

We will need to know what it means to add const to a type reference. We will need to know what it means to take it away- both in reference versions, as well. Some attributes are trivial to add- e.g., const. Some attributes will be trivial to take away- e.g., threadsafe.

type Attribute = type {
   Standard.Functional.Function(void, TypeReference) OnAdd;
   Standard.Functional.Function(void, TypeReference) OnAddReference;

   Standard.Functional.Function(void, TypeReference) OnRemove;
   Standard.Functional.Function(void, TypeReference) OnRemoveReference;

};
For const, some of these definitions will be relatively trivial.

using Standard;
using Compiler;
using Attribute;
using Algorithms;
var Attribute Standard.Attributes.Const;
Const = [&] {
    var Attribute attribute;
    

    attribute.OnAdd = [&](type) {
        ForEach(type.member_variables, [&](member_variable) {
            member_variable.Type.AddAttribute(Const);
        });
        var mem_functions_copy := type->MemberFunctions;
        type.MemberFunctions.Clear();
        ForEach(mem_functions_copy, [&](member_function) {
            if (member_function.arguments["this"].HasAttribute(Const)) {
                type.MemberFunctions.Insert(member_function);
            }
        });
        type->OnChange(
            event = MemberFunctionAdd,
            action = [&](member_function) {
                if (!member_function.arguments["this"].HasAttribute(Const)) {
                    type.MemberFunctions.Remove(member_function);
                }
            }
        );

        type->OnChange(
            event = VariableAdd,
            action = [&](variable) {
                variable.AddAttribute(Const);
            }
        );
    };
    

    attribute.OnAddReference = [&](type) {
        OnAdd(type.Unref());
    };



    attribute.OnRemoveReference = [&](type) {
        throw Standard.Compiler.BuildError("Error: Cannot bind non-const reference to const object.");
    };
    attribute.OnRemove = [&](type) {
        type.MemberFunctions = type->MemberFunctions;
        type.MemberVariables = type->MemberVariables;
        // Also remove the OnChange functions
        // Not too sure how to make that happen :(
    });
    return attribute; 
};


So what does all this mean? It means that when you add const to a TypeReference, the type becomes const, and all the member variables of that type become const, and all member functions are removed except those where "this" is marked as const. It means that you can trivially add const to references, and that when you do so, the referred-to type becomes const. It means that if you attempt to instantiate a non-const reference to a const object, then the compiler will cry like a little girl. It means that if you add a member function or variable to a type, then the references will update themselves accordingly.

This is pretty much it for the definition of const and how const behaves. However, we still haven't defined what const means. Right now, we could use "const" to mean anything, it's more aptly named as TriviallyAddableNonReferenceRemovableDiscriminating. That definition comes from which members we choose to mark as const. Obviously primitive types will follow the conventions. Other specifiers, like "pure", could come with different costs or accesses.

No comments:

Post a Comment