In a recent post, I discussed plans for my Const attribute system. However, I'm not completely sure about how this is going to work. Now, function attributes and type attributes will likely have to be different things, so let's pretend that I named the previous Attribute type something type-specific like TypeAttribute, and get rolling. The first problem is that the syntax completely doesn't support attributes. At all. I could use this as a keyword but that would conflict with the object this for member functions. I might have to flat out cut function definitions as they are in C++ and completely replace them with lambda expressions.
FunctionReference f([&]() {
f.Attributes(Pure, Threadsafe);
return []() {
};
});
Alternatively, I had plans for "this" to be just another argument... maybe I should just cut "this" as a reference to the object, and set it to be a reference to the function? Another problem is member functions.. again. I can't use this syntax for them, because that would create a run-time FunctionReference, which is not what I'm looking for. I would basically have to cut type and function literals and just go straight to lambdas and types as just another container. In that case, how does one create Types if not by literal? Default-construct a TypeReference? Maybe call a function?
Another problem is going to be dealing with types that have attributes. For example, FunctionReference and TypeReference. You can add attributes to them- but what if I want the actual TypeReference itself to be Const instead of a TypeReference to a Const type? Maybe decltype() can solve that problem.
decltype(FunctionReference).Attributes(Const) f([&]() {
f.Attributes(Pure, Threadsafe);
return []() {
};
});
decltype(TypeReference).Attributes(Const) MyClass([&]() {
TypeReference T(TypeReference.New());
T.PublicMemberVariables.Insert("ohai", Standard.Containers.String);
return T;
});
Owch. You know, I think a little method chaining could
using Standard;
using Compiler;
using Containers;
using Attributes;
TypeReference MyClass([&]() {
var x = TypeReference.New()
.PublicMemberVariables.Insert("name", String)
.PublicMemberVariables.Insert("type", TypeReference);
x.OnChange(
event = any,
Action = [](arg) {
throw Standard.Exceptions.Error("Attempted to modify MyClass!");
}
);
});
It's not that bad. I can work on it. Maybe I could stick with "type" as the type literal. Now on to the decidedly non-trivial problem: How to define a FunctionAttribute. I suspect that fundamentally, we will ask mostly the same questions as of a TypeAttribute- what happens when we add it, and what happens when we take it away.
decltype(FunctionAttribute).Attributes(Const) Pure([&] {
Pure.OnRemove = [&](Function) {
// remove trivially
// remove the hook we added
};
Pure.OnAdd = [&](Function) {
// Verify that the function is actually pure by checking the expression contents and only calls
// other pure functions
// Make sure that nobody changes it behind our back
Function.OnChange(
Event := change, // maybe only one event is possible with Functions?
Action := [&](Function) {
// Verify pure, or throw
}
);
};
});
ThreadSafe is going to be another kind of problem. I could simply propagate it like const or pure, but fundamentally, a single function cannot be proved to be threadsafe. I guess that I could quite explicitly prove that it doesn't have some kinds of threading bugs, maybe.
No comments:
Post a Comment