Re: [scala-language] The cake’s problem, dotty des ign and the approach to modularity.
martin odersky <[email protected]>
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAENVNkbntccnFuka2_NYTSLzbMfdV5VkmQOt4FvE5oH+2tHO3A@mail.gmail.com> |
On Tue, May 12, 2015 at 4:18 PM, Oliver Ruebenacker <[email protected]> wrote: > > Hello, > > My problem is still (yeah, still) to figure out what exactly is cake > pattern. There is no Wikipedia article on it. I could not find any > definition ("Cake pattern is ..."). I saw some examples, and I'm never sure > which parts of the discussion apply to dependency injection in general, > which parts are specific to cake, and which parts are specific to the > particular example. > > I know I asked this before. I could spend some time to dig out what the > answer was. But even better would be if those who put examples of cake on > the web could explain what makes it cake. > For me a cake is simply a mixin composition of traits that refer to members of other traits in the cake using their self types. Cheers - Martin > Best, Oliver > > On Tue, May 12, 2015 at 4: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. > > > > > -- > Oliver Ruebenacker > Solutions Architect at Altisource Labs > 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. -- 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.