Scala 2.10 and Continuations (akka-dataflow) in the sbt console - scala

What is the status of the continuations plugin in Scala 2.10; I'm slightly confused. The following setup is in the Akka 2.2-SNAPSHOT documentation:
autoCompilerPlugins := true,
libraryDependencies <+= scalaVersion {
v => compilerPlugin("org.scala-lang.plugins" % "continuations" % "2.10.0")
},
scalacOptions += "-P:continuations:enable",
First, the scalacOption doesn't work with 2.10 anymore, and the scalaVersion is not actually used in the library dependencies. If I naively go ahead with 2.10 and no special configurations (remove all of the above), and Akka 2.1.0:
import concurrent.ExecutionContext.Implicits.global
import akka.dataflow._
flow { "Hello world!" } onComplete println
I get an error indicating that the continuations plug-in is not enabled.
What what is the correct approach to enable continuations in Scala 2.10?
In particular: How can I drop into the sbt console and try out the above example with flow. It seems I also need to make sure the compiler plugin is enabled for the REPL?
EDIT: The scalacOptions entry does work, it seems I had a typo.

With this build.sbt:
autoCompilerPlugins := true
scalaVersion := "2.10.0"
libraryDependencies +=
compilerPlugin("org.scala-lang.plugins" % "continuations" % "2.10.0")
scalacOptions += "-P:continuations:enable"
the following continuations-only (no Akka) example works in the REPL:
scala> import scala.util.continuations._
scala> reset { val i = shift { body: (Int => Unit) => body(5);
| println("done") }; println(i) }

Related

is it necessary to add my custom scala library dependencies in new scala project?

I am new to Scala and I am trying to develop a small project which uses a custom library. I have created a mysql connection pool inside the library. Here's my build.sbt for library
organization := "com.learn"
name := "liblearn-scala"
version := "0.1"
scalaVersion := "2.12.6"
libraryDependencies += "mysql" % "mysql-connector-java" % "6.0.6"
libraryDependencies += "org.apache.tomcat" % "tomcat-dbcp" % "8.5.0"
I have published the same to local ivy repo using sbt publishLocal
Now I have a project which will be making use of the above library with following build.sbt
name := "SBT1"
version := "0.1"
scalaVersion := "2.12.6"
libraryDependencies += "com.learn" % "liblearn-scala_2.12" % "0.1"
I am able to compile the new project but when I run it I get
java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
But if I add
libraryDependencies += "mysql" % "mysql-connector-java" % "6.0.6"
libraryDependencies += "org.apache.tomcat" % "tomcat-dbcp" % "8.5.0"
in the project's build.sbt it works without any issues.
Is this the actual way of doing things with scala - sbt? ie : I have to mention dependencies of custom library also inside the project?
Here is my library code (I have just 1 file)
package com.learn.scala.db
import java.sql.Connection
import org.apache.tomcat.dbcp.dbcp2._
object MyMySQL {
private val dbUrl = s"jdbc:mysql://localhost:3306/school?autoReconnect=true"
private val connectionPool = new BasicDataSource()
connectionPool.setUsername("root")
connectionPool.setPassword("xyz")
connectionPool.setDriverClassName("com.mysql.cj.jdbc.Driver")
connectionPool.setUrl(dbUrl)
connectionPool.setInitialSize(3)
def getConnection: Connection = connectionPool.getConnection
}
This is my project code:
try {
val conn = MyMySQL.getConnection
val ps = conn.prepareStatement("select * from school")
val rs = ps.executeQuery()
while (rs.next()) {
print(rs.getString("name"))
print(rs.getString("rank"))
println("----------------------------------")
}
rs.close()
ps.close()
conn.close()
} catch {
case ex: Exception => {
println(ex.printStackTrace())
}
}
By default SBT fetches all project dependencies, transitively. This means it should be necessary to explicitly declare only liblearn-scala, and not also the transitive dependencies mysql-connector-java and tomcat-dbcp. Transitivity can be disabled, and transitive dependencies can be excluded, however unless this has been done explicitly, then it should not be the cause of the problem.
Without seeing your whole build.sbt, I believe you are doing the right thing. If sbt clean publishLocal is not solving the problem, you could try the nuclear option and clear the whole ivy cache (note this will force all projects to re-fetch dependencies).

Using .value in shared setting definition in SBT / Sane way to organize settings based on Scala version

