Welcome to the Dependecy Inyection HELL

449 переглядів
Перейти до першого непрочитаного повідомлення

Daniel Sanchez

не прочитано,
22 квіт. 2016 р., 13:38:3222.04.16
Кому: play-framework
Hello everyone.

I'm Scala programmer (in fact, I know a bit more about scala that java) and user of Play since 2.1 version 3 years ago. I did not cared about porting my code to use DI before, but with Play 2.5 and the "Deprecated Warning Wall" (DWW) due Play.current, Cache, and WS libraries, I started to make it.

I understand the reasons why Play Team want to use DI "out of the box" in the project, and yes, It is a good thing, but this becomes in a pain in projects like mine where rewrite for use DI does not look trivial.

My issue with it is: using DI seems very complicate to do and explain to your friends if they does not come from Java Enterprice world. I'm no a full Java programmer, never in my life use Spring or anything, my background was in languages like python, ruby, etc, and Scala (only playing with language befor PlayFramework). When I listended about Play years ago that was like "oh, cool, a powerful rails in Scala!", but now it feels too complicate as old Java World.


I have been fighting one week tryng to port my code, but it is hard and complicate.
I really want to know the community opinion about it.

Thanks for read!

Byron Weber Becker

не прочитано,
22 квіт. 2016 р., 14:17:3022.04.16
Кому: play-framework
Like you, porting seemed like a never-ending hell.  Like you, I had no prior experience with DI.  

Now that I'm through it, I'm definitely in a much better place in that my testing is much more robust.

Was it worth it?  I think so.

Would I do it differently next time?  Definitely.  I did it as part of the migration from Play 2.3 to 2.4.  I switched to Play 2.4, compiled, saw a huge mountain of compile errors, and dug in.  Silly me.  If I were to do it over I'd start with doing much of the DI in 2.3 so I could focus on just one area, getting it to compile, and then moving on.  

Will Sargent

не прочитано,
22 квіт. 2016 р., 19:10:1522.04.16
Кому: play-fr...@googlegroups.com
Thanks Byron and Daniel,

We're working on improving the documentation and expanding the migration, and it really helps to hear more about this.  Would you be able and willing to write some more about this, detailing the problems you ran into and what worked and what didn't?

Will.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/1b04ceb4-1458-46f0-88e0-dd5a07667d28%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Andrew Gaydenko

не прочитано,
22 квіт. 2016 р., 20:55:2622.04.16
Кому: play-framework
Will, hi!

Will you find a minute to share upcoming DI-related plans? The things is, I have moved code to 2.5 (and documentations was sufficient at my case), but still in 100% cases use objects for controllers (and even lazy vals for parameterless actions) as well as own router with actions as just functions' names (that is instant-less). And I'd want to avoid to rewrite these millions actions. Will my future shine? :)

Byron Weber Becker

не прочитано,
22 квіт. 2016 р., 21:44:4422.04.16
Кому: play-framework
Will -- I'm willing to consider this.  I'll contact you out-of-group to discuss further.

Byron

Greg Methvin

не прочитано,
22 квіт. 2016 р., 22:01:3522.04.16
Кому: play-framework
On Fri, Apr 22, 2016 at 10:38 AM, Daniel Sanchez <anonim...@gmail.com> wrote:
My issue with it is: using DI seems very complicate to do and explain to your friends if they does not come from Java Enterprice world. I'm no a full Java programmer, never in my life use Spring or anything, my background was in languages like python, ruby, etc, and Scala (only playing with language befor PlayFramework). When I listended about Play years ago that was like "oh, cool, a powerful rails in Scala!", but now it feels too complicate as old Java World.

What do you find complicated about dependency injection? There are certainly ways to use DI frameworks in a more confusing/complicated way, but if you're sticking with simple constructor injection I think it makes things easier, at least as compared to global state. It's much easier to break apart your dependencies and properly unit test them.

I don't think it's fair to suggest that DI is an "enterprise Java" thing. Actually, I'd say DI provides a lot more value when it comes to large-scale consumer applications than enterprise apps, just because the scale of those apps means testability and modularity are even more important. Most of the developers I've worked with in the past were not from the enterprise Java world, and they easily were able to understand DI and why it is useful. The issue is that a lot of developers just don't have the prior experience.

--
Greg Methvin
Senior Software Engineer

Naftoli Gugenheim

не прочитано,
25 квіт. 2016 р., 12:59:5225.04.16
Кому: play-framework


On Fri, Apr 22, 2016, 10:01 PM Greg Methvin <gr...@lightbend.com> wrote:
On Fri, Apr 22, 2016 at 10:38 AM, Daniel Sanchez <anonim...@gmail.com> wrote:
My issue with it is: using DI seems very complicate to do and explain to your friends if they does not come from Java Enterprice world. I'm no a full Java programmer, never in my life use Spring or anything, my background was in languages like python, ruby, etc, and Scala (only playing with language befor PlayFramework). When I listended about Play years ago that was like "oh, cool, a powerful rails in Scala!", but now it feels too complicate as old Java World.

