com-lihaoyi / scalatags

ScalaTags is a small XML/HTML construction library for Scala.
https://com-lihaoyi.github.io/scalatags/
MIT License
753 stars 117 forks source link

`implicits` import needs more traits mixed in. #119

Open stewSquared opened 8 years ago

stewSquared commented 8 years ago

This comes up every now and then in the gitter:

No idea why. In general if I don’t want to pollute the namespace, how should I import scalatags?

I wonder why is it not working, maybe I should add some imports?

Basically, implicits doesn't have enough traits to be used independently like all or short.

Instead of just extending Aggregate, it should also extend DataConverters and Util. That last one is tricky, though, because you can only import ._ from a single object that extends Util(or Cap) or lose implicits to ambiguity. The fact that each of tags, tags2, attrs, styles, styles2, svgTags, svgAttrs extends Cap is then extremely limiting. Sensible sounding imports like the following break:

import svgAttrs._
import svgTags._
import implicits._ //Assuming we make this mix in the implicits from Util, this breaks
import tags._

I suggest refactoring these packages so that only all, short, and implicits extend Util.

I have a proof of concept diff for just the refactor of tags and implicits. The basic idea is to have most packages import from a member of type Util rather than extending it. If that looks like the right direction, I can apply that to the rest and turn it into a PR.

stewSquared commented 8 years ago

Since this has brought up again via #134, I should share what I've learned.

I've tried removing Util from various objects. This worked fine for tags and attrs, but gets really messy for styles. See my WIP here: https://github.com/stewSquared/scalatags/tree/implicits-import

A better option might be to dig into what's causing the implicits to fail in the first place. I would expect implicit shadowing to solve the problem, since everything that extends Cap/Util, should have implicits of the same name and type. But implicit shadowing seems to be failing. I suspect has something to do with the roundabout inheritance/mixing happening here. The implicits no longer have the same type because Frag, Modifier, etc., all have different types in these objects, causing shadowing to fail.

Maybe someone can come up with a minimal example?

lihaoyi commented 7 years ago

I've just bumped into this again; it seems that even small things like import scalatags.JsDom.svgAttrs._ also pulls in implicits, which can conflict. I think we should get rid of most of the implicits except for those in .all and .implicits, to avoid conflict