Open
Description
How'd you like them buzzwords.
Scala 3.2 added an experimental support for custom @main
annotations, see here: https://dotty.epfl.ch/docs/reference/experimental/main-annotation.html#
It would be excellent to experiment with a @ioMain
annotation (or even @io
?) in Cats Effect or any auxiliary project.
I went ahead and wrote a demonstrator to hwet your appetite:
//> using scala "3.3.1"
//> using lib "org.typelevel::cats-effect::3.5.3"
import scala.annotation.MainAnnotation
import scala.util.CommandLineParser.FromString
import scala.annotation.experimental
import cats.effect._
@experimental class ioMain extends MainAnnotation[FromString, IO[Unit]]:
import MainAnnotation.{Info, Parameter}
def command(info: Info, args: Seq[String]): Option[Seq[String]] =
Some(args)
def argGetter[T](
param: Parameter,
arg: String,
defaultArgument: Option[() => T]
)(using parser: FromString[T]): () => T =
() => parser.fromString(arg)
def varargGetter[T](param: Parameter, args: Seq[String])(using
parser: FromString[T]
): () => Seq[T] =
() => args.map(arg => parser.fromString(arg))
def run(program: () => IO[Unit]): Unit =
val app = new IOApp.Simple {
def run = program()
}
app.main(Array.empty)
end ioMain
@experimental
@ioMain def sum(first: Int, second: Int, rest: Int*) =
IO.println(first + second + rest.sum)
Run this program with Scala CLI:
$ scli ioMain.scala -- 25 16 100 50
Once the annotation design exits experimental
phase, users should just be able to do
@ioMain def sum(first: Int, second: Int, rest: Int*) =
IO.println(first + second + rest.sum)
And enjoy that deliciously non-invasive experience.