FAQ
hi,
    I'm wondering why import cycle not allowed in Go. It seems to me forbid
import cycle make package init() function call a bit easier to reason but
it should not be a too hard issue to solve. A common use case of cyclic
import for me is to declare a common interface in top level package, then
make a few implementations in different sub-package, finally make some
convenient function like a factory to forward specific implementation in
top level package. However, forbid cyclic dependence make this process very
difficult and fragile, especially when there is multiple different
interface involved. Why this design choice is taken?

Best Regards,
Jiacheng Guo

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Robert Johnstone at Apr 16, 2014 at 4:59 pm
    Hello,

    Put your common interface into one package, you implementation in their
    respective packages, and then use a new package for the factory. No cyclic
    dependencies.

    Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example.


    On Wednesday, 16 April 2014 12:40:57 UTC-4, Jiacheng Guo wrote:

    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me forbid
    import cycle make package init() function call a bit easier to reason but
    it should not be a too hard issue to solve. A common use case of cyclic
    import for me is to declare a common interface in top level package, then
    make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jiacheng Guo at Apr 17, 2014 at 6:32 am
    I'm using this pattern. However, I feel create a separate can be very
    fragile and hard to maintain when there is multiple related interface to
    implement, as they may have to gain an instance from factory, and fragment
    the package too much.

    "Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example."

    This seems to be an interesting approach. I will check it out

    Thanks,
    Jiacheng Guo
    On Thursday, April 17, 2014 12:59:34 AM UTC+8, Robert Johnstone wrote:

    Hello,

    Put your common interface into one package, you implementation in their
    respective packages, and then use a new package for the factory. No cyclic
    dependencies.

    Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example.


    On Wednesday, 16 April 2014 12:40:57 UTC-4, Jiacheng Guo wrote:

    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me
    forbid import cycle make package init() function call a bit easier to
    reason but it should not be a too hard issue to solve. A common use case of
    cyclic import for me is to declare a common interface in top level package,
    then make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Brendan Tracey at Apr 17, 2014 at 6:57 am
    One of the big reasons is compile times. If two packages import each other,
    when one changes they must both be recompiled. Same goes for all cycles. In
    the worst case, your whole program must be recompiled with every change.

    In my mind, the lack of cyclical dependencies is one of go's best decisions
    for supporting programming at scale. You are a good programmer, so you want
    to keep your packages small for legibility (and godoc helps highlight the
    complexity). Go forbids cyclical dependencies, and so your program is a DAG
    consisting of a bunch of small chunks. This combination goes a long way in
    preventing spaghetti code even as programs get large.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Egon at Apr 17, 2014 at 7:09 am

    On Thursday, April 17, 2014 9:32:13 AM UTC+3, Jiacheng Guo wrote:
    I'm using this pattern. However, I feel create a separate can be very
    fragile and hard to maintain when there is multiple related interface to
    implement, as they may have to gain an instance from factory, and fragment
    the package too much.
    Remember that you can declare the interfaces in multiple places without any
    problem.

    "Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example."
    Instead of "init" approach you can always make a separate package that
    pulls the things together. i.e. manually.

    e.g. https://github.com/egonelbre/mud/tree/master/telnet

    How to resolve the cyclic dependency depends on what you are implementing.

    + egon

    This seems to be an interesting approach. I will check it out
    Thanks,
    Jiacheng Guo
    On Thursday, April 17, 2014 12:59:34 AM UTC+8, Robert Johnstone wrote:

    Hello,

    Put your common interface into one package, you implementation in their
    respective packages, and then use a new package for the factory. No cyclic
    dependencies.

    Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example.


    On Wednesday, 16 April 2014 12:40:57 UTC-4, Jiacheng Guo wrote:

    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me
    forbid import cycle make package init() function call a bit easier to
    reason but it should not be a too hard issue to solve. A common use case of
    cyclic import for me is to declare a common interface in top level package,
    then make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jiacheng Guo at Apr 17, 2014 at 7:20 am
    "Remember that you can declare the interfaces in multiple places without
    any problem"
    This is indeed a very good insight for me. I got too used to old oo
    approach, that declare an interface once then everyone try to implement it.
    Declare an interface multiple time can solve some case for me.
    On Thursday, April 17, 2014 3:09:06 PM UTC+8, egon wrote:


    On Thursday, April 17, 2014 9:32:13 AM UTC+3, Jiacheng Guo wrote:

    I'm using this pattern. However, I feel create a separate can be very
    fragile and hard to maintain when there is multiple related interface to
    implement, as they may have to gain an instance from factory, and fragment
    the package too much.
    Remember that you can declare the interfaces in multiple places without
    any problem.

    "Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example."
    Instead of "init" approach you can always make a separate package that
    pulls the things together. i.e. manually.

    e.g. https://github.com/egonelbre/mud/tree/master/telnet

    How to resolve the cyclic dependency depends on what you are implementing.

    + egon

    This seems to be an interesting approach. I will check it out
    Thanks,
    Jiacheng Guo
    On Thursday, April 17, 2014 12:59:34 AM UTC+8, Robert Johnstone wrote:

    Hello,

    Put your common interface into one package, you implementation in their
    respective packages, and then use a new package for the factory. No cyclic
    dependencies.

    Alternatively, have your sub-packages register with init. Look at the
    database/sql or image packages for example.


    On Wednesday, 16 April 2014 12:40:57 UTC-4, Jiacheng Guo wrote:

    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me
    forbid import cycle make package init() function call a bit easier to
    reason but it should not be a too hard issue to solve. A common use case of
    cyclic import for me is to declare a common interface in top level package,
    then make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ingo Oeser at Apr 17, 2014 at 4:07 pm

    On Thursday, April 17, 2014 9:20:25 AM UTC+2, Jiacheng Guo wrote:
    "Remember that you can declare the interfaces in multiple places without
    any problem"
    This is indeed a very good insight for me. I got too used to old oo
    approach, that declare an interface once then everyone try to implement it.
    Declare an interface multiple time can solve some case for me.

    Actually it is more useful to declare the minimal interface very close to
    the consumer expecting the interface.
    That way you can keep both updated very easily. It is also completely
    opposite to the traditional approach of
    declaring an interface close to a random bunch of entities implementing
    that interface.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Egon at Apr 16, 2014 at 6:54 pm

    On Wednesday, April 16, 2014 7:40:57 PM UTC+3, Jiacheng Guo wrote:
    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me forbid
    import cycle make package init() function call a bit easier to reason but
    it should not be a too hard issue to solve. A common use case of cyclic
    import for me is to declare a common interface in top level package, then
    make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?
    Cyclic dependencies introduce problematic "init" order. Avoiding cyclic
    dependencies enforces simpler packages that have clearer dependencies and
    it's easier to reason about effects of changes in packages. Cyclic
    dependencies allows much more easily to reason about what needs to be
    compiled when something changes.

    http://stackoverflow.com/questions/1897537/why-are-circular-references-considered-harmful

    Of course there have been discussions on the forums as well.

    + egon

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jiacheng Guo at Apr 16, 2014 at 8:00 pm
    Hi,
        I'm wondering why import cycle not allowed in Go. It seems to me forbid
    import cycle make package init() function call a bit easier to reason but
    it should not be a too hard issue to solve. A common use case of cyclic
    import for me is to declare a common interface in top level package, then
    make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?


    Best Regards,
    Jiacheng Guo

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • John Asmuth at Apr 17, 2014 at 1:37 am
    The 'factory' function you describe does not have to be in the original
    package.

    The very pattern you describe is something I have with go.wde.

    github.com/skelterjohn/go.wde is the high-level interface.
    github.com/skelterjohn/go.wde/windows is the windows-specific
    implementation.
    github.com/skelterjohn/go.wde/xgb is the X windows-specific implementation.
    github.com/skelterjohn/go.wde/init is a convenience package that will use
    the right backend for your current system.

    In go, a package is a compilation unit. If two files must always be
    compiled together, they must be in the same package.
    On Wednesday, April 16, 2014 12:40:57 PM UTC-4, Jiacheng Guo wrote:

    hi,
    I'm wondering why import cycle not allowed in Go. It seems to me forbid
    import cycle make package init() function call a bit easier to reason but
    it should not be a too hard issue to solve. A common use case of cyclic
    import for me is to declare a common interface in top level package, then
    make a few implementations in different sub-package, finally make some
    convenient function like a factory to forward specific implementation in
    top level package. However, forbid cyclic dependence make this process very
    difficult and fragile, especially when there is multiple different
    interface involved. Why this design choice is taken?

    Best Regards,
    Jiacheng Guo
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jan Mercl at Apr 17, 2014 at 7:42 am

    On Wed, Apr 16, 2014 at 6:40 PM, Jiacheng Guo wrote:
    Why this design choice is taken?
    It's not really a choice, there's only one option when initialization
    of something depends on something else being already initialized,
    which is what the specs guarantee[0]. Without such guarantee, everyone
    would have to handle correct initialization code explicitly - in code.

    IOW, in the general case there's a partial ordering of initialized
    things. Correct initialization order is the depth first traversal of
    the dependency tree(s). Allowing cycles would mean there's no correct
    initialization order available. Except for some rather trivial (no
    dependencies present) cases - the dependency "tree(s)" form a list.

    (The problem is also related to determining sizes of types, but that's
    not the topic here.)

       [0]: http://golang.org/ref/spec#Program_execution

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris dollin at Apr 17, 2014 at 11:37 am

    On 16 April 2014 17:40, Jiacheng Guo wrote:


    A common use case of cyclic import for me is to declare a common interface
    in top level package, then make a few implementations in different
    sub-package,
    Aside: Go-the-language doesn't have any notion of "sub"-package.
    They're just packages.

    Chris

    --
    Chris "allusive" Dollin

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 16, '14 at 4:41p
activeApr 17, '14 at 4:07p
posts12
users8
websitegolang.org

People

Translate

site design / logo © 2018 Grokbase