Implicit compilation errors when mixing slick and akka imports

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Implicit compilation errors when mixing slick and akka imports

Matan Safriel
Hi, 

This a small frustration about Scala as it is about Slick.
Introducing the following direct SQL access imports into otherwise working slick code:

import scala.slick.driver.JdbcDriver.backend.Database
import Database.dynamicSession

A previously working session implicit stops working with scala.slick.SlickException: No implicit session available;

As much as I recall from a similar case with Akka imports, there is no proper/documented way to realize there is a collision behind the scenes regarding an implicit. I assume it may be the same case here, although I intuitively realized these imports introduced the regression and just removed them to solve. Previously with Akka, scala complained about no implicit being available whereas in fact there were two of them available.

Hopefully this friction can be avoided in the future, or at least mentioned as an eye catching warning at the top of http://slick.typesafe.com/doc/2.0.0/sql.html.

I think there's something fundamentally broken in Scala or TypeSafe Scala libraries with how implicits are handled in compilation errors. I read the Scala community code of conduct, this is not intended as a snide comment but as a suggestion for making things more coder friendly when it comes to avoiding implicit black holes in compilation scenarios.

-matan

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Jon Pretty-4
This is a problem several people are very conscious of. There's a well-advanced proposal in the Typelevel fork of the Scala compiler to offer a better error message for these cases.

https://github.com/typelevel/scala/pull/32

Cheers,
Jon

On 25 September 2014 19:31, Matan Safriel <[hidden email]> wrote:
Hi, 

This a small frustration about Scala as it is about Slick.
Introducing the following direct SQL access imports into otherwise working slick code:

import scala.slick.driver.JdbcDriver.backend.Database
import Database.dynamicSession

A previously working session implicit stops working with scala.slick.SlickException: No implicit session available;

As much as I recall from a similar case with Akka imports, there is no proper/documented way to realize there is a collision behind the scenes regarding an implicit. I assume it may be the same case here, although I intuitively realized these imports introduced the regression and just removed them to solve. Previously with Akka, scala complained about no implicit being available whereas in fact there were two of them available.

Hopefully this friction can be avoided in the future, or at least mentioned as an eye catching warning at the top of http://slick.typesafe.com/doc/2.0.0/sql.html.

I think there's something fundamentally broken in Scala or TypeSafe Scala libraries with how implicits are handled in compilation errors. I read the Scala community code of conduct, this is not intended as a snide comment but as a suggestion for making things more coder friendly when it comes to avoiding implicit black holes in compilation scenarios.

-matan

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



--
Jon Pretty | @propensive

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Jason Zaugg
In reply to this post by Matan Safriel

On Fri, Sep 26, 2014 at 3:31 AM, Matan Safriel <[hidden email]> wrote:

Hi, 

This a small frustration about Scala as it is about Slick.
Introducing the following direct SQL access imports into otherwise working slick code:

import scala.slick.driver.JdbcDriver.backend.Database
import Database.dynamicSession

A previously working session implicit stops working with scala.slick.SlickException: No implicit session available;

As much as I recall from a similar case with Akka imports, there is no proper/documented way to realize there is a collision behind the scenes regarding an implicit. I assume it may be the same case here, although I intuitively realized these imports introduced the regression and just removed them to solve. Previously with Akka, scala complained about no implicit being available whereas in fact there were two of them available.

Hopefully this friction can be avoided in the future, or at least mentioned as an eye catching warning at the top of http://slick.typesafe.com/doc/2.0.0/sql.html.

Thanks for sharing this problem.

It would be useful to create an standalone example of this problem that we could discuss.

Here’s what I tried:

@annotation.implicitNotFound("No Session for You!")
trait Session
object Database {
  implicit def dynamicSession1: Session = ???
  implicit def dynamicSession2: Session = ???
}

object Test1 {
  import Database.dynamicSession1

  def foo {
    import Database.dynamicSession2
    implicitly[Session] // useful error message
  }
}

object Test2 {
  import Database.dynamicSession1

  def foo {
    import Database.dynamicSession1
    implicitly[Session] // works
  }
}

object Test3 {
  import Database._

  def foo {
    import Database.dynamicSession1
    implicitly[Session] // useful error message
  }
}

-jason

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Johannes Rudolph-2
In reply to this post by Jon Pretty-4
Hi Jon, hi Matan,

On Fri, Sep 26, 2014 at 12:49 AM, Jon Pretty <[hidden email]> wrote:
> https://github.com/typelevel/scala/pull/32

Does that proposal also deal with the problem that in a possible tree
of implicit lookups not all errors from the leaves are shown but only
the top error? If you don't show all info, you are left with the
choices of either showing only the top error (what Scala does
currently) or showing only some errors from the leaf level which may
lead to the actual error still being lost in the process.

I've got a POC macro which can be used on a case-by-case basis that
tries to show all necessary info as shown in the attached screenshot.

https://github.com/jrudolph/rescue

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

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