What do you find complicated about dependency injection?

Dealing with external frameworks that magically do stuff to your code based on random annotations, yes is complicated.

Scala has much better solutions. Labeling those solutions " compile-time DI" only makes them harder to appreciate to people not coming from Java-think land.

I've been around the Scala community for a very long time. It's always been the consensus (at least judging by mailing list discussions) that both annotations as well as DI frameworks are signs of lack of expressivity in a language, and were unnecessary and unidiomatic in Scala.

Of course, no one in the Scala community is a fan of global mutable state. But the solution doesn't need to involve magic. Scala is capable -- in fact was designed specifically to be capable -- of expressing dependencies at various levels of granularity, such as explicit and implicit parameters, and self types. And there's no reason to label that "dependency injection." No one is taking a hypodermic needle and injecting something in from the side (which is what annotation-processing reflection-using or bytecode-rewriting do, in a sense). There's no need for a special term for it, because it's what all modular or functional code does at all levels: use parameters or scope, rather than using external state.

To be clear, I think the so-called "compile-time DI" API is designed excellently. But the fact that it's called that (rather than "using parameters" or just "no DI" -- no need to contrast with outdated API), and is a second-class citizen (no activator template!!!) is extremely annoying, and probably turns away (or off) a lot of the more seasoned Scala developers.

Personally I'd rather the guice stuff be recommended only for people already used to it. The default play-scala activator template should use "compile-time DI" and the docs should refer to it by default.

Of course, I don't know if lightbend will agree... maybe they'd be too worried about the effect on all their customers coming from Java...


There are certainly ways to use DI frameworks in a more confusing/complicated way, but if you're sticking with simple constructor injection I think it makes things easier, at least as compared to global state. It's much easier to break apart your dependencies and properly unit test them.

I don't think it's fair to suggest that DI is an "enterprise Java" thing. Actually, I'd say DI provides a lot more value when it comes to large-scale consumer applications than enterprise apps, just because the scale of those apps means testability and modularity are even more important. Most of the developers I've worked with in the past were not from the enterprise Java world, and they easily were able to understand DI and why it is useful. The issue is that a lot of developers just don't have the prior experience.

--
Greg Methvin
Senior Software Engineer

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Will Sargent

не прочитано,
25 квіт. 2016 р., 14:41:0325.04.16
Кому: play-fr...@googlegroups.com
To be clear, I think the so-called "compile-time DI" API is designed excellently. But the fact that it's called that (rather than "using parameters" or just "no DI" -- no need to contrast with outdated API), and is a second-class citizen (no activator template!!!) is extremely annoying, and probably turns away (or off) a lot of the more seasoned Scala developers.

I'm going to clean up the tutorials section with updated examples.  There are (core team maintained) two compile time DI templates:


I think contributors should be able to review and commit PRs to them as well, if I understand Github's new rights pages correctly...

Will.

Naftoli Gugenheim

не прочитано,
25 квіт. 2016 р., 15:20:3925.04.16
Кому: play-fr...@googlegroups.com


On Mon, Apr 25, 2016, 2:40 PM Will Sargent <will.s...@lightbend.com> wrote:
To be clear, I think the so-called "compile-time DI" API is designed excellently. But the fact that it's called that (rather than "using parameters" or just "no DI" -- no need to contrast with outdated API), and is a second-class citizen (no activator template!!!) is extremely annoying, and probably turns away (or off) a lot of the more seasoned Scala developers.

I'm going to clean up the tutorials section with updated examples.  There are (core team maintained) two compile time DI templates:


Good to know, I should have looked again

I think contributors should be able to review and commit PRs to them as well, if I understand Github's new rights pages correctly...

Will.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Andrew Gaydenko

не прочитано,
25 квіт. 2016 р., 15:28:1925.04.16
Кому: play-framework

nafg,

I feel the same way.

Also I don't think core Scala teams have rejected that beauty and elegance Scala bring to all of us. Typesafe rebranding, DI in Play, Java-first in Lagom - all these signs are signs of some internal reformatting, and the most obvious thought comes to me the reformatting is forced by lack of background support in "clean Scala world". Probably we must accept the reality :)


Greg Methvin

не прочитано,
25 квіт. 2016 р., 20:37:0425.04.16
Кому: play-framework
Ideally Play should not have much of an opinion on which kind of dependency injection you use, and that's something we're working more on now and for the 2.6 release (in which Guice support will likely be split out from core). As Will said, we want to keep improving our documentation and helpers for people who want to use a pure Scala "compile-time DI" approach. The main issue is documentation (and sample projects), though. We need to make sure our documentation makes sense for both kinds of dependency injection, since a lot of what we have so far assumes Guice.

