9

My project has a simple structure as following:

|- core.clj
|- dialogs.clj
|- dialogs/
   |- name_dialog.clj

name_dialog has a dependency from core, and core should require name_dialog.

So I have dependencies like this:

core.clj

(ns ddsl.core
  (:gen-class)
  (:require [clojure.xml :refer :all]
            [ddsl.dialogs :refer :all]))

dialogs.clj

(ns ddsl.dialogs
    (:require [ddsl.core :refer :all]))

(load "dialogs/name_dialog")

name_dialog.clj

(in-ns 'ddsl.dialogs)

When I try to run the program I'm getting the following error Cyclic load dependency: [ /ddsl/core ]->/ddsl/dialogs->[ /ddsl/core ]

Please let me know, how to restructure my project (i'm a novice in Clojure).

lich
  • 290
  • 1
  • 5
  • 10
  • Why does `core` require the other namespaces? – Lee Oct 07 '15 at 12:00
  • `core` produces xml from clojure "template", and has `-main` function that receives template name as argument, e.g. "name-dialog" and produces xml from it – lich Oct 07 '15 at 12:03
  • (defn state [s & xs] (hash-map :tag :state :attrs {:name s} :content (if xs (vec xs) nil))) – lich Oct 07 '15 at 12:06
  • 1
    It sounds like the functions in `core` which depend on those in other namespaces should be moved into those namespaces. `core` namespaces shouldn't need to depend on other modules. – Lee Oct 07 '15 at 12:19
  • thanks, I'll try to move them, it is quite logical. But in `core` I have function that receives name of dialog, e.g. `dialog_name`, and produces xml, so that should be loaded as a module anyway? (defn -main [dialog] (emit (eval (symbol dialog)))) – lich Oct 07 '15 at 13:13

1 Answers1

8

The classic answer, not specifically Clojure related, may be to review the modules and their responsibilities.

(-> below stands for "depends on")

Given:

core -> dialogs -> core

Extract the part of the core module which is required by dialogs into a separate shared module:

shared (depends on "nothing")
core -> dialogs -> shared
core -> shared (possibly)

As for me, cyclic dependencies are an indicator of something wrong with the design. Even when the technical problem is resolved (with load-time sequence or compilation, etc.), cyclic dependencies are typically a sign of tight coupling and still are worth fixing.

Tim
  • 12,318
  • 7
  • 50
  • 72