Comment by robalni

2 days ago

I think the point you missed or don't want to accept is that I think of all layers of memory management as the same thing just on different layers. Where you say that I mix different concepts, I say that it's just different layers of the same problem.

So which layer should we care about? All of them? Yes, if we want the most safety.

I will give you an example of how I can use memory incorrectly in "safe" rust. Let's say I have an integer that contains my age. Now I forget what the number was used for and I use it as shoe size. I have now used memory (the content of the variable) as something it was not intended for. Maybe you think this example is silly, but what is really the difference between using a float pointer as an int pointer and using age as shoe size? Another thing we could do is to use an index for one array as an index for another array. That's an example of using a pointer as the wrong type because an index is just a relative pointer.

So if we want to care about all layers of memory safety then we have to care about not using ages as shoe sizes and indexes with the wrong arrays. "Memory safe" languages usually don't help us with that and therefore they don't give us total memory safety. I think "memory safety" is not a very useful term because all data in a program lies in memory and basically all bugs have something to do with using that memory in wrong ways.

> we have to care about not using ages as shoe sizes and indexes with the wrong arrays. "Memory safe" languages usually don't help

In languages even slightly better than C one can create a wrapper type for int/float with additional semantics like age, shoe size or something else. Since they are different types, using one in place of other isn't possible. This doesn't solve all problems, but at least can prevent silly mistakes.

  • Interesting, I have had ideas about having that feature in a language: being able to make subtypes, like "this is an integer but on the next level it is a shoe size". Can you give an example of such a language or how they usually do that?

    • Haskell: newtype ShoeSize = ShoeSize Integer

      (The first ShoeSize is the type name, the second is the name of the constructor that converts an integer to one, or pattern-matches on it. This is unambiguous in Haskell and they are often the same. It has symmetry with "data" which is for more general ADTs that can have more than one constructor.)