The runtime DI approach affords a lot of flexibility you can't get with compile-time DI, and lets us automatically discover modules without forcing the user to provide explicit bindings. So we felt it was consistent with Play's philosophy to provide really good integration with at least one runtime DI framework, and make sure everything "just works" from the start. But I can see how this also might be too much magic for newcomers. Perhaps if the user had to explicitly configure it when you set up your project, and the behavior was obviously documented, that would make it more obvious what is going on.

Andrew, I'm not sure what you mean by "internal reformatting". The choice to release the Lagom API first in Java and the Lightbend rename didn't really have anything to do with Scala. The rename was more aimed at Typesafe's customers, where many of the decision-makers don't assign special significance to the name "Typesafe", and releasing the Lagom Java API first was done because that's where we thought the need was greatest. I'm not speaking for Lightbend in any official capacity here though.

Adding DI support in Play was done because a lot of people were asking for it and complaining about it, and we thought it was necessary to get rid of global state. It was really hard to build and properly test a large (or even small) app in Play using dependency injection. I tried it back in the Play 2.1 days, and there were a lot of hacks we had to do to get around Play's global state. That said, we've always wanted to make sure the DI support is not bound to any one framework or library.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Andrew Gaydenko

не прочитано,
26 квіт. 2016 р., 04:49:5626.04.16
Кому: play-framework
Greg,

Do you mean Scala language doesn't allow to avoid Play's global state without using this or that alien framework?

Igmar Palsenberg

не прочитано,
26 квіт. 2016 р., 05:34:2726.04.16
Кому: play-framework
 
Also I don't think core Scala teams have rejected that beauty and elegance Scala bring to all of us. Typesafe rebranding, DI in Play, Java-first in Lagom - all these signs are signs of some internal reformatting, and the most obvious thought comes to me the reformatting is forced by lack of background support in "clean Scala world". Probably we must accept the reality :)

We're not all Scala programmers. A big part of the Play users do Java, and not Scala, for a lot of reasons. Play should support both camps, no just Java, not just Scala. And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.



Igmar 

Naftoli Gugenheim

не прочитано,
26 квіт. 2016 р., 12:14:0626.04.16
Кому: play-framework

On Mon, Apr 25, 2016, 8:36 PM Greg Methvin <gr...@lightbend.com> wrote:
Ideally Play should not have much of an opinion on which kind of dependency injection you use, and that's something we're working more on now and for the 2.6 release (in which Guice support will likely be split out from core). As Will said, we want to keep improving our documentation and helpers for people who want to use a pure Scala "compile-time DI" approach. The main issue is documentation (and sample projects), though.

Agreed. Honestly, myself I'm doing okay, it's just that I'm thinking ahead in terms of our hopes to expand the team, and I want more junior Scala developers not to have unnecessary friction following my recommendations.

We need to make sure our documentation makes sense for both kinds of dependency injection, since a lot of what we have so far assumes Guice.

The runtime DI approach affords a lot of flexibility you can't get with compile-time DI,

I'm not sure what specifically you're referring to, but really that's true in general of runtime-based approaches vs. compile-time-based approaches. JavaScript is much more flexible than Scala. And that's very closely related to the reasons I prefer Scala over JavaScript, as well as the reasons many people might prefer JavaScript over Scala.
My point is not "if you're doing Scala, then everything MUST be statically known or referentiality transparent." However those should certainly be the default approach, since they're more idiomatic in Scala-land.

and lets us automatically discover modules without forcing the user to provide explicit bindings.

How to solve that without "magic" is a discussion well worth having (but not in this thread).

So we felt it was consistent with Play's philosophy to provide really good integration with at least one runtime DI framework, and make sure everything "just works" from the start. But I can see how this also might be too much magic for newcomers.

I wouldn't exactly call myself a newcomer, :) and any magic is too much for my tastes. :)


Perhaps if the user had to explicitly configure it when you set up your project, and the behavior was obviously documented, that would make it more obvious what is going on.

Andrew, I'm not sure what you mean by "internal reformatting".

I think he means shifted priorities.

The choice to release the Lagom API first in Java and the Lightbend rename didn't really have anything to do with Scala. The rename was more aimed at Typesafe's customers, where many of the decision-makers don't assign special significance to the name "Typesafe", and releasing the Lagom Java API first was done because that's where we thought the need was greatest. I'm not speaking for Lightbend in any official capacity here though.

This has been rehashed enough times, but my takeaways are: (1) I think lightbend's argument is reasonable, yet (2) it reveals (or declares) that it's not what we thought Typesafe was: the Scala company -- the company whose purpose was to promote Scala, but rather just some company that scalac's team happens to be embedded inside of; so ultimately (3) it left the existing Scala community with a bad taste.


Adding DI support in Play was done because a lot of people were asking for it and complaining about it,

I remember when that happened in the Lift community... :)

