Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

terse syntax for typeclass instances #2879

Closed
fommil opened this issue Jul 17, 2017 · 14 comments
Closed

terse syntax for typeclass instances #2879

fommil opened this issue Jul 17, 2017 · 14 comments

Comments

@fommil
Copy link

fommil commented Jul 17, 2017

When creating a typeclass instance, one must do a lot of boileplate. The instance pattern is well known but still has boilerplate.

implicit val FooBar: Foo[Bar] = instance { b => ... }

It would be nice if this something like this were possible

implicit val _: Foo[Bar] = instance { b => ... }

Which is still full of boilerplate, so better suggestions would be good. The linked ticket talks about a lot of the more general cases and is worth reading.

@sjrd
Copy link
Member

sjrd commented Jul 17, 2017

implicit val _ would have zillions of problems wrt. binary compatibility (irrespective of "typeclasses" or other uses of implicits). You really need an explicit name.

@fommil
Copy link
Author

fommil commented Jul 17, 2017

Then generate the name from the type in the manner suggested.

@Jasper-M
Copy link
Contributor

@fommil I don't think you included your suggestion for generating a name in this ticket ;)

@fommil
Copy link
Author

fommil commented Jul 17, 2017

oh, it's IMPLICIT 😛

@smarter
Copy link
Member

smarter commented Jul 17, 2017

You'd need a spec for generating a name from a type that accounts for every possible way to write a type, not something that sounds very fun. However, Dotty does reduce the boilerplate a bit by desugaring:

val x: Foo[Bar] = new { ... }

To:

val x: Foo[Bar] = new Foo[Bar] { ... }

@fommil
Copy link
Author

fommil commented Jul 17, 2017

wouldn't it just be a case of leaving all alphanums in place and erasing everything else from the explicit type that was written? Manual conflict resolution. It's just a heuristic and for bincompat the user can always write the original val name out again.

@mdedetrich
Copy link

implicit val _ would have zillions of problems wrt. binary compatibility (irrespective of "typeclasses" or other uses of implicits). You really need an explicit name.

It would also make it hard (or impossible) to use the implicit explicitly incase of ambiguous implicit s

@Jasper-M
Copy link
Contributor

It would also make it hard (or impossible) to use the implicit explicitly incase of ambiguous implicits

Actually it's already possible to define an implicit that can't be used explicitly:

scala> object Module { 
     |   trait Foo[T]
     |   private[Module] object Foo { 
     |     implicit def FooString = new Foo[String] { 
     |       override def toString = "it's me!"
     |     } 
     |   } 
     | }
defined object Module

scala> implicitly[Module.Foo[String]]
res0: Module.Foo[String] = it's me!

scala> Module.Foo.FooString
<console>:13: error: object Foo in object Module cannot be accessed in object Module
       Module.Foo.FooString
              ^

@mdedetrich
Copy link

@Jasper-M Yes, but you can't refer to the implicit typeclass instance that was defined explicitly because it has no name, so if you want to use this typeclass instance explicitly you can't (unless you want to just copy the source code and create a typeclass instance on the fly which is what it seems like you are proposing)

@Jasper-M
Copy link
Contributor

@mdedetrich I'm sorry, I think at least one of us is confused. I wasn't disagreeing nor proposing anything. I meant to demonstrate that in current scala and dotty it is already possible to define an implicit that can only be used implicitly and not explicitly.

@sjrd
Copy link
Member

sjrd commented Jul 26, 2017

Actually it's already possible to define an implicit that can't be used explicitly:

I don't think that's intended. IMO that's a bug. The compiler should not allow you to do that, since it is clearly violating the privateness of object Foo.

@mdedetrich
Copy link

@Jasper-M Ah, thanks for clarifying

@Jasper-M
Copy link
Contributor

I don't think that's intended. IMO that's a bug. The compiler should not allow you to do that, since it is clearly violating the privateness of object Foo.

Not disagreeing here either :-p Whether it's a bug or feature is not entirely clear to me. However Dotty seems to be bug-or-feature compatible with it.

@odersky
Copy link
Contributor

odersky commented Jan 15, 2018

I am reluctant to introduce another use of _. Maybe it's just lack of a good naming convention? If we write in the original example:

implicit val FooIsBar: Foo[Bar] = instance { b => ... }

I think that's actually quite legible. Using a _ would be shorter but would not add to clarity. So I am closing this one.

@odersky odersky closed this as completed Jan 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants