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

[Feature request, speculative] Allow arbitrary method "forwarding" #58

Closed
adampauls opened this issue Mar 10, 2020 · 4 comments
Closed

Comments

@adampauls
Copy link
Contributor

adampauls commented Mar 10, 2020

While writing #57, it occurred to me that it might be possible to do something general to "override" the behavior of existing methods on types. I think one can write a generic ForwardingFunctor that allows you to declare something like

trait OneTypeArgForwardingFunctor[F[_], T, M]

implicit def OptionGetForwardingFunctor[T]: OneTypeArgForwardingFunctor[Option, T, { def get: T}] = new ForwardingFunctor[Option, T, {def get: T}] {
  def get(ft: Option[T])(f: T => T): F[T] = Some(f(ft.get))
}

implicit def OptionGetOrElseForwardingFunctor[T]: OneTypeArgForwardingFunctor[Option, T, { def getOrElse(default: => T): T}] = new ForwardingFunctor[Option, T, {def get: T}] {
  def getOrElse(ft: Option[T], default: => T)(f: T => T): F[T] = Some(f(ft.getOrElse(default))
}

Then, when encountering a method call in a path, quicklens could first first call Context. inferImplicitValue(ForwardingFunctor[tpe.typeConstructor, tpe.typeArg, {method signature}]), where method signature is a structural type that matches the signature of method. If nothing is found, it can fallback to copies. Obviously the previous is not valid code but I hope you get my meaning.

This would allow client code to override the behavior of any existing method on any existing class without writing new macro code, so for example you could override Array.apply to act like at, and you could also allow people to call defs defined on case classes. I'm not entirely sure this will all work out, I'm still learning what the limits of macros are, and there's definitely some subtleties around higher-kinded types and mismatches in type parameters. Just a thought, would you be interested if I could work it out?

I'd happily take this on if you think this feature would be useful.

@adampauls adampauls changed the title [Feature request, speculative] [Feature request, speculative] Allow arbitrary method "forwarding" Mar 10, 2020
@adamw
Copy link
Member

adamw commented Mar 10, 2020

That would be a nice trick, however usage of structural types in Scala is discouraged. It's based on reflection, slow, non-graalvm-friendly etc. :)

@adampauls
Copy link
Contributor Author

Right, yes, I'm aware of that. IIUC though, the nice thing here is that the structural types would be compile-time only, just there to provide a way to get a handle on the implicit. No reflection would actually be called at runtime. I'm not sure if there's away to actually @compileTimeOnly those types, I can look into it.

@adampauls
Copy link
Contributor Author

I thought this through and it won't work like I expected.

@adamw
Copy link
Member

adamw commented Mar 16, 2020

Ah, well, always worth exploring :)

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

2 participants