Live data from Hacker News

Cyclic dependencies are evil (2013)

fsharpforfunandprofit.com

21–30 of 125 posts

Re: Cyclic dependencies are evil (2013)

#21
post #8
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.…

I’m having a hard time understanding why you think F# is unable to handle the domain model presented.

It reads as an extremist take on Chesterton’s Fence: “the fence exists, therefore it is probably the only thing that could’ve worked.”

There is nothing in this contrived example that F# or Haskell (gasp, pure functional) wouldn’t handle with ease. It just would be modeled differently from traditional langs. I’d argue the alternative modeling forced by FP langs would be superior.

Re: Cyclic dependencies are evil (2013)

#22
This is one of the things that frustrates me about go. They started with this very good advice and then took it one step stupider: Disallowing circular imports.

Why is this bad? It makes it impossible in many situations to locate your public API at the top level. Let's say you have a Widget interface and APIs to do things with those Widgets. Eventually your library gets complex enough that you want to separate functionality into subdirs. Now you have a problem: You can't access the definition for Widget from the subdir because importing the top level would create a circular import!

The only way to get around this problem is to have no code at the top level, and put your public API in a subdir. Just be sure to do this when first starting your library or you'll have to break things.

Re: Cyclic dependencies are evil (2013)

#23
post #2

EDIT: In fact I appear to have paraphrased the next post in the series, https://fsharpforfunandprofit.com/posts/removing-cyclic-depe... . Probably go and read that instead. One pattern this nudges you towards is having a Domain.fs at the top of each project. Since everything in your project wants to talk in terms of the data types you've modelled, it makes sense to put them all in the same place at the top. Moreover,…

This is hexagonal architecture. I’ve yet to see anything quite as nice as it once I started using it.

The only downside to hexagonal architecture is that you start to see how mediocre most architectures are, and how frameworks often cap how good your architecture can be by virtue of their structure. Frameworks tend to resist being put on boxes, and hexagonal architecture tries to put all external dependencies in boxes.

Re: Cyclic dependencies are evil (2013)

#24

I still cringe when I think back to some C projects from long ago, where the dependency chains of headers and libraries where unfathomably byzantine. On a related note, lately I have been looking into some biochemistry topics and their relation to computer science. It seems that cyclic dependencies are possibly a requirement for life, which makes faithful simulations of biochemical processes an interesting challenge.

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. :)

Re: Cyclic dependencies are evil (2013)

#25
I've never tried F# so I'm not sure I'm exactly "on base" here, but I actually think this way. It's frustrating to me when dependencies happen automatically or when they can be used before they are declared.

It helps me understand what's included if I can see a nice list of all the dependencies. It helps me narrow down where the problem is if I only have to address dependencies I know have already loaded.

I learned to program in the 80's however, and it probably is a bit "old school".

Re: Cyclic dependencies are evil (2013)

#26
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.…

I don’t quite understand what you’re trying to convey with your example in regards to FP.

First of all, both data and functions are first class concepts in the functional paradigm and are not glued together as classes. So you’re not modeling your domain as „account service“ and „customer service“, but rather have data representation of these concepts and functions that query/reduce etc on those. In your example that would be a relational model, described as sets of tuples/maps, and relational functions do derive new data. There is no need for circular dependence, because your operations are generic over relational data.

I agree with the notion that the purely functional approach doesn’t dominate, for good reason. But more and more languages are incorporating FP concepts since about a decade or longer, at least the basic building blocks like closures, immutability and function composition have gained massive traction and eliminate the need for many of the complex patterns in traditional, class based OO.

Re: Cyclic dependencies are evil (2013)

#27

I still cringe when I think back to some C projects from long ago, where the dependency chains of headers and libraries where unfathomably byzantine. On a related note, lately I have been looking into some biochemistry topics and their relation to computer science. It seems that cyclic dependencies are possibly a requirement for life, which makes faithful simulations of biochemical processes an interesting challenge.

The C language and gcc are a cyclic dependency too.

Re: Cyclic dependencies are evil (2013)

#28
post #20
post #7

Earlier quoted context omitted.

In F#, you would naturally approach this by defining a Customer independent of the Account (e.g. just containing a name and address), and an Account independent of the Customer (e.g. just containing an ID), and then a Bank which is a mapping of Account to Set . What you see as a cyclic dependency, I see as a data type that you haven't reified.

This resembles sql a lot. Btw I'm surprised that few languages seem to have in their standard library a many-to-many container which supports efficient lookups in either direction.

Which languages support this at all? Are you talking about ORM?

Re: Cyclic dependencies are evil (2013)

#29

This is one of the things that frustrates me about go. They started with this very good advice and then took it one step stupider: Disallowing circular imports. Why is this bad? It makes it impossible in many situations to locate your public API at the top level. Let's say you have a Widget interface and APIs to do things with those Widgets. Eventually your library gets complex enough that you want to separate functi…

You can deal with that issue by defining things in a submodule, then importing and re-exporting them in the top-level (e.g. `type Foo = subdir.Foo`). That even lets you move things into the submodule without breaking callers. Other submodules can then import from the submodule rather than the top-level.

Re: Cyclic dependencies are evil (2013)

#30

This is one of the things that frustrates me about go. They started with this very good advice and then took it one step stupider: Disallowing circular imports. Why is this bad? It makes it impossible in many situations to locate your public API at the top level. Let's say you have a Widget interface and APIs to do things with those Widgets. Eventually your library gets complex enough that you want to separate functi…

This is how libraries are exported inside Google (use /public subdir for the public interface), and I guess with Go this got into the language. But I think Go made much worse things than this :)
Post reply on HN