and we thought it was necessary to get rid of global state.

Oh, absolutely! There's zero question about that! Global (or shared) mutable state is considered Public Enemy Number One in the Scala community. ;) It's the biggest impediment to modularity.

It was really hard to build and properly test a large (or even small) app in Play using dependency injection.

Presumably those last three words are unnecessary? Global state is impossible to test, period!

I tried it back in the Play 2.1 days, and there were a lot of hacks we had to do to get around Play's global state. That said, we've always wanted to make sure the DI support is not bound to any one framework or library.

Again, part of the point here is that (at least to anyone with some exposure to FP) global state and DI are not the only two options.
Runar has argued that in a sense, FP is synonymous with modularity. Basically, global mutable state means that module A can affect module B without your consent, because there's nothing stopping either one from writing to it or depending on it. FP means no side effects, so no reading except from parameters and no writing except producing a return value. Thus, by definition, infinite modularity. Nothing can impact anything else except how you explicitly wire them up.
Another way of looking at it: pure functions are explicit about all of their dependencies, and function composition is wiring it up to an implementation.
The way I see it, in the phrase dependency injection, the word injection means "magic," i.e., the wiring is generated by some framework. So in my opinion, "compile-time DI" is a fine name for things like macwire etc. But the default -- using a custom loader and writing code to instantiate the router etc., should not be called DI. It's ordinary Scala programming.


On Mon, Apr 25, 2016 at 12:28 PM, Andrew Gaydenko <andrew....@gmail.com> wrote:

nafg,

I feel the same way.

Also I don't think core Scala teams have rejected that beauty and elegance Scala bring to all of us. Typesafe rebranding, DI in Play, Java-first in Lagom - all these signs are signs of some internal reformatting, and the most obvious thought comes to me the reformatting is forced by lack of background support in "clean Scala world". Probably we must accept the reality :)


--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/d38e0534-a436-4680-a37a-5a46bcde68c2%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Senior Software Engineer

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Naftoli Gugenheim

не прочитано,
26 квіт. 2016 р., 12:16:5926.04.16
Кому: play-framework


On Tue, Apr 26, 2016, 5:34 AM Igmar Palsenberg <ig...@palsenberg.com> wrote:
 
Also I don't think core Scala teams have rejected that beauty and elegance Scala bring to all of us. Typesafe rebranding, DI in Play, Java-first in Lagom - all these signs are signs of some internal reformatting, and the most obvious thought comes to me the reformatting is forced by lack of background support in "clean Scala world". Probably we must accept the reality :)

We're not all Scala programmers. A big part of the Play users do Java, and not Scala, for a lot of reasons. Play should support both camps, no just Java, not just Scala.

I have no problem with that. I think the Java documentation should prefer guice, or whatever Java devs prefer. However in Scala-land, it's not idiomatic.

And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.


And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.

Absolutely, no one is suggesting that.




Igmar 

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Igmar Palsenberg

не прочитано,
26 квіт. 2016 р., 17:31:1826.04.16
Кому: play-framework
 
Also I don't think core Scala teams have rejected that beauty and elegance Scala bring to all of us. Typesafe rebranding, DI in Play, Java-first in Lagom - all these signs are signs of some internal reformatting, and the most obvious thought comes to me the reformatting is forced by lack of background support in "clean Scala world". Probably we must accept the reality :)

We're not all Scala programmers. A big part of the Play users do Java, and not Scala, for a lot of reasons. Play should support both camps, no just Java, not just Scala.

I have no problem with that. I think the Java documentation should prefer guice, or whatever Java devs prefer. However in Scala-land, it's not idiomatic.

I prefer stuff that works, and is well documented. Whatever suits that. I find Guice to be actually pretty simple : It either works, or not. If not, it usually dies with an exception. I've learnt to read those pretty fast.


And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra. 


And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.

Absolutely, no one is suggesting that.

<rant>
To be honest, I rather have Play ditch SBT. If you're talking about magic, SBT gives it all to you. Fighting the magic right now :(
</rant>


Igmar

Greg Methvin

не прочитано,
26 квіт. 2016 р., 21:51:5626.04.16
Кому: play-framework
Andrew,

The Scala language does allow you to avoid global state with proper design. That's exactly what "compile-time DI" is. Maybe it should just be called "manual dependency wiring" instead. It's just slightly more verbose and more work on the part of the developer.

Play's philosophy has generally been that things should work with little or no configuration, and using Guice by default provided an easy way to do that. Guice was the most popular DI strategy we saw our users using (both in Scala and Java), and it works well for Java, Scala, and hybrid projects. Now, it's more clear that Guice introduces a lot of complexity that some people don't like, so if we had to do it again we would probably put more work into making it clear that several options exist for wiring together your dependencies.

Greg

On Tue, Apr 26, 2016 at 1:49 AM, Andrew Gaydenko <andrew....@gmail.com> wrote:
Greg,

