Skip to content

Instantly share code, notes, and snippets.

@jlareck
Last active Sep 2, 2021
Embed
What would you like to do?
How to share Quotes entities between multiple methods

Problem: we need to share same symbols between two methods. How we can do this? The first idea of solution: We can create a class like Helper with [Q <: Quotes, T: Type](using val q: Q) and in this case we avoid duplication of (using Quotes) for each entitiy.

class Helper[Q <: Quotes, T: Type](using val q: Q) {
  import q.reflect.*

  val classDynamicSymbol = Symbol.requiredClass("me.shadaj.scalapy.py.Dynamic")
  val classReaderSymbol = Symbol.requiredClass("me.shadaj.scalapy.readwrite.Reader")
  val classWriterSymbol = Symbol.requiredClass("me.shadaj.scalapy.readwrite.Writer")
  val classAnySymbol = Symbol.requiredClass("me.shadaj.scalapy.py.Any")
 }

object FacadesImpl {
  def native_impl[T: Type](using q: Quotes): Expr[T] = {
      import q.reflect.*
      val helper = new Helper[q.type, T]
      ....
  }
  def native_named_impl[T: Type](using q: Quotes): Expr[T] = {
      import q.reflect.*
      val helper = new Helper[q.type, T]
      ....
  }
}

The second idea of solution: We can create an object with defs like this:

object Shared {
  def classReaderSymbol(using Quotes) = {
    import quotes.reflect.*
    Symbol.requiredClass("me.shadaj.scalapy.readwrite.Reader")
  }

  def classWriterSymbol(using Quotes) = {
    import quotes.reflect.*
    Symbol.requiredClass("me.shadaj.scalapy.readwrite.Writer")
  }
}

But here we have duplication of using Quotes and import quotes.reflect.* .

The third idea of solution: we can reduce the lines in the second solution by changing using Quotes to using q: Quotes and rewrite in this way:

object Shared {
  def classDynamicSymbol(using q: Quotes) = 
    q.reflect.Symbol.requiredClass("me.shadaj.scalapy.py.Dynamic")
 }

What solution is better? Is there any other solution for sharing entities from Quotes?

@nicolasstucki
Copy link

nicolasstucki commented Sep 2, 2021

Option 5

object Shared {
  def classDynamicSymbol(using Quotes) = 
    Symbol.requiredClass("me.shadaj.scalapy.py.Dynamic")
  
  private def Symbol(using Quotes): quotes.reflect.Symbol.type = quetes.reflect.Symbol
}

@nicolasstucki
Copy link

nicolasstucki commented Sep 2, 2021

Option 6
object Shared {
  def classDynamicSymbol(using Quotes) = requiredClass("me.shadaj.scalapy.py.Dynamic")
  
  private def requiredClass(name: String)(using Quotes): quotes.reflect.Symbol = 
    quetes.reflect.Symbol.requiredClass(name)
}

@nicolasstucki
Copy link

nicolasstucki commented Sep 2, 2021

The first one is the only one that should not be used. If there are errors with the paths it may be quite cryptic why it fails.

@jlareck
Copy link
Author

jlareck commented Sep 2, 2021

Okay, I see, thank you a lot! I guess I will use the 4th option then

@nicolasstucki
Copy link

nicolasstucki commented Sep 2, 2021

Good choice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment