Hello folks,
How one can rewrite construct like this:
namedDBs.foreach(_() autoCommit { implicit session =>
...
}
in to Scala 3 syntax (I mean avoid to use implicit keyword). The code as is, is compiled by in Scala 3
Hello folks,
How one can rewrite construct like this:
namedDBs.foreach(_() autoCommit { implicit session =>
...
}
in to Scala 3 syntax (I mean avoid to use implicit keyword). The code as is, is compiled by in Scala 3
It depends on the type of the autoCommit. The idiomatic way in Scala 3 would be to define autocommit like this:
def autoCommit(body: Session ?=> Unit): Unit
?=>
is a context function type that takes an implicit paremeter of type Session
. One you have that your main code becomes simply
namedDBs.foreach: db =>
db().autoCommit:
... // a given of type Session is available here
The idea is that code passed to a parameter of context function type S ?=> T
will be expanded to a lambda that will get the S
implicitly. No need to write it out.
Assuming that you method signature is: def autoCommit[Ctx,R](fn: Ctx => R): R = ???
I don’t think there is currently a clean replacement for that, unless you’d rewrite the method signature itself as Martin suggests. One think that would work is
autoCommit( ctx =>
given Ctx = ctx
???
)
However, if I’d need to keep the original signature for any reasons I’d keep using implicit ctx => ???
It really reminds me one of recent changes to Scala Native to make it more Scala 3 idiomatic: nativelib: Make `Zone.apply` context-function based, add `Zone.acquire` for Scala2 compat by WojciechMazur · Pull Request #3752 · scala-native/scala-native · GitHub
Maybe some functions extensions similar to tupled
might be useful allowing to convert A => B
into A ?=> B
and other way around?
One way is to use pattern bound given instances:
autoCommit{ case given Session =>
???
}
Thanks @WojciechMazur and @Odersky for reply.
I can’t change the method signature, it is ScalikeJDBC API.
@WojciechMazur you guess signature very closely , and yes I can use your workaround, but it looks strange and is verbose.
@Odersky I understand point but I don’t understand what is the reason, that compiler do not allow just simply substitute implicit with given word in this case (all is pretty clear: scope of application and also source). It look pretty transparent and not damaging. Is there any reason to avoid using implicit as I used it now ? It going to be deprecated ?
In Scala 3, the type of a given is the one thing that matters. It must always be written explicitly. The name can be dropped. So implicit foo =>
is out, you’d at least have to write something like given foo: Foo =>
. But since we have already a better idiomatic solution with CFTs, there’s not need to complicate the syntax. The workarounds by @WojciechMazur and @markehammons are fine.