Do you mean Scala language doesn't allow to avoid Play's global state without using this or that alien framework?

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Greg Methvin

не прочитано,
26 квіт. 2016 р., 23:24:2026.04.16
Кому: play-framework
On Tue, Apr 26, 2016 at 2:31 PM, Igmar Palsenberg <ig...@palsenberg.com> wrote:
And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra.

Exceptions are fine when they actually represent an exceptional (error) case, especially if they prevent your possibly broken or misconfigured application from starting.

While I agree in a lot of cases the manual Scala code is easier to understand than Guice, there are a few cases where Guice will provide a more useful error than manual wiring. Think about what happens when you accidentally introduce a circular dependency. The equivalent Guice code will error when creating the injector, which means your application won't start at all (usually a good thing). Using manual wiring your app still starts and throws an error later.

Another situation where I like Guice more is when binding eager singletons. lazy vals are the preferred way to declare dependencies using the thin cake pattern, but you have to explicitly call them to make sure they're initialized on startup; Guice handles this for you automatically.

I'm not arguing for either approach here. I'm just saying each approach has its own pros and cons that you should be aware of. I really like the simplicity and elegance of the pure Scala approach, and that's what I've been using recently, but I also understand what's possible with Guice and runtime DI in general.

Ryan Tanner

не прочитано,
27 квіт. 2016 р., 01:07:2527.04.16
Кому: play-framework
I used to be in favor of the cake pattern (or variants of it) but after seeing a large project that used Guice, only through the javax.inject.* packages, I'm fully onboard with JSR-330.

Yes, there's an occasional exception, but I think I prefer that over the discipline required to keep the cake pattern sane with large teams.  

Naftoli Gugenheim

не прочитано,
28 квіт. 2016 р., 03:02:0028.04.16
Кому: play-framework


On Tue, Apr 26, 2016, 5:31 PM Igmar Palsenberg <ig...@palsenberg.com> wrote:
And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra. 

I was afraid that misunderstanding would happen... :)

What I meant is, I'd prefer not to make exceptions to the rule of "no magic." I didn't mean avoiding throwing runtime exceptions. Although of course that's related, because often magic as opposed to language feature means runtime error rather than compile-time error.



And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.

Absolutely, no one is suggesting that.

<rant>
To be honest, I rather have Play ditch SBT. If you're talking about magic, SBT gives it all to you. Fighting the magic right now :(
</rant>

:)
A few comments about SBT:
1. I don't think anything in Play depends on SBT other than the SBT plugin. Granted, most of the user experience of developing in Play is provided by the plugin, and working without it is not really documented or practical. The point is that it's possible for someone to develop the equivalent of the SBT plugin (at last the parts that don't require a feature unique to SBT) standalone or for some other build tool. In fact I believe that a groovy or maven integration has been done by someone.
2. While there are decisions SBT made that many would disagree with, and that's frustrating, I think SBT is far better than any other build tool.
3. If you're expecting SBT to just be a Scala version of some other build tool, you will be very disappointed. SBT has to be understood for what it is. It's an original approach to solving the problem. James Roper has a good set of blog posts explaining what SBT really is (don't have the link at the moment).
4. Keep an eye on Christopher Vogt's CBT.




Igmar

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Naftoli Gugenheim

не прочитано,
28 квіт. 2016 р., 03:05:2528.04.16
Кому: play-framework
I don't know what the ideal is, or if there's some way to get the best of both worlds. But I remember, when I was part of the Lift community, being very bothered by the way they became their own island, with many of their own ways of doing things completely detached from the rest of the Scala community. Play is not in the same boat at all -- this is only one matter -- but I think it's very important to be in line with the spirit of the larger Scala community.

Curious, to what extent do other frameworks (spray, sinatra, finch) require/support DI?


--
Greg Methvin
Senior Software Engineer

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Naftoli Gugenheim

не прочитано,
28 квіт. 2016 р., 03:11:3828.04.16
Кому: play-framework


On Wed, Apr 27, 2016, 1:07 AM Ryan Tanner <ryan....@gmail.com> wrote:
I used to be in favor of the cake pattern (or variants of it) but after seeing a large project that used Guice, only through the javax.inject.* packages, I'm fully onboard with JSR-330.

Yes, there's an occasional exception, but I think I prefer that over the discipline required to keep the cake pattern sane with large teams.  

Just to be clear, I'm not advocating cakifying everything (I have one project where that didn't turn out as well as is hoped). But using some combination of traits, lazy vals, and parameter passing doesn't seem too bad. (I confess I don't have a Play project nearly the size of the aforementioned cakified project, which incidentally uses Lift.)


On Tuesday, April 26, 2016 at 9:24:20 PM UTC-6, Greg Methvin wrote:


