Monocle icon indicating copy to clipboard operation
Monocle copied to clipboard

Mononcle doesn't support `@Lenses` in Scala3.

Open dev-jiwonyang opened this issue 2 years ago • 11 comments

I used @Lenses macro annotation in Scala2, but I can't find @Lenses in Monocle 3.1.0 with Scala3. Does anyone know anything about this issue? Does Monocle have any plan to support @Lenses in Scala3?

dev-jiwonyang avatar Jan 31 '23 05:01 dev-jiwonyang

Scala 3 doesn't support (yet) macro annotations such as @Lenses. Until such support is provided it won't be possible to support @Lenses

cquiroz avatar Mar 11 '23 14:03 cquiroz

Coming soon though!

  • https://github.com/lampepfl/dotty/pull/16392
  • https://github.com/lampepfl/dotty/pull/16454

armanbilge avatar Mar 11 '23 16:03 armanbilge

I am no expert, but following these PR's I'm under the impression this is still impossible under Scala3 post-typer Macro Annotations. I'm sure there will be other similar opportunities under the new Scala3 metaprogramming facilities, but in any case, Macro Annotations have been merged since 3.3.0-RC2 so hopefully we'll have a definitive answer soon.

nkgm avatar Apr 02 '23 11:04 nkgm

@nkgm correct. I think a more fruitful approach would actually be to lobby for inclusion in Scala proper. It doesn't mean including an optics library, just the following:

A. A case class or something basically of the form case class Field[A, B](get: A => B, set: B => A => A). Although I would like for it to also include name: String. B. Some syntax (e.g. a macro annotation or something else) that gets the compiler to generate a bunch of these for you

A macro that generates a single one would be very easy to write, so there's no need for them to special-case that.

Meanwhile, the recommended migration path is to use the focus macros instead. Although, I wonder if there's a performance effect, since lenses as fields would reuse the same instance.

nafg avatar Jun 09 '23 05:06 nafg

I think it's been enough time that we need to start looking into alternatives for folks to migrate.

Off the top of my head I know that simulacrum looked into using scalafix rules to do this.

yilinwei avatar Dec 21 '23 19:12 yilinwei

Maybe some way with named tuples?

Or like I said before, just start a pre-SIP.

Code gen seems dubious since it belongs in a companion. Unless I make the companions extend a trait that is generated.

The quick fix approach that was discussed on the forums might be interesting though.

nafg avatar Dec 21 '23 22:12 nafg

I was hoping to do the rewrite pre-compliation so it wouldn't be in your source tree; for all intents and purposes it would just allow the same source to be used for Scala 2/3.

What quick fix approach were you referencing?

yilinwei avatar Jan 02 '24 20:01 yilinwei

The idea discussed here: https://contributors.scala-lang.org/t/scala-3-macro-annotations-and-code-generation/6035

nafg avatar Jan 02 '24 21:01 nafg

How can code not in the source tree be part of the companion object of code that is

nafg avatar Jan 02 '24 21:01 nafg

Some build tools (dune from the OCaml ecosystem iirc) distinguish the source tree to the sources compiled by the compiler - the first step is to symlink the files into a target directory before compilation and run the compiler on those sources. Generated sources are also written directly to this directory and the compiler essentially runs on this folder.

In this build model, it's quite trivial to rewrite the sources before the compile step - I'm not entirely sure whether sbt or mill follows the same model. If it didn't, we could do something a little bit more involved where we filter the sources which use the trait and instead dump an edited source in the managedSources/generatedSources.

The idea would be to look for the @Lens marker trait and rewrite an existing companion object to add some extra lines of code to synthesize the required companion objects. That way, the semantics are the same for Scala 3/Scala 2 and it will ease migration until a better alternative emerges.

yilinwei avatar Jan 02 '24 21:01 yilinwei