ark-lang / ark

A compiled systems programming language written in Go using the LLVM framework
https://ark-lang.github.io/
MIT License
677 stars 47 forks source link

The state of references. #703

Open kiljacken opened 8 years ago

kiljacken commented 8 years ago

First up, sorry for pseudo-necroing #631.

For a while I've been iffy about our inclusion of references. I don't really see the point of having them as they provide little to no benefits. As I am in this state of mind I'd like to put the debate to rest once and for all.

TL;DR: References coercion/casting ruins everything. However, not having that results in references only being usable where the equivalent pointer would never be null in any case. Skip to end for proposal.

Now, on to the actual meat of this post. Back in January @0xbadb002 mentioned the following benefits to references, which is the main reasons why still have them:

  • should always point to an object (i.e. shouldn't be nullptr/NULL)

The weight here is on should. In most cases a pointer should point to something as well, but there is no guarantee there either. In the trivial case where we could guarantee that a reference was not null, we would trivially know that the corresponding pointer isn't null either. This case is illustrated by the following example:

a := 0;
f(&a); // We could use ^ here and maintain the same guarantee

With the inclusion of pointer to reference coercing this guarantee is even weaker as a null-pointer could easily be coerced to a reference, without any sort of warning:

type Thing struct { b: ^int };
a: Thing = ...; // Assume we get this from somewhere else

// I want to pass the backing memory of a.b along to a function taking a
// reference. This works nicely with coercion, but what if b is null?
f(a.b);
  • you can't take the address of a reference

I imagine this refers to the C++ way of doing references, as this isn't really applicable to the concept of references in Ark. Currently references are just another type of pointer, and thus taking the address of it makes little sense. We do however prohibit returning references or composite types containing them.

  • you can't re-seat a reference, but you can change a pointer as much as you like

Again I believe this refers to the C++ reference, as this is not the case in Ark.

  • you can't perform arithmetic with references (not even sure if we're supporting this with pointers anyway, but still relevant)

As we allow casting references to and from uintptr this guarantee doesn't hold.

As you see many of these issues occur due to a lack of isolation on the concept of references. To maintain these guarantees we would have to remove all casting and coercion from/to references from Ark. With changes like this the actual usability of references would be limited to the cases where the programmer wouldn't even doubt for a second that the equivalent pointer is null, that is the cases I illustrated with the first example.

Proposal: As I really don't like having the references in the current state, I believe that we should either completely redesign how we plan on implementing them and thinking things through or we should straight up remove them from the language.

felixangell commented 8 years ago

I guess I'm okay with the removal of references

felixangell commented 8 years ago

I should probably clarify this is quite a sudden change from my initial argument... but the points you raise here are valid

MovingtoMars commented 8 years ago

References give us a safe way to pass stack memory to a function, since we know a reference can't outlive the value if points to.

They also allow us to say that a function takes a memory argument, but doesn't return it or store it anywhere. This is good for ARC pointers since it means we don't need a ref check.

If we can figure out a way to do this without references, we should remove them.

kiljacken commented 8 years ago

Your points do not hold as long as we allow casting of references to uintptr, as I described in my rant.

MovingtoMars commented 8 years ago

Basically, the idea is that uintptr is by design unsafe, so guarantees may not still hold.

kiljacken commented 8 years ago

But what is the point of having a guarantee that you can't guarantee, that is what I simply don't get. If we do not lock down the references and actually guarantee those things, they provide no real safety. It's like the whole const mess in C++.