Live data from Hacker News

Cyclic dependencies are evil (2013)

fsharpforfunandprofit.com

41–50 of 125 posts

Re: Cyclic dependencies are evil (2013)

#41
post #18
post #13

Earlier quoted context omitted.

This came up in an application I had modeling college football. A Team is a member of a Conference and a Conference is made up of Teams. But during realignment a few years ago when teams were switching all over the place it became apparent that Teams and Conferences were truly independent of each other and that their association itself was a first class object which also needed to capture the Season/Year. Not really…

This is almost exactly the motivational example that Codd used when originally describing relational algebra. He described 5 different data organization schemes for a single problem and designed relational algebra to work with all of them. This ability for the same program logic to work with many different data storage layouts should make changes like you describe less painful to implement. (see page 2) E. F. Codd. 1…

My dream, when I'll have a few years of free time, is to design a language were the relational table is the primary data structure abstraction.

Re: Cyclic dependencies are evil (2013)

#42
post #16
post #3

Language constraints aside, the real world is not something that can be cleanly modeled without the notion of circular dependencies between things. Not very many real, practical activities can be truly isolated from other closely-related activities and wrapped up in some leak-proof contract. Consider briefly the domain model of a bank. Customers rely on Accounts (I.e. have one or many). Accounts rely on Customers (i.…

In a relational database you would have a CustomerAccount table keeping track of which accounts that belongs to which customers. Customer would not know about Account, and vice versa. And what has reflection to do with this?

Reflection allows you to put the interfaces to Account and Customer into a shared module and the business logic implementations into their own mutually independent modules, thus removing the cyclic compile time dependency.

You "wire up" the implementations at runtime, using reflection.

Re: Cyclic dependencies are evil (2013)

#43

Earlier quoted context omitted.

You would forget everything about a customer if they closed their last account?

No, of course you would maintain a Set as well (possibly even a Map for efficiency).

... if you model it that way you're not using cyclic dependencies at all and this is in fact exactly how you would model it in a functional way.

Re: Cyclic dependencies are evil (2013)

#44
post #11
post #3

Language constraints aside, the real world is not something that can be cleanly modeled without the notion of circular dependencies between things. Not very many real, practical activities can be truly isolated from other closely-related activities and wrapped up in some leak-proof contract. Consider briefly the domain model of a bank. Customers rely on Accounts (I.e. have one or many). Accounts rely on Customers (i.…

Sometimes I read conversations about software engineering concepts by career developers and I get this sense that there is this entire hidden world of other engineers that I have somehow managed never to encounter. Every engineer I've ever met who has been doing it for more than a couple years universally decries circular dependencies. Every one of them has come to that opinion via hard won experience dealing with re…

> Every engineer I've ever met who has been doing it for more than a couple years universally decries circular dependencies. Every one of them has come to that opinion via hard won experience dealing with real world problems they encountered.

They may not realize they have them - at runtime, in the object graph, possibly indirectly. There's little difference in principle between cycles in "static" code vs. runtime state, but we often can't express them in the former, because our languages don't specify the concept of dependency at enough granularity (and some rely on a linear compilation pass).

Re: Cyclic dependencies are evil (2013)

#46

Earlier quoted context omitted.

I’m a compiler nerd at the moment. I have an inherent trust of things that bootstrap themselves, as if it means they are conceptually more pure. I’m not sure whether that is 100% well founded, but it sounds similar to some of these observations. :)

I think self-hosting is just a little over-rated for languages. It's good that Rust and C++ are self-hosting, you'd expect those to be languages you can write a compiler in. But Lua and JavaScript satisfy their own niche just fine without having popular runtimes written in themselves.

There are a few JS interpreters written in JS, don't know about Lua.

Re: Cyclic dependencies are evil (2013)

#47

Earlier quoted context omitted.

I’m a compiler nerd at the moment. I have an inherent trust of things that bootstrap themselves, as if it means they are conceptually more pure. I’m not sure whether that is 100% well founded, but it sounds similar to some of these observations. :)

I think self-hosting is just a little over-rated for languages. It's good that Rust and C++ are self-hosting, you'd expect those to be languages you can write a compiler in. But Lua and JavaScript satisfy their own niche just fine without having popular runtimes written in themselves.

Most languages don't aspire to be so conceptually-complete that they insist on being bootstrapped. Which is fine, I make my living with them.

Those that do, however, are immensely beautiful and there is more to be learned from them.

Re: Cyclic dependencies are evil (2013)

#48
The generic way to remove a cyclic dependency is by Dependency Inversion (not to be confused with Dependency Injection), so that a mutual dependency A B is transformed into the noncircular set of dependencies { A –> BIntf, BImpl –> BIntf, BImpl –> A }. That is, at least one node in the dependency cycle is split into interface and implementation, breaking the cycle.

Compilers for languages like C# and Java can deal with (seemingly) circular dependencies within a set of classes to compile, because when A uses B they only have to consider the interface (type signature) of B, not its implementation. (Cyclic dependencies between modules are still a problem, in particular for build systems.)

I'm not really familiar with F# (so someone please correct me if necessary), but in languages that use type interference to determine function signatures, one consequence is that the interface (type signature) of the function then depends on its implementation, so you can't as easily invert the dependency as when you have explicitly declared type signatures.

Re: Cyclic dependencies are evil (2013)

#49
post #42
post #16

Earlier quoted context omitted.

In a relational database you would have a CustomerAccount table keeping track of which accounts that belongs to which customers. Customer would not know about Account, and vice versa. And what has reflection to do with this?

Reflection allows you to put the interfaces to Account and Customer into a shared module and the business logic implementations into their own mutually independent modules, thus removing the cyclic compile time dependency. You "wire up" the implementations at runtime, using reflection.

I still don't get it. I put the interface into a shared module and the implementations in independent modules without reflection. Why exactly would we need reflection to do that?

Re: Cyclic dependencies are evil (2013)

#50
post #3

Language constraints aside, the real world is not something that can be cleanly modeled without the notion of circular dependencies between things. Not very many real, practical activities can be truly isolated from other closely-related activities and wrapped up in some leak-proof contract. Consider briefly the domain model of a bank. Customers rely on Accounts (I.e. have one or many). Accounts rely on Customers (i.…

But functional-only business applications already did take the world by storm! Relational DBs is the defacto way data is organized, and a Junction table is the way you model the data so that a functional query (generally in SQL) can be made against it.
Post reply on HN