Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Allow export of extension clause parameters #17678

Closed
adampauls opened this issue Nov 6, 2022 · 0 comments
Closed

Allow export of extension clause parameters #17678

adampauls opened this issue Nov 6, 2022 · 0 comments

Comments

@adampauls
Copy link
Contributor

adampauls commented Nov 6, 2022

After this PR, it is possible to export members in extension clauses like so:

extension (t: T)(using inst: Foo[T])
  private def tCeremony = t
  export tCeremony.*
  private def instCeremony = inst
  export instCeremony.*

It would be nice to be able to do

extension (t: T)(using inst: Foo[T])
 export t.*
 export inst.*

This might seem a little silly, but it would be very useful for typeclass programing. With inheritance, it is nice to be able to declare an interface using a val or def on a trait and then "implement" it with a param on a case class. With typeclasses, you can already do a similar thing:

trait Typeclass[Self]:
  extension(self: Self)
    def prop1: String
    def prop2: Int
    def method(x: Int): String

case class Foo(prop1: String, prop2: Int, extraProp: Boolean):
  def method(x: Int): String = x.toString

given Typeclass[Foo] with
  extension (self: Foo)
    private def selfCeremony = self
    export selfCeremony.*

def takesTypeclass[T: Typeclass](t: T): String = t.prop1 + t.method(t.prop2)
object Test {
  takesTypeclass(Foo("a", 2, true))
}

but that extra ceremony in the extension is a little ugly. Similarly, as suggested by this thread, it would be nice to be able to call "static" methods on a typeclass (those not naturally written as extension (self: Self) def ... using static syntax:

trait Typeclass[Self]:
  def static(x: Int): Int

object Typeclass:
  extension [Self](n: Typeclass.type)(using tc: Typeclass[Self])
    private def tcCeremony = tc
    export tcCeremony.*

def takesTypeclass[T: Typeclass](t: T): Int = Typeclass.static(5)
// instead of def takesTypeclass[T: Typeclass](t: T): Int = summon[Typeclass[T]].static(5)
// or         def takesTypeclass[T](t: T)(using tc: Typeclass[T]): Int = tc.static(5)

I think this is probably a very simple change, but I could not figure out how to do it myself.

@ckipp01 ckipp01 transferred this issue from lampepfl/dotty-feature-requests May 31, 2023
@scala scala locked and limited conversation to collaborators May 31, 2023
@ckipp01 ckipp01 converted this issue into discussion #17679 May 31, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant