[External] : Re: Question about circular references

David Alayachew davidalayachew at gmail.com
Tue Jul 4 17:52:21 UTC 2023


Hello Ron,

Thank you for your response!

> > But regardless, you are declaring this out of the blue.
> > Where are you coming from when you say this? What backs
> > this statement up? I have come to you with widely
> > accepted definitions. If you are going to say that final
> > fields, in this instance, don't permit cycles, I need you
> > to explain how and why, not just claim that they do.
>
> For the purpose of this discussion, final is a feature
> that requires a field to be assigned (only once) in the
> constructor. If it’s assigned a value arriving to the
> constructor from the outside, then that value cannot the
> object currently being constructed. (Yes, you can get
> around that by passing `this` from a constructor to other
> constructors). This is in contrast to non-final fields
> that can be assigned outside the constructor, and so can
> be assigned in methods that receive the current object
> itself as an argument, something that the constructor
> cannot do.

Ok, I think I see where the problem is.

When you say "final fields do not PERMIT cycles", I am interpreting that to
mean "whether or not cycles are representable, they are not permitted, and
this is by intention". Whereas I think you are saying "final fields are
unable to have cycles because pre-existing mechanics prevent it, even
though there is nothing explicitly forbidding it with intention".

If that is the case, then we have been talking past each other.

My entire point thus far has been acknowledging that, yes, these things are
not representable, but then saying that they in fact should be. You have
been retorting the entire time saying they are not representable and that's
not a problem because of (what I perceive to be) circular logic. You have
still not responded to those points I've made by the way.

But to actually address this quote, yes, as I have said multiple times,
whether it is through records or final fields or something else entirely,
we are currently unable to represent cycles. But that is a byproduct of the
particular set of mechanics Java provided to create records and finality.
At no point along the line was it said that final SHOULD NOT be able to
represent circular references. And it is THAT that I am asking for evidence
for. And the reason why is because, if there is not an explicit,
intentional reason why they should not, then I am of the firm opinion that
they should be able to.

> > By all means, I am not picky. Can you show me what this
> > would look like though? I can understand how you would
> > achieve immutability doing this, but not the directness
> > constraint I am talking about above.
>
> You create your nodes and then you set their references
> (say, from a builder class), but you don’t expose a
> public API that allows mutating your nodes.

So, in short, you are saying that I should be creating a builder class, or
some privately available mechanism, to be able to insert in the necessary
references while still keeping my public API with no mutation options?

Here's a compilable example.

```java

public class ImmutableAndDirectCircularReferences
{

   public static class GraphBuilder
   {

      public static Node graph1()
      {

         Node start = new Node();
         Node t = new Node();
         Node u = new Node();
         Node v = new Node();
         Node end = new Node();

         start.setter(t, u, v);
         t.setter(u, v, end);
         u.setter(v, end, end);
         v.setter(end, end, end);
         end.setter(end, end, end); //or something like this

         return start;

      }

   }

   public static class Node
   {

      private Node t, u, v;

      private Node() {}

      private void setter(Node t, Node u, Node v)
      {

         this.t = t;
         this.u = u;
         this.v = v;

      }

      public Node t()
      {

         return this.t;

      }

      public Node u()
      {

         return this.u;

      }

      public Node v()
      {

         return this.v;

      }

      //equals, hash, tostring

   }

}
```

Fair. I'll concede that it checks all the boxes. More specifically, I'll
concede that it is not accurate for me to say that Java can't model
circular references while maintaining immutability and direct references.

But man, it does it in the worst way possible. We have more boilerplate
than multiple other solutions combined, and even then, we have to go deep
into indirection to EVENTUALLY construct a direct solution. It's the worst
of both worlds while still checking all the boxes. Knowing that this is the
actual solution to my problem makes me wish for another solution that much
more.

But regardless. Point conceded.

Thank you for your time and help!
David Alayachew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20230704/c672d995/attachment-0001.htm>


More information about the amber-dev mailing list