On Tue, Apr 26, 2016 at 2:31 PM, Igmar Palsenberg <ig...@palsenberg.com> wrote:
And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra.

Exceptions are fine when they actually represent an exceptional (error) case, especially if they prevent your possibly broken or misconfigured application from starting.

While I agree in a lot of cases the manual Scala code is easier to understand than Guice, there are a few cases where Guice will provide a more useful error than manual wiring. Think about what happens when you accidentally introduce a circular dependency. The equivalent Guice code will error when creating the injector, which means your application won't start at all (usually a good thing). Using manual wiring your app still starts and throws an error later.

Another situation where I like Guice more is when binding eager singletons. lazy vals are the preferred way to declare dependencies using the thin cake pattern, but you have to explicitly call them to make sure they're initialized on startup; Guice handles this for you automatically.

I'm not arguing for either approach here. I'm just saying each approach has its own pros and cons that you should be aware of. I really like the simplicity and elegance of the pure Scala approach, and that's what I've been using recently, but I also understand what's possible with Guice and runtime DI in general.

--
Greg Methvin
Senior Software Engineer

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Igmar Palsenberg

не прочитано,
28 квіт. 2016 р., 05:23:1128.04.16
Кому: play-framework


Op donderdag 28 april 2016 09:02:00 UTC+2 schreef nafg:


On Tue, Apr 26, 2016, 5:31 PM Igmar Palsenberg <ig...@palsenberg.com> wrote:
And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra. 

I was afraid that misunderstanding would happen... :)

What I meant is, I'd prefer not to make exceptions to the rule of "no magic." I didn't mean avoiding throwing runtime exceptions. Although of course that's related, because often magic as opposed to language feature means runtime error rather than compile-time error.

Play is pretty much without magic if you ask me. Only some magic when you use Ebeans on Java, but for the rest, we didn't have much suprises when it comes to this. We also run some (large) Play 1.2 apps, and that's a whole different story.


And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.

Absolutely, no one is suggesting that.

<rant>
To be honest, I rather have Play ditch SBT. If you're talking about magic, SBT gives it all to you. Fighting the magic right now :(
</rant>

:)
A few comments about SBT:
1. I don't think anything in Play depends on SBT other than the SBT plugin. Granted, most of the user experience of developing in Play is provided by the plugin, and working without it is not really documented or practical. The point is that it's possible for someone to develop the equivalent of the SBT plugin (at last the parts that don't require a feature unique to SBT) standalone or for some other build tool. In fact I believe that a groovy or maven integration has been done by someone.

My biggest problem with SBT is that without Scala knowledge, it's nearly impossible to get anything done. It usually means copy & paste code, and hope that it works. Most of the time it does, if it doesn't : Really nasty.
 
2. While there are decisions SBT made that many would disagree with, and that's frustrating, I think SBT is far better than any other build tool.

It probably is. It however has a bad habit of screwing up my Ivy cache, which needs a total wipe in that case. I have a (good) copy of the Ivy cache if it needs restoring, else it will take > 1 hour to re-download all assets.
 
3. If you're expecting SBT to just be a Scala version of some other build tool, you will be very disappointed. SBT has to be understood for what it is. It's an original approach to solving the problem. James Roper has a good set of blog posts explaining what SBT really is (don't have the link at the moment).

I come from a cmake / gnu make world. Both I understand well. I do understand ant / maven, and I dislike XML in general. Both are usually OK for me, but on the other hand : I hardly do any fancy stuff. Different with C / C++, I usually do fancy stuff there. I hope to add SBT to that list some day :)
 
4. Keep an eye on Christopher Vogt's CBT.

 I will. Thanks for the pointers !


Igmar

Christian Kaps

не прочитано,
28 квіт. 2016 р., 05:27:0128.04.16
Кому: play-framework
Dependency Injection is only one specific style of the InversionOfControl(also known as the Hollywood Principle - "Don't call us, we'll call you") pattern used to build reusable, extendable, decoupled and testable components in an object oriented software architecture. So in my opinion the term "Dependency Injection" ist a bit misused here because it's only a single solution for a common problem. As Greg pointed out in another answer, ideally Play should follow the IOC principle and then the choose of the IOC style/container should be delegated to the user. With this in mind it's regardless of whether a user used compile-time or runtime dependency injection, the service locator pattern or if the user wires the dependencies by hand inside the code.

IOC is also complete language agnostic because it's a design pattern used in object oriented programming. So in every language which supports object oriented programming you will stumble over it sooner or later. So for me it's not a Java enterprise thing, it's more a how many experiences do I have in object oriented software architectures. Personally, I've learned this pattern a couple of years ago in the PHP world and I'm sure there are solutions for every object oriented language out there.

Best regards,
Christian

Naftoli Gugenheim

не прочитано,
28 квіт. 2016 р., 09:48:4128.04.16
Кому: play-framework


On Thu, Apr 28, 2016, 5:23 AM Igmar Palsenberg <ig...@palsenberg.com> wrote:


Op donderdag 28 april 2016 09:02:00 UTC+2 schreef nafg:


On Tue, Apr 26, 2016, 5:31 PM Igmar Palsenberg <ig...@palsenberg.com> wrote:
And to be blunt : Java DI isn't that hard. Really, I come from a C / C++ background, and I picked that up in < 3 months, including learning Java.

I don't think it's hard to learn. But one of the great things that I've found about Scala making magic unnecessary, is that things become much more predictable, and thus finding bugs takes much shorter. I don't know if that holds in the question of guice vs. explicit parameter passing, but I'd rather avoid exceptions, even if only for the slippery slope argument.

I actually prefer getting them. And no, Java doesn't have the fancy Scala stuff for the bit extra. 

I was afraid that misunderstanding would happen... :)