I want to provide a multiple settings based on Scala binary version.
Those settings would be shared between several projects.
Something like:
lazy val akaneSettings = Def.settings(
organization := "ws.kotonoha",
moduleName := "akane",
crossScalaVersions := Seq("2.11.12", "2.12.4"),
scalaVersion := "2.11.12",
version := "0.2-SNAPSHOT",
javacOptions ++= Seq("-encoding", "utf8"),
scalacOptions ++= Seq(
"-feature",
"-deprecation"
),
scalaBinaryVersion.value match {
case "2.11" =>
Def.settings(
scalacOptions ++= Seq(
"-Ybackend:GenBCode",
"-Yopt:l:classpath",
"-Yopt-warnings",
"-target:jvm-1.8"
),
libraryDependencies ++= Seq("org.scala-lang.modules" % "scala-java8-compat_2.11" % "0.8.0")
)
case "2.12" =>
Def.settings(
scalacOptions ++= Seq(
"-opt:l:classpath"
)
)
case _ => throw new Exception("Not supported yet")
}
}
)
Unfortunately, the pattern match on .value does not work: it requires that I use it within a macro context.
Of course I can do the branching logic for each individual setting and use := / ++=, but that will leave a mess.
Is there a way to sanely organize groups of settings based on Scala version?
You need to move your conditional checks to inside the settings definitions, and not generate multiple settings from outside.
SBT's syntax might give the impression that you're updating values in a mutable fashion, such as by using the := operator, but you're not. Every single setting transformation is stored to be composed and applied later. At the point where akaneSettings is defined the value of scalaBinaryVersion is not known (and may actually be different depending on the context being evaluated).
Your example should look somewhat like:
// No need to use Def.Setting in recent SBT versions
lazy val akaneSettings = Seq(
organization := "ws.kotonoha",
// ...,
scalacOptions ++= {
scalaBinaryVersion.value match {
case "2.11" =>
Seq("-some-2.11-setting")
case "2.12" =>
Seq("-some-2.12-setting")
case _ =>
sys.error("Only Scala 2.11 and 2.12 are supported")
}
},
libraryDependencies ++= {
scalaBinaryVersion.value match {
case "2.11" =>
Seq("org.scala-lang.modules" % "scala-java8-compat_2.11" % "0.8.0")
case "2.12" =>
Seq.empty
case _ =>
sys.error("Only Scala 2.11 and 2.12 are supported")
}
}
}
You can create functions to generate your settings. For example:
def akaneSettings(scalaBinaryVersion: String) = Def.settings(
...
scalaBinaryVersion match {
...
}
)
... and then using it as akaneSettings(scalaBinaryVersion.value).

Macros annotation not working in IntelliJ14

I am having trouble using Scala Macros. It keeps on telling me to
enable macro paradise to expand macro annotations
from the #compileTimeOnly message I wrote. I followed all the instructions from Macro annotation documentation and the SBT example.
IDE: IntelliJ 14.1
Scala version: 2.11.7
Build.scala under the Project folder:
import sbt._
import sbt.Keys._
object Build extends Build {
val paradiseVersion = "2.1.0-M5"
lazy val sm = Project(id = "server-modules", base = file(".")).settings(
version := "1.0",
logLevel := Level.Warn,
scalacOptions ++= Seq(),
scalaVersion := "2.11.7",
crossScalaVersions := Seq("2.10.2", "2.10.3", "2.10.4", "2.10.5", "2.11.0", "2.11.1", "2.11.2", "2.11.3", "2.11.4", "2.11.5", "2.11.6", "2.11.7"),
resolvers += Resolver.sonatypeRepo("snapshots"),
resolvers += Resolver.sonatypeRepo("releases"),
addCompilerPlugin("org.scalamacros" % "paradise" % paradiseVersion cross CrossVersion.full),
libraryDependencies <+= (scalaVersion)("org.scala-lang" % "scala-reflect" % _),
)
}
Code:
#compileTimeOnly("enable macro paradise to expand macro annotations")
class dmCompile extends StaticAnnotation{
def macroTransform(annottees: Any*): Any = macro DMCompile.impl
}
object DMCompile {
def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
Log.info("Work work work!")
c.Expr(q"""var x = y""")
}
}
#dmCompile class Test{}
What exactly am I missing?
This took me the entire day, but I got it working.
Simply disregard the SBT settings for macros paradise and manually add it in the Preference -> Scala Compiler
That's it!
For me a solution was to change Incrementality type from IDEA to SBT in the Settings. This allows to use native SBT's build engine instead of IDEA's one.

Sbt 0.13 ScriptEngine is Null for getEngineByName(“scala”)

I have problem in using ScriptEngine from sbt 0.13.8
build.sbt
fork in run := true
scalaVersion := "2.11.6"
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % "2.11.6"
)
UseConfig.scala
object UseConfig {
def main(args: Array[String]) = {
import javax.script.ScriptEngineManager
val e = new ScriptEngineManager(null).getEngineByName("scala")
println(e)
}
}
and it prints null.
When I run a similar code in scala 2.11.6 console a scala engine is found successfully.
p.s. Is there are any other ways to compile dynamically scala code under sbt?

Shapeless example with map won't compile (scala)

I'm trying to map over an HList in shapeless. The following example is derived from here:
import shapeless._
import poly._
object Main {
def main(args: Array[String]) = {
object choose extends (Set ~> Option) {
def apply[T](s : Set[T]) = s.headOption
}
val sets = Set(1) :: Set("foo") :: HNil
val opts = sets map choose // map selects cases of choose for each HList element
}
}
Unfortunately I am unable to compile the example. The compiler says "value map is not a member of HCons[scala.collection.immutable.Set[Int],HCons[scala.collection.immutable.Set[String],HNil]]". I suspect there is a missing import of an implicit that defines the map operation on HLists, but I don't know what that import should be. I'm using sbt with the following build.sbt file:
name := "scala-polymorphism-experiments"
version := "0.1.0"
scalaVersion := "2.10.3"
resolvers ++= Seq(
"Sonatype OSS Releases" at "http://oss.sonatype.org/content/repositories/releases/",
"Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
)
libraryDependencies ++= Seq("org.scalatest" % "scalatest_2.10" % "2.0" % "test",
"com.chuusai" % "shapeless" % "2.0.0-SNAPSHOT" cross CrossVersion.full changing())
I also have this problem if I use the M1 release of 2.0.0. What should I change to make this example compile and run?
The problem was never determined. The solution was to comment out all code in all other scala files in the project, recompile, then uncomment and compile again. No doubt an
sbt clean
would have done just as well.