Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Luis Miguel Mejía Suárez
    @BalmungSan
    @masonedmison it should work the same as with the main, doesn't it?
    Mason Lazalier Edmison
    @masonedmison
    I believe so, yes. I was more asking about how we should name the tests and extract them out, e.g. what is the best way to extract out the hlist tests from DriverSpec.
    I could imagine us
    1) have a DriverSpec in each the scala-2 and scala-3 directories and the only differing bits would be hlist vs. tuple, respectively
    or
    2) Have a base BaseDriverSpec with the "common" tests that work for both versions in scala and then extend this within scala-2 and scala-3 directories (as DriverSpec) adding the hlist and tuple tests there.
    Luis Miguel Mejía Suárez
    @BalmungSan
    @masonedmison I would follow the typelevel style here.
    A empty class that extends a platform depedant trait that contains the actual tests.
    That way, we can refer to that class in the DriverSpec
    Mason Lazalier Edmison
    @masonedmison
    Ah yes very nice. I'll follow this pattern, thanks @BalmungSan
    Luis Miguel Mejía Suárez
    @BalmungSan
    Let meknow if you find any other problem :)
    Mason Lazalier Edmison
    @masonedmison
    Sounds good. I was going to start looking at the Cypher interpolator macro tonight along with fixing the tests using the above suggestion
    Luis Miguel Mejía Suárez
    @BalmungSan
    :tada:
    Luis Miguel Mejía Suárez
    @BalmungSan

    Hi @/all I just opened an issue that brings some complex topics on the table for discussion, I would be very grateful if you can find the time to read it and leave your thoughts.
    Thanks in advance!

    neotypes/neotypes#561

    Mason Lazalier Edmison
    @masonedmison
    Hey all, sort of an update/non-update. Spinning my wheels regarding the CypherStringInterpolator scala3 port. Particularly the bit I am struggling with is how to work with the args: Any* (within c). In scala3, this ends up being Expr[Seq[Any]] to whereas (IIUC) scala2 we are able to get an Iterator[Expr[Any]] (in which we can ultimately get the Tree and type for each element to splice in the code the QueryArgMapper for said type).
    Luis Miguel Mejía Suárez
    @BalmungSan
    Did you checked how literally does it?
    Mason Lazalier Edmison
    @masonedmison
    Ah I have not, good call.
    I was looking at protoquill for some inspo but that stuff is still above my head.
    Mason Lazalier Edmison
    @masonedmison
    Ah it doesn't look like Literally actually uses the Expr[Seq[Any]] - only in reporting an error if interpolation is not supported (here)[https://github.com/typelevel/literally/blob/main/core/shared/src/main/scala-3/org/typelevel/literally/Literally.scala#L41]

    Alex Ioffe suggested doing something like this

    def myMacro(builder: DeferredQueryBuilder): Something = ${ myMacroImpl('builder) }
    def myMacroImpl(builder: Expr[DeferredQueryBuilder])(using Quotes): Expr[Something] =
      builder match
        case '{ CypherStringInterpolator($partsExpr).c(${ Varargs(params) }: _*) } => 
          partsExpr match
            case '{ StringContext.apply(${ Varargs(parts) }: _*) } =>
              // at this point you have parts: Expr[Seq[String]] and params: Expr[Seq[Any]] or something like that

    but I am not sure how we would pass in DeferredQueryBuilder since that is what the macro itself returns.

    Luis Miguel Mejía Suárez
    @BalmungSan
    So I think it should be the opposite.
    def myMacroImpl(builder: Expr[Seq[Any]])(using Quotes): Expr[DeferredQueryBuilder] =
    Or something, I really have not even looked into a hello world example of Scala 3 macros
    Mason Lazalier Edmison
    @masonedmison
    Still plugging away on this. Getting... closer I think/hope?
    Luis Miguel Mejía Suárez
    @BalmungSan
    No worries, thanks a lot fot he hard work!
    Mason Lazalier Edmison
    @masonedmison
    This still needs a lot of work (and the way parts is currently is downright wonky) but after a few days of wrestling with this, I at least have something that compiles so I will savor this as a milestone :sweat_smile:
    package neotypes
    
    import scala.quoted._
    import internal.utils.queryparts.createQuery
    import scala.reflect.*
    import neotypes.types.QueryParam
    import scala.annotation.tailrec
    
    final case class CypherStringInterpolator(private val sc: StringContext) extends AnyVal {
      inline def c(inline args: Any*): DeferredQueryBuilder = ${ CypherStringInterpolator.macroImpl('args, 'sc) }
    }
    
    object CypherStringInterpolator {
    
      type Res = Either[String, QueryArg]
    
      def macroImpl(argsExpr: Expr[Seq[Any]], clz: Expr[StringContext])(using quotes: Quotes): Expr[DeferredQueryBuilder] =
        import quotes.reflect.*
    
        def invert[T: Type](exprs: Expr[Seq[T]]): List[Expr[T]] =
          exprs match {
            case Varargs(props)                     => props.toList
            case '{ Seq(${ Varargs(props) }) }      => props.toList.map(_.asExprOf[T])
            case _ => println(s"Unable to match ${exprs.show} "); null
          }
    
        def argMapperFor(tt: TypeRepr) =
          TypeRepr.of[QueryArgMapper].appliedTo(tt)
    
        def asRightQueryArg(expr: Expr[Any]): Expr[Res] =  
          val tt = expr.asTerm.tpe.widen
          Implicits.search(argMapperFor(tt)) match {
            case iss: ImplicitSearchSuccess => {
              val tcl = iss.tree
              val e = Apply(Select.unique(tcl, "toArg"), expr.asTerm :: Nil)
                .asExprOf[QueryArg]
              '{ Right($e) }  
    
          }
            case isf: ImplicitSearchFailure =>
              val e = Expr(isf.explanation)
              '{ compiletime.error($e) }
        }
    
        def parts: List[Expr[Boolean => Res]] = {
          val inverted = invert(argsExpr)
          inverted  
            .map { (expr: Expr[Any]) => 
              val qarg: Expr[Res] = asRightQueryArg(expr)
              '{
                (b: Boolean) => 
                  if (b) 
                    $qarg
                  else Left($expr.toString)
              } 
            }
        }
    
        val partsPacked: Expr[List[Boolean => Res]] = Expr.ofList(parts)
    
        val boolsAndRes: Expr[(List[Boolean], List[Res])] = '{ 
          $clz
            .parts
            .foldLeft((List.empty[Boolean], List.empty[Res])) { case ((hashTags, res), s) =>
                val nextRes = Left(s) :: res
                if (s.endsWith("#"))
                  (false :: hashTags) -> nextRes
                else
                  (true :: hashTags) -> nextRes
            }
        }
    
        val interleaved: Expr[List[Res]] = 
          '{
            Interleave($partsPacked, $boolsAndRes._2, $boolsAndRes._1)
          }
        '{ createQuery($interleaved: _*) }
      }
    
      object Interleave {
        import CypherStringInterpolator.Res
        def apply(parts: List[Boolean => Res], queries: List[Res], endWithHashTags: List[Boolean]): List[Res] =
          interleave(parts, queries, endWithHashTags, List.empty)
        private[this] def interleave(parts: List[Boolean => Res], queries: List[Res], endWithHashTags: List[Boolean], acc: List[Res]): List[Res] =
          (queries, parts, endWithHashTags) match {
            case (Nil, l2, b)            => acc.reverse ++ (l2 zip b).map { case (e, b) => e(b)} 
            case (l1, Nil, _)            => acc.reverse ++ l1
            case (h1 :: t1, h2 :: t2, bh :: bt) => interleave(t2, t1, bt, h2(bh) +: h1 +: acc)
            case _ => acc
        }
      }
    Luis Miguel Mejía Suárez
    @BalmungSan
    :tada: :tada: :tada:
    Aaron Hiniker
    @hindog
    hey all, is there a way to execute a query with results and ALSO get the ResultSummary somehow? From what I've seen, the only way to get a ResultSummary back is by using the execute method but I also want to return records
    Luis Miguel Mejía Suárez
    @BalmungSan
    @hindog hi, not really, you are right.
    But, it should be possible quite easily to fix that.
    Please, open an issue
    Aaron Hiniker
    @hindog
    will do, thanks
    Luis Miguel Mejía Suárez
    @BalmungSan
    Hi @masonedmison now that neotypes/neotypes#563 is ready
    I was planning to merge and release 0.23.0 soon. However, wanted to confirm first with you, because I would rather publish for Scala 3 before doing that.
    (BTW, any review in that PR would be welcome)
    Mason Lazalier Edmison
    @masonedmison
    @BalmungSan Hi. Sorry I haven't done much work on the scala3 support since my last post above. Assuming my first attempts at the generic and CypherStringInterpolator stuff is not totally off base, the remaining work to be done it to move the shapeless2 specific tests to a separate scala-2 directory. I can try to spend some time on this week in which case we might have something ready for review in the next week or two? Sorry this is taking so long btw.
    I'll try to peek that MR in the next day or two :)
    Luis Miguel Mejía Suárez
    @BalmungSan
    @masonedmison hey no worries, I didn't want to push rather to know the current state and maybe to know if I can help.
    I don't mind waiting a couple of days more, since I would rather publish Scala 3 support before dropping Java 8 and Java 11 support.
    But, also, I actually don't mind that much since I personally am already using Java 17 but no Scala 3.
    And based on the feedback from the issue it seems most folks using neotypes also don't have a problem upgrading Java
    Mason Lazalier Edmison
    @masonedmison
    @BalmungSan Sounds good. I will try to push my latest changes tomorrow and provide a more detailed to-do list in case you would like to help out a bit :).
    Luis Miguel Mejía Suárez
    @BalmungSan
    :D
    Luis Miguel Mejía Suárez
    @BalmungSan
    Oh, I forgot to mention here, sorry.
    @/all neotypes version 0.23.0 was released last weekend! It upgraded to the Java driver series 5 and thus requires Java 17.
    Luis Miguel Mejía Suárez
    @BalmungSan
    @/all neotypes version 0.23.1 was released! It upgraded to the Java driver to 5.3.0
    geoffjohn11
    @geoffjohn11
    :tada:
    Luis Miguel Mejía Suárez
    @BalmungSan

    Hi all, I have been working on something related to neotypes.
    I am calling the project Neotypes-Schema, and is basically a complete refactor of the decoders API from the current approach based on typeclasses (full implicit) into a combinators-based API which focuses on explicit with opt-in implicit derivation when useful (for example, to preserve a similar UX for simple use cases).
    As some may know, this is also my current Master's project.

    I am just starting with the real work, but I have an initial draft of how the API will look like here: https://gist.github.com/BalmungSan/075a7485163dce26ea5a7029ec6f9fcd
    In case anyone would like to give it a look and leave feedback, I would be very grateful.
    (PS: Sorry for the spanglish in the gist, is for my professor)

    Mason Lazalier Edmison
    @masonedmison
    @BalmungSan Sorry for ghosting regarding the scala 3 support. I have the next couple of days off and am hoping to at least get my first pass implementation working (with fixed and passing tests).
    Luis Miguel Mejía Suárez
    @BalmungSan
    @masonedmison hey no worries, I just hope it was just boring stuff like work raher than something serious :)
    BTW, since my work here neotypes/neotypes#584 will change a lot of things I don't recommend continue working on your PR
    Since all that work may get lost
    Unless we decide to merge yours first to make a Scala 3 release and then mine
    That was the original plan before I started working on that refactor
    But now, I think it would be best to tackle Scala 3 support after that
    However, I would appreciate a lot your input both in that as well as in my refactor