As you may know, I am working on a Domain Specific Language in the context of my InnuenDo Web 3.0 stack (that aims to focus on HIVE first before branching out to other Web 3.0 chains).
The Domain Specific Language ( Merg-E ) tries to be a least-authority security first language, and that is exactly where I need feedback about at the moment.
In the language variables (called muttable in Merg-E speak) are considered to imply authority. They are passed by refference, or in some cases by wrapped refference, but that is not relevant here, while constants (non-mutable) are considered non-authority entities.
When something is mutable, a wide range of ownership primitives governs what happens when something is handed over to a different execution context like a function, including rules for variable capture in closures that Merg-E makes explicit:
int8 increment = 1;
shared mutable int64 counter=0;
mutable function silly ()::{
counter;
}{
lock(counter) {
counter = counter + increment;
}
}!!{
};
blocker c4;
c4 += silly();
c4 += silly();
c4 += silly();
c4 += silly();
await.all c3
Notice the '::{}' part where the shared mutable counter is explicitly captured from the clossure by the function definition? Also notice that the constant increment is implicitly captured. This is by design because in Merg-E access to mutables is considered to imply authority while access to constants does not.
It is generally considered bad practice to hard code sensitive data or a secret string like a password or an API key into your code, but people do it all the time.
string api_key = "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173";
This breaks the Merg-E assumption that constants don't ever hold any authority.
But now comes the dilemma. We couls add a modifier to the language like secret or sensitive and make it communicate to th compiler that this constant does hold authority, and thus should not get captured implicitly:
sensitive string api_key = "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173";
But if we do that, aren't we sending the wrong message to users? Are we makeing the language less safe by making it safer but incentifying unsafe code?
I've been thinking about using a naming convention I used in two different ocasions, using thwe modifier "hazardous" to denote a potentilay hazardous coding practice, but the two situations where I use that modifier, the language runtime itself is actually made less safe by the usage of the construct:
lock(counter) {
borrowed mutable int8 random;
hazardous blocker haverandom;
haverandom += get_random_int8(random);
await.all haverandom;
counter = counter + incremwent + random;
}
In this case we tell the compiler that yes we know it is hazardous to put a blocker inside of a lock, but we know what we are doing, and we accept the measures the scheduler will have to take to make the use slightly less hazardous, wisking starvation of non hazardous tasks while racing to schedule get_random_int8 and any of "its" hazardous blocker linked tasks and their continuations as quickly as possible.
And the second one:
hazardous prune scope.imported.lang.Amplify;
Here we tell the compiler that yes we know soft pruning a DAG is p[otentialy non deterministic, but we want the compiler and/or runtime to try anyway, pruning the DAG in a potentially unsafe way.
But this would be ambiguous:
hazardous string api_key = "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173";
Because in fact it is the "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173" bit that is hazardous, using this modifier makes api_key safer to use.
I could opt for:
string api_key = hazardous "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173";
But currently rvalues can't have modifiers, and changing that would be a major change to the semantic lexer, and frankly I'm not sure if this edge case is worth that much trouble.
An other rather impactfull change would be reversing the default (like I did by making mutable rather than const a modifier. If I do that, constants won't be implicitly captured anymore, what is quite a change from the current design, this would work as needed:
string api_key = "secret_bd93f7d7ba08410ac0beda6f070e11d3d6708173";
But the first bit of sample code would need an extra explicit modifier indicating that the constant doesn't hold any authority. The word inert might be suitable, I'm not quite sure:
inert int8 increment = 1;
shared mutable int64 counter=0;
mutable function silly ()::{
counter;
}{
lock(counter) {
counter = counter + increment;
}
}!!{
};
blocker c4;
c4 += silly();
c4 += silly();
c4 += silly();
c4 += silly();
await.all c3
So right now, if you are reading this, even if you understand only half because the examples are in a language that you don't know and that for the most part doesn't exist yet, that doesn't disqualify you, please give me your feedback on this dilema.
What do you think?
- Leave the language as it is, no changes, don't incentify bad coding
- Add an (lvalue) modifier like sensitive to indicate the constant contains sensitive data
- Somewhat ambiguouslym ad an (lvalue) modifier hazardous like the other two uses of hazardous already in the language
- Change the language to allow for rvalue modifiers and mark the string itself as hazardous
- Reverse the idea that by default constants have no authority and make a modifier like inert that tells the compiler the constant has no authority.
All input is apreciated.
I'm creating a comment for each of the options below, rewards burned, please vote with 1% on what you think is hte best option.
And the winner is... lucky no. 1
Just look at what OpenSSH did as a Blueprint, less is more.
Programming languages that allow for crazy levels of complexity generally bite the end users hand off at some point, less complexity is good :)
1: Leave the language as it is, no changes, don't incentify bad coding
Vote with a 1% vote if you think this is the best option
2: Add an (lvalue) modifier like sensitive to indicate the constant contains sensitive data.
Vote with a 1% vote if you think this is the best option
3: Somewhat ambiguously, ad an (lvalue) modifier hazardous like the other two uses of hazardous already in the language.
Vote with a 1% vote if you think this is the best option.
4: Change the language to allow for rvalue modifiers and mark the string itself as hazardous.
Vote with a 1% vote if you think this is the best option.
5: Reverse the idea that by default constants have no authority and make a modifier like inert that tells the compiler the constant has no authority.
Vote with a 1% vote if you think this is the best option.