5 ms·
Ask HN: Do we have a programming language with a permission system?
I was wondering why don't we have / if it exists why don't we use a programming language with a permission system?
TLDR: Declare variables as `let some_var: rw i32` for a read-write i32.
I was looking into Val and Rust and we can see that they have different semantics for different things you can do with variables. In rust you can use &T to borrow (which is like read-only), &mut T to read-write and T to own. Val has similar semantics with let, inout, sink and set. However, some of them "encompass" others. For example, if I pass &mut T I can read and write to the variable, if I pass T I take full ownership and I can read write and own it. There is no such thing as "write-only" or "own-only" (correct me if I'm wrong).
So why not have a language that defines these as a permission based system? Let's stick with read write own as `r w o`.
Ex:
fn foo(x: r i32){
let a: w i32 = x; // passes
x = 42; // fails
}
// Take ownership, x cannot be used outside after this is called.
fn foo2(x: o i32){
let a: w i32 = x; // fails
x = 42; // fails
}
fn main(){
let x: rwo = 23;
foo(x);
foo2(x);
print(x); // fails because foo2 took ownership and dropped it.
}
- deleted 3y ago[deleted]
- flohofwoe 3y agoI'm not aware of any but I've been thinking about this too, but more on the level of "code regions" vs "nested data structures". Currently access is often regulated by knowledge of a reference/pointer to some specific piece of data. I'd like all application data to accessible via one big nested data structure without knowing "secret" pointers or references which grant access, but instead just filesystem-path-like accessors, e.g. 'root.gfx.buffers.count'. Then restrict certain sections of the code to have no access, read-only access or full read-write access to certain parts of the data. Pretty much as if the application data is a file system, and certain code sections/subsystems are users/groups. (for instance only a physics subsystem has full read/write access to its data under 'root.physics', some other subsystems that need to inspect the current state of the physics world only have read access, while all other subsystems have no access at all)
- zademn 3y agoSounds interesting. However, it seems...cumbersome? to define for each code block the relation with each data structure. Maybe if you can abstract a "code block type" and build relations between that type and some data. Something like struct Player{ int rwo hp; int rwo damage; Vec<Items> rwo inventory; } codeblock hpSomething{ uses rw Player.hp; uses r Player.inventory; } int main(){ // init player that fought something hpSomething { // read a potion and heal potion = player.inventory.potion.value; player.hp += potion; } }
- mmmmmbop 3y agoInteresting. C++ sort of has parts of this concept with const and std::move operators. From your code example, I feel like one problem is that arguments are passed the same way wether it's r, w, or o. Meaning that if e.g. the foo(x: r i32) API changes to foo(x: o i32), your code that was previously modifying x afterwards would now break.
- zademn 3y agoI didn't dive deep into C++, the main idea is to let users "compose" different permissions instead of the language composing them for us by giving some keywords. You are correct, the code example is minimal, we can introduce some semantics to how we pass arguments too. I wanted to focus on the idea of composing permissions.
- Someone 3y agoI remember reading about one long ago, but don’t remember anything more. Google gave me https://marioskogias.github.io/docs/enclosure.pdf https://marioskogias.github.io/docs/enclosure.pdf. That isn’t what I saw then, but it does use R, RW, and RWX.
- brudgers 3y agoNot sure if it's what you are looking for, but contracts seem to be a fine grained version of control beyond read and write. For example as available in Racket: https://docs.racket-lang.org/guide/contracts.html https://docs.racket-lang.org/guide/contracts.html Good luck.