Re: [scala-language] The cake’s problem, dotty des ign and the approach to modularity.
Eugene Burmako <[email protected]>
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAA2kKAvnK_y7zs+AvJu7RJ1D1s=Ot4HYUPVMddJfzCQuijKrzw@mail.gmail.com> |
Well, TreeApi is still part of the cake, because some parameters / return types of its methods are cake-dependent. On 12 May 2015 at 16:44, Oliver Ruebenacker <[email protected]> wrote: > > Hello, > > On Tue, May 12, 2015 at 10:31 AM, Haoyi Li <[email protected]> wrote: > >> > Dependencies are not declared, so are hard to track for big cakes. >> >> Only true if you don't use https://github.com/lihaoyi/acyclic! >> >> I'm sure you're sick of me pitching my library, but banning circular >> dependencies between files solves exactly this problem. You can not longer >> take a dependency on *Global* on every single *Slice*, because *Global* needs >> a dependency on every *Slice* in order to extend it. Thus you are forced >> by acyclic to keep each slice only depending on the smaller slices that you >> truly need, in a controlled fashion, or explicitly spelling out >> dependencies into abstract members. This solves your problem entirely. >> >> > - If cakes contain types, these can be accessed from outside the cake only >> with path dependent types. Cakes with mutual type dependencies between >> them (as they exist in nsc) are particularly hard to model. >> >> I feel that this is more a problem with path-dependent types rather than >> with cakes. This is true, but you can often avoid path dependent types in >> many scenarios by declaring all your "real" types/interfaces outside the >> cakes, and then the cakes become a lazy way of doing constructor injection >> (2 lines per file, rather than 1 per class) without any of the weirdness >> you find in tools.nsc.Global >> > > The path-dependent types in Global have path-independent traits (e.g. > Tree.TreeApi for Global.Tree). > > Best, Oliver > >> >> >> >> On Tue, May 12, 2015 at 1:22 AM, martin odersky <[email protected]> >> wrote: >> >>> I would not classify cake as an anti-pattern per se. Like any scheme >>> it is good for something but can be over-used. In fact, cake and >>> inheritance are quite similar in their benefits and problems. >>> Here are some points I can think of (I'd be interested in other >>> arguments people might have). >>> >>> The good: >>> >>> - Lets you compose multiple components quickly and with minimal fuss >>> - no parameters, no forwarders, no imports, just mix slices together. >>> >>> - Allows for mutual dependencies between slices. >>> >>> - Is therefore very general: Any set of global definitions with >>> arbitrary dependencies between them can be lifted into a cake. >>> >>> The bad: >>> >>> - Because they are so convenient, cakes tend to get big. >>> >>> - Dependencies are not declared, so are hard to track for big cakes. >>> >>> - If cakes contain types, these can be accessed from outside the cake >>> only with path dependent types. Cakes with mutual type dependencies >>> between them (as they exist in nsc) are particularly hard to model. >>> >>> In summary, cakes, like inheritance, are a useful tool to achieve >>> close coupling of components. It's very easy to link components in one >>> cake, and it is comparably much harder to access them from the >>> outside, in particular if types are involved. Cakes are misused in a >>> situation where weak coupling is preferable (and those situations are >>> in the majority). >>> >>> My advice would be: Cakes are fine to model mutual dependencies >>> between traits. However, care must be exercised to keep them >>> reasonably small. Furthermore, one should think twice whether >>> embedding types in cakes is the right way to model things. Nowadays, >>> I'd do that only if the type was essentially private to the >>> participants of the cake, or if it was clear that every instance needs >>> its different opaque type. Otherwise one might end up with awkward >>> situations, where e.g. the type of symbols in the nsc compiler depends >>> on the cake that's used. Sometimes you want that isolation, but at >>> other times you want to communicate a symbol between different >>> compiler instances (i.e., cakes), and then all you can do is copy an >>> arbitrary complex graph of symbol dependencies (see the "Importers" >>> framework in scala.reflect). So, putting types in traits can be a >>> premature restriction of their usage. >>> >>> The alternative to cakes is essentially functional abstraction. Have >>> components parameterized by others. Depending where you come from you >>> might call that "functors" or "constructor dependency injection". >>> Implicit parameters can help reduce the boilerplate in function >>> application. >>> >>> The dotty compiler uses fine-grained functional abstraction >>> everywhere, using implicit context arguments. That has turned out to >>> work quite well so far. Contexts are still cakes, in that they mix >>> together slices that are modelled around different concerns. But they >>> are much smaller and tend not to contain types, just methods and >>> fields. >>> >>> This writeup got much longer than I meant it to be when I started... >>> >>> - Martin >>> >>> >>> On Tue, May 12, 2015 at 9:13 AM, Alex Ivanov <[email protected]> >>> wrote: >>> > Good morning everyone. >>> > >>> > I’m very interested in the topic of modularity in Scala. It’s not a >>> secret >>> > that today The Cake Pattern is the most popular way to achieve >>> modularity in >>> > the project and, to some extent, a nice way to manage dependencies. On >>> the >>> > other hand this way of structuring the application becomes more and >>> more an >>> > anti-pattern, but unfortunately there’s not much explanation why. I >>> feel >>> > that it’s pretty hard to answer why it’s becomes an anti-pattern >>> without >>> > some big, active project (like Scala compiler), but in general i can >>> think >>> > of things like - complicated design, not that nice way to manage >>> > dependencies, problems with binary compatibility, slower compilation >>> due to >>> > inheritance overuse and complex cyclic dependencies, any other issues >>> that i >>> > didn’t think of? >>> > >>> > I remember that not so long ago Prof. Odersky mentioned he was also >>> > disappointed in the pattern and went a bit different way with a Dotty >>> > design. But, unfortunately, i couldn’t find details on this decision, >>> what >>> > were the problems and how they were solved with a new design (would be >>> good >>> > to read a paper like Scalable Component Abstractions). Anyway the >>> project is >>> > open-source, so it’s not hard to take a look and see that there are >>> some >>> > differences in the design, some components are packed within >>> modules/objects >>> > and it uses less cake-style coupling (beside the Context structure). >>> Could >>> > someone please unveil the secrets of the dotty architectural design? >>> > >>> > And, i guess, that last question that bothers me, what to use instead >>> of the >>> > Cake? In the talk “Scala - the simple parts” i liked the idea on the >>> Scala’s >>> > Modular Roots where we can see the mapping between Scala and SML >>> languages. >>> > Can’t reason much on this, i’ve just started looking at what we can >>> achieve >>> > with this SML-style modularity (maybe someone could explain this as >>> well =)? >>> > ), but it looks like a better approach to the modular design, >>> especially in >>> > combination with typeclasses. Of course we should “use the right tool >>> for >>> > problem”, but it feels like the Cake Pattern, is not good as the >>> essential >>> > approach to the application architecture and modularity. >>> > >>> > -- >>> > You received this message because you are subscribed to the Google >>> Groups >>> > "scala-language" group. >>> > To unsubscribe from this group and stop receiving emails from it, send >>> an >>> > email to [email protected]. >>> > For more options, visit https://groups.google.com/d/optout. >>> >>> >>> >>> -- >>> Martin Odersky >>> EPFL >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "scala-language" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "scala-language" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > Oliver Ruebenacker > Solutions Architect at Altisource Labs <http://www.altisourcelabs.com/> > Be always grateful, but never satisfied. > > -- > You received this message because you are subscribed to the Google Groups > "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.