screenshot1.png (52K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Johannes Rudolph-2
On Fri, Sep 26, 2014 at 11:35 AM, Johannes Rudolph
<[hidden email]> wrote:
> I've got a POC macro which can be used on a case-by-case basis that
> tries to show all necessary info as shown in the attached screenshot.
>
> https://github.com/jrudolph/rescue

Btw. the point of the screenshot is that from the point of the
compiler you could provide either of those implicits and the lookup
would likely succeed.

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Jon Pretty-4
Hi Johannes,

That looks really useful!

The issue I referenced doesn't cover that case, but this one does:

  https://github.com/typelevel/scala/issues/25

It's assigned to me, but I haven't started looking at it yet. I'll definitely take a closer look at "rescue" before I do.

Cheers,
Jon

On 26 September 2014 11:37, Johannes Rudolph <[hidden email]> wrote:
On Fri, Sep 26, 2014 at 11:35 AM, Johannes Rudolph
<[hidden email]> wrote:
> I've got a POC macro which can be used on a case-by-case basis that
> tries to show all necessary info as shown in the attached screenshot.
>
> https://github.com/jrudolph/rescue

Btw. the point of the screenshot is that from the point of the
compiler you could provide either of those implicits and the lookup
would likely succeed.

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net



--
Jon Pretty | @propensive

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Hubert Plociniczak-4
In reply to this post by Johannes Rudolph-2
On 09/26/2014 11:35 AM, Johannes Rudolph wrote:

> Hi Jon, hi Matan,
>
> On Fri, Sep 26, 2014 at 12:49 AM, Jon Pretty <[hidden email]> wrote:
>> https://github.com/typelevel/scala/pull/32
> Does that proposal also deal with the problem that in a possible tree
> of implicit lookups not all errors from the leaves are shown but only
> the top error? If you don't show all info, you are left with the
> choices of either showing only the top error (what Scala does
> currently) or showing only some errors from the leaf level which may
> lead to the actual error still being lost in the process.
>
> I've got a POC macro which can be used on a case-by-case basis that
> tries to show all necessary info as shown in the attached screenshot.
>
> https://github.com/jrudolph/rescue
>

I really like that you were able to pull that off with just using macro.
A bit of a problem is that potential implicits are often eagerly
rejected based on the shape of the type. This is especially annoying
when inferencer instantiates type parameter to a too narrow type etc. I
don't think that macro will reveal such information because it is too
late in the business. Also, I haven't tried, but I imagine that
diverging implicits can be problematic?

I, personally, take a slightly different, more aggressive, approach,
where I instrument the full compiler to collect all the important
typechecker decisions and help with debugging type inference in general.
As it turned out, I was able to apply the same approach to debugging
implicits. And yes, I can visualize all the decisions of the typechecker
but this typically generated too much information to be comprehensible
for regular users (just think of LMS which often has to consider tens or
hundreds of implicits every single time). I believe that a more
systematic way through an interactive (console) debugger is a way to go;
there you can track decisions of implicit resolution in a step-by-step
manner but sometimes you can also ask debugger to do some of that work
for you. That's from my side, but still I'm impressed with your macros
hack approach.

hubert

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Johannes Rudolph-2
Hi Hubert,

thanks for looking at it!

On Fri, Sep 26, 2014 at 12:03 PM, Hubert Plociniczak
<[hidden email]> wrote:
> I really like that you were able to pull that off with just using macro.

Yes, it's such a ridiculous hack in many regards it's amazing that it
works at all.

> A bit of a problem is that potential implicits are often eagerly rejected
> based on the shape of the type. This is especially annoying when inferencer
> instantiates type parameter to a too narrow type etc. I don't think that
> macro will reveal such information because it is too late in the business.

It captures the output of `-Xlogimplicits`. So, everything that's in
there the macro should be able to process.

> Also, I haven't tried, but I imagine that diverging implicits can be
> problematic?

I cannot remember but it would be interesting to see what happens.

> I, personally, take a slightly different, more aggressive, approach, where I
> instrument the full compiler to collect all the important typechecker
> decisions and help with debugging type inference in general. As it turned
> out, I was able to apply the same approach to debugging implicits. And yes,
> I can visualize all the decisions of the typechecker but this typically
> generated too much information to be comprehensible for regular users (just
> think of LMS which often has to consider tens or hundreds of implicits every
> single time). I believe that a more systematic way through an interactive
> (console) debugger is a way to go; there you can track decisions of implicit
> resolution in a step-by-step manner but sometimes you can also ask debugger
> to do some of that work for you. That's from my side, but still I'm
> impressed with your macros hack approach.

I think whatever type debugging mechanism there is it must scale. The
current Scala behavior doesn't scale because it shows too little
information even for an implicit problem that is just nested one level
deep. My macro, and the screenshot I showed is somewhat tailored for a
frequent issue we've seen with spray where an `ExecutionContext` is
missing some levels deep. Having to use an interactive console for
problems like this would be overkill. But, I agree, for even more
complex types, an even deeper view into what's going on might be
necessary.

One indication for that are all the regexes the macro uses to cut away
information wherever possible to make it feasible at all to show
something on the console (and to resurrect information lost by the
compiler creating error message strings out of real info).


--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Implicit compilation errors when mixing slick and akka imports

Stefan Zeiger
In reply to this post by Matan Safriel
On 2014-09-25 19:31, Matan Safriel wrote:
Introducing the following direct SQL access imports into otherwise working slick code:

import scala.slick.driver.JdbcDriver.backend.Database
import Database.dynamicSession

A previously working session implicit stops working with scala.slick.SlickException: No implicit session available;

As much as I recall from a similar case with Akka imports, there is no proper/documented way to realize there is a collision behind the scenes

This doesn't look like a collision. You get this exception at runtime because the dynamicSession was not properly initialized. I assume you have something along the lines of:

    db.withSession { implicit session => myQuery.run }

This won't initialize the dynamic session, which only happens in the overload of withSession that takes a thunk, not a function with a Session parameter.

So the interesting question here is why the imported dynamicSession implicit has a higher priority than the implicit Session in your own code, which is impossible to tell if you don't provide the actual code.

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