
Implicit Scope and Implicit Resolution in Scala - dade
http://www.geekabyte.io/2017/12/implicit-scope-and-implicit-resolution.html
======
sreque
It's always ironic to me that people think implicits reduce code clarity, and
yet those same people use runtime DI frameworks and possibly AOP. Scala
implicits can in my opinion be thought of as a simple compile-time lexically-
scoped DI framework. It's very much a compile-time equivalent of the
@Autowired or @Inject annotation in runtime DI frameworks, except it has the
benefit of lexical scoping.

The great thing about implicits is that errors occur at compile-time and your
IDE can give you all the information you need to understand what implicits are
in play. On the other hand, there is no tool in the world that will save you
from a complex spring-based application with strange initialization order
errors, certain features silently not working for who knows what reason, and
often barely-comprehensible stacktraces.

~~~
tomerbd
Interesting.

My question then would be is there any convention of where to create all these
implicits?

In the old xml spring world (with it's proc and cons) I knew I could locate
the creation and injection of my dependencies in a single xml, which was fully
dedicated for object creation and injection, so it was very organised, and
enforced all developers to work the same way.

How would I look at a codebase and understand if there is are clear places
where the objects (implicits) are created and, how do I override them in
tests? Do I need to invent all this, or follow a convention? How do I
understand the structure of dependencies in the project?

spring xml enforced me to do it in a certain way and enforced everybody to do
it in a certain way which was great, any project I opened I new what was
happening at least in DI prespective.

And then I would ask what about the cake pattern in scala for a kind of
dependency injection? I mean would you prefer one of them for dependency
injection? or is it relative to the case you work at?

~~~
sreque
So, to start, I would say that I agree with you that I like my DI logic for my
application centralized, whether it's in a single or few classes or in a
single or few XML files. On the other hand, people who use @Autowired or
@Inject are doing the opposite; they are scattering their DI logic throughout
the application, which I very much do not prefer.

That said, the DI analogy breaks down a little bit when you consider that
Scala implicit resolution happens at compile-time and is lexically scoped. As
such, you can't override implicits that are created/resolved in other source
files without editing those source files directly. You can only affect the
implicits in your source files by using imports or defining implicit
overrides.

If you want a full-blown compile-time DI framework with centralized logic in a
single location, then Scala's MacWire library seems to be the best example:
[https://github.com/adamw/macwire](https://github.com/adamw/macwire)

Scala's implicits can be seen as some kind of lightweight DI system, but it is
definitely not meant to be used to wire together an application at the top-
level.

------
christophilus
I haven't used implicit scopes in Scala, but after watching a demo of them, I
think it's a feature that can easily be abused and cloud code clarity. Scala
more than almost any other language in it's class seems particularly full of
such features.

I'd love to hear from some seasoned Scala folk: what do you think of these new
features?

~~~
tunesmith
I'm not quite seasoned, but I recognize that this discussion regularly gets
muddied because it conflates implicit parameters and implicit conversions.

Implicit parameters are everywhere, and they're relatively simple to
understand once you get past the mental block that your variables might not
actually be declared in the file of code you are viewing. Your mental model
just has to include what that file _imports_ , and then you can pretty much
understand what implicit parameters are doing. Implicit parameters are useful
for a basic form of dependency injection, and they're one of the basic
prerequisites for when you are using actors or futures.

Implicit conversions are something else - I wouldn't use them just to be
clever.

But once you get into things like typeclasses (which are easier to understand
in Haskell for some reason), implicits become important. So if you have reason
to use typeclasses (and there are very good reasons to use them), then
implicits are valuable.

If your programming doesn't need much abstraction, then you don't really need
those kinds of tools though.

~~~
christophilus
I understand the distinction and don't like implicit parameters.

Coming from Clojure, one could say that the "use" keyword shares a lot of the
same pitfalls as implicit parameters, in that you are introducing values into
your namespace which have not explicitly been referenced or scoped.

In Clojure, I choose "require" instead of "use" because "use" introduces too
much ambiguity. The "use" statement in Clojure consistently makes code harder
to read (for me), and I suspect the same is true of Scala's implicit
parameters.

[Edit: Rails is another great example of implicit parameters run amok.
Needless to say, I'm not a Rails fan.]