What I meant is, I'd prefer not to make exceptions to the rule of "no magic." I didn't mean avoiding throwing runtime exceptions. Although of course that's related, because often magic as opposed to language feature means runtime error rather than compile-time error.

Play is pretty much without magic if you ask me. Only some magic when you use Ebeans on Java, but for the rest, we didn't have much suprises when it comes to this. We also run some (large) Play 1.2 apps, and that's a whole different story.

I would describe guice as magic.



And while it's not always pretty, and sometimes really ugly, it's just what reality is today. Yes, Java DI has some serious limitation, and the Scala way is much better, ditching the Java camp is not really an option I think.

Absolutely, no one is suggesting that.

<rant>
To be honest, I rather have Play ditch SBT. If you're talking about magic, SBT gives it all to you. Fighting the magic right now :(
</rant>

:)
A few comments about SBT:
1. I don't think anything in Play depends on SBT other than the SBT plugin. Granted, most of the user experience of developing in Play is provided by the plugin, and working without it is not really documented or practical. The point is that it's possible for someone to develop the equivalent of the SBT plugin (at last the parts that don't require a feature unique to SBT) standalone or for some other build tool. In fact I believe that a groovy or maven integration has been done by someone.

My biggest problem with SBT is that without Scala knowledge, it's nearly impossible to get anything done. It usually means copy & paste code, and hope that it works. Most of the time it does, if it doesn't : Really nasty.
 
2. While there are decisions SBT made that many would disagree with, and that's frustrating, I think SBT is far better than any other build tool.

It probably is. It however has a bad habit of screwing up my Ivy cache, which needs a total wipe in that case. I have a (good) copy of the Ivy cache if it needs restoring, else it will take > 1 hour to re-download all assets.

Check out coursier. It's an SBT plugin that implements its own resolver rather than using ivy. It's much faster, downloads on parallel, and uses its own cache directory.

 
3. If you're expecting SBT to just be a Scala version of some other build tool, you will be very disappointed. SBT has to be understood for what it is. It's an original approach to solving the problem. James Roper has a good set of blog posts explaining what SBT really is (don't have the link at the moment).

I come from a cmake / gnu make world. Both I understand well. I do understand ant / maven, and I dislike XML in general. Both are usually OK for me, but on the other hand : I hardly do any fancy stuff. Different with C / C++, I usually do fancy stuff there. I hope to add SBT to that list some day :)
 
4. Keep an eye on Christopher Vogt's CBT.

 I will. Thanks for the pointers !


Igmar

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Naftoli Gugenheim

не прочитано,
28 квіт. 2016 р., 09:48:4528.04.16
Кому: play-framework


On Thu, Apr 28, 2016, 5:27 AM Christian Kaps <kaps.ch...@gmail.com> wrote:
Dependency Injection is only one specific style of the InversionOfControl(also known as the Hollywood Principle - "Don't call us, we'll call you") pattern used to build reusable, extendable, decoupled and testable components in an object oriented software architecture. So in my opinion the term "Dependency Injection" ist a bit misused here because it's only a single solution for a common problem. As Greg pointed out in another answer, ideally Play should follow the IOC principle and then the choose of the IOC style/container should be delegated to the user. With this in mind it's regardless of whether a user used compile-time or runtime dependency injection, the service locator pattern or if the user wires the dependencies by hand inside the code.

IOC is also complete language agnostic because it's a design pattern used in object oriented programming. So in every language which supports object oriented programming you will stumble over it sooner or later. So for me it's not a Java enterprise thing, it's more a how many experiences do I have in object oriented software architectures. Personally, I've learned this pattern a couple of years ago in the PHP world and I'm sure there are solutions for every object oriented language out there.

Best regards,
Christian

How are all those fancy buzzwords different than "factor out a pure function"? Pure functions are reusable, extensible, decoupled, and testable.



Am Freitag, 22. April 2016 19:38:32 UTC+2 schrieb Daniel Sanchez:
Hello everyone.

I'm Scala programmer (in fact, I know a bit more about scala that java) and user of Play since 2.1 version 3 years ago. I did not cared about porting my code to use DI before, but with Play 2.5 and the "Deprecated Warning Wall" (DWW) due Play.current, Cache, and WS libraries, I started to make it.

I understand the reasons why Play Team want to use DI "out of the box" in the project, and yes, It is a good thing, but this becomes in a pain in projects like mine where rewrite for use DI does not look trivial.

My issue with it is: using DI seems very complicate to do and explain to your friends if they does not come from Java Enterprice world. I'm no a full Java programmer, never in my life use Spring or anything, my background was in languages like python, ruby, etc, and Scala (only playing with language befor PlayFramework). When I listended about Play years ago that was like "oh, cool, a powerful rails in Scala!", but now it feels too complicate as old Java World.


I have been fighting one week tryng to port my code, but it is hard and complicate.
I really want to know the community opinion about it.

Thanks for read!

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Christian Schmitt

не прочитано,
28 квіт. 2016 р., 14:15:3328.04.16
Кому: play-framework
How do you factor out a pure function that calls Play.current which lazy gets a application (which needs to start everything).
Just look at the code of the BodyParser. There is a call to Play.current to get the ActorSystem to get the Materializer. However you only need an ActorSystem to test them. Still at the current stage every BodyParser test needs the whole application.

James Roper

не прочитано,
11 трав. 2016 р., 00:38:1711.05.16
Кому: play-framework
I'm a bit late to the table here, but I'll put out a few points:

Explicit constructor parameters, implicit parameters (either to constructors or methods), the reader monad, self types, macro based wiring, are all forms of dependency injection. A components dependencies are injected into it by something else (some runtime library, the compiler, or explicitly by the programmer).  Where they differ is in how (and when) the dependencies are injected.  The other flavour of inversion of control is to use a service locator, and none of the above mentioned techniques use a service locator.  I think it is appropriate to call it dependency injection because dependency injection is a well understood design pattern, hence the use of the term dependency injection greatly helps terse, expressive communication.

We did a lot of research and talking to people when we were in the design stages for Play 2.4.  Everyone I talked to had a different opinion on how DI should be done in Scala, and very often, they were of the opinion that every other way was the wrong way.  Some people were dead set on the cake pattern, others said implicit parameters should be used, still others put forward the reader monad.  And if you searched the pros and cons of these, you'd find a long list of cons for each.  DI in the world of Scala without tools like Guice, at that time (early 2014) was very immature, and ill understood.  Of course, I'm sure people in this discussion are likely to respond to that with "I understood what I was doing well!"  And that's enough for your project, but you're missing the point.  Play is a framework used by thousands of people, something that works for just you is not enough.  In the Scala community in general, there was no consensus, there was just argument after argument about what the right way (or wrong way) was.

So our approach was to come up with a solution that would be compatible with as many different Scala dependency injection approaches as possible, but wouldn't push any one in particular.  This would give the Play community time to experiment and understand what the best way was for Play, so that in a future release, we could standardise on that.  But that left a problem, if we're not pushing any particular DI approach, what does a newcomer use?  Do they have to first go research all the different DI approaches in Scala, understand their trade offs, then select one, before they can write Hello World in Play?  Of course that was not an option.  So we made the pragmatic solution of providing Guice as the default DI framework for Scala as well as Java, because although there are better ways to do DI in Scala than Guice, Guice is a mature technology that works - no ones project would fail because we chose Guice.

Sure, using Guice adds magic that's not enforced by the compiler.  But avoiding magic as an end in itself is not a good goal to have - my goal isn't to avoid magic, it's to maximise the clarity and hence the maintainability of a program.  Avoiding magic can certainly help that, as every bit of additional magic you add to a system means you need additional knowledge not enforced by the compiler in order to understand that system.  But as with everything, it's a trade off, there are costs and benefits, the question is whether the costs outweigh the benefits.  What does that magic bring to the table?  How much clarity and maintainability does it cost?  Guice injection may be magic, but it's very straight forward to understand magic, it does not take much time or effort to learn it, and as far as giving new Play developers a good start to writing their system without prematurely forcing a DI strategy that the community may decide to abandon goes, I think it brings a lot to the table.

Going forward, I'm thinking of standardising on macwire.  Macwire of course adds macro magic, but it's magic that happens at compile time, and it's very straight forward to remove it and replace it with a completely manual approach if it ever becomes a problem.  The move to macwire is not to say we'll exclude other types of DI, it's just what will be in the default Play template when you create a new app - there probably won't even be a macwire dependency in Play.  We'll probably try this out in Lagom first.


For more options, visit https://groups.google.com/d/optout.



--
James Roper
Software Engineer

Lightbend – Build reactive apps!
Twitter: @jroper
Відповісти всім
Відповісти автору
Переслати
0 нових повідомлень