How bad are circular references?

How bad are circular references?
I'm doing this on a personal project and I'm already feeling dirty to couple classes like that, but it makes it so easier to interact between them...

Attached: file.png (248x82, 6K)

Garbage collector can deal with them.
Problem might appear when your algos work with acyclic graphs.
Lang without pointers can surprise you on where it references and where it copies. Careful.

Garbage collector cant deal with them.

>How bad are circular references?
Most modern garbage collectors will do a BFS to figure out circular references, so they're not bad per se; it would be a lot worse if you did this in for example C++ with shared_pointers.

However, I would argue that modifying members of guiobj from a constructor of a different class is bad design and counter-intuitive. If you need a reference to Simulator from guiobj, you should rather make a global reference to the simulator that is accessible from guiobj.

If you need a circular references you probably have bad design.
I think the one thing that beginner programmers (which I assume you are) need to learn is to write simple and clean code.

import itertools

for i in itertools.count():
a = {}
b = {"a":a}
a["b"] = b

no leak

I'm pretty new to OOP, how should I make a GUI class and a internal logic class interact between themselves without circular dependency?

Singletons and static public instances.

Believe it or not, in 90% cases everything in your GUI will have exactly 1 instance. So you simply declare it all once, initialize it once and then you are done.

If you feel fancy, do the nesting with namespaces or static classes.

>inb4 not OOP
It is still OOP. Button, window, action it all still is object with its methods. And yes, you need this in many constructors. And no, it isnt problem for GC because you initialize everything only once and dont terminate it until end of program anyway.

what about some sort of third party, like a message bus?

MVC pattern. It's not quite a circular dependency because usually at the very least the view dependency isn't the SPECIFIC one you're using, but some kind of abstract interface / trait thing.

(cont'd)
Or you basically do a controller that depends on view/model and a view that depends on the model.

>If you need a circular references you probably have bad design.
wrong

Well, i'm kinda doing it like this already, GUI and Simulator classes have only one instance. But one have reference to the other and call methods between them, it somehow feel wrong to couple them together like this.

I'm not really familiar with MVC, it seems like it is better suited for larger codebases, for a small project seems like unnecessary bloat

Attached: file.png (423x372, 26K)

>If you need a circular references you probably have bad design.
class ListNode:
def insert(self, tail):
self.next = tail.next
tail.next = self
self.prev = tail

>self.play()
Ahahahahahahahagahahagagbajsgagahahaha

WTF are you doing son??? The whole main_loop doesnt make sense. This whole code should be in that object self points to. Simple as that.

Every method have automatic (self or this) pointer to the object its part of and you dont even need to explicity use it. Go put your code inside that object and run it within without the self disaster.

> it seems like it is better suited for larger codebases
You pretty much always do MVC, SAM, Async FRP or something else like that. It's absolutely not just for larger codebases.

Maybe the function names aren't very intuitive, i'll try to explain:

The function main_loop() starts initializing some shit, like running the GUI initial code, setting the world initial parameters, then it enter the loop.
The loop represents a frame in the simulator, each frame it calls GUI.hande_events() to handle some minimal input like closing/resizing the window, then calling the play() method in the AI class of each NPC, this method execute some actions(calling methods from the simulator class) for THAT FRAME. After that, it calls the GUI to draw shit on the screen and go to the next frame.

>circular references
The situations where they're used to good effect is so niche in practice that you should reconsider if you didn't make a mistake a while back in design.
>GC
Seems a bit cynical to assume user wouldn't know if his environment deals with circular references or not.

>The situations where they're used to good effect is so niche in practice
There's so many graph structures where you use circular references, for good reason

>doubly linked list
>niche

Well, from context, OP likely meant circular dependencies (ypu know, between classes) rather than circular references inside data structures.

These pretty much aren't required or good.

not that there's any difference, but if you have classes which have component sub-classes then those components having a link to their owner is also useful

class Tree:
def insert(self, element):
root.insert(Node(self, element))

class Node:
def __init__(self, tree, element):
self.tree = tree
self.element = element

I'd suggest to never do this.

The tree should know what nodes it has, the nodes don't need to know what tree they belong to. It shouldn't even matter if instances [of subtrees] are on ten trees at the same time. Or if the tree type changes.

You could also use a MVC pattern,since you already have a view and a model,the calls between the two would be handled by the controller

>the nodes don't need to know what tree they belong to
sometimes they do
depends what you're doing
you're making a baseless generalization

How often do you implement doubly linked lists on your own?
Also I don't think self referential doubly linked lists are good. But let's ignore that completely. It's not important.
Again, you either use a library or write it once.
Looking at op it's clear that he's not implementing some generic datastructure.

>Again, you either use a library or write it once.
It's like you think graphs are some generic data structure and not something you'll implement dozens of different times for different types of graph

Everyone is just talking about memory management. But in terms of class design, patterns like this are wrong. Class dependencies should always be going down, not up. Here's a quote from John Carmack
>If you’re willing to restrict the flexibility of your approach, you can almost always do something better

I thought we weren't writing horribly slow code. My mistake.
If you're constantly writing cyclic graphs manually like some ape you can ignore my advice.

Specifc code is faster than generic code. Whether a graph is cyclic or not has nothing to do with performance. You backed yourself into a corner by saying something dumb and trying to defend it

They never do, or basically so close to never that you should just not consider it before you really really have to.

The Tree knows what Nodes it has, but the Nodes never know what Tree(s) and other data structures they belong to [even which instances thereof]. Same for Integers in a List. And so on.

It's not a "baseless" generalization, no. It ties into all sorts of concerns about code re-usability and maintenance, RAM usage and so on, and it is valid between pretty much all imperative and FP programming languages.

It is a baseless generalization. I can think of plenty of instances where nodes should know about their parents

That's different and not equivalent to keeping a reference to the tree or graph or other collection they belong to.

what? what's the difference? its exactly the same

No, they're both Nodes, which is a necessary interface type to even get the functionality Nodes provide.

Not an extraneous other type like a Tree, array, ... that Nodes *could* be stored in.

>don't mind me, just moving the goalposts here

>How often do you implement doubly linked lists on your own?
They're so simple, that if I need one, it's usually simpler to just make one yourself. But then again, I mostly write C. In Python, I'd probably just deal with the footprint of using a list, and change to something else if it turned out to be a performance issue.

its fine just becareful when printing your object to the console/log

Are you seriously suggesting that you write hybrid datastructures manually for every single one of your handrolled graphs?
That's absurd.

>it's usually simpler to make one yourself
Over and over again. Fine.
What a twisted view of programming.