warning: Creating default object from empty value in /opt/bitnami/apps/portal/htdocs/modules/taxonomy/ on line 33.

user-land compiler warnings in Scala, part 2


Last week I wrote about #8820, my proposal to add user-land compiler warnings in Scala. The example I had was implementing ApiMayChange annotation. This was ok as a start, but a bit verbose. If we want some API status to be used frequently, it would be cool if library authors could define their own status annotation. We're going to look into doing that today.

user-land compiler warnings in Scala


As a library author, I've been wanting to tag methods in Scala that can trigger custom warnings or compiler errors. Why would I want to intentionally cause a compiler error? One potential use case is displaying a migration message for a removed API. A week ago, I sent #8820 to scala/scala proposing the idea of @apiStatus that enables user-land compiler warnings and errors.

equal protection under Eq law


The relationship given to Int and Long should be exactly the same as the relationship third-party library like Spire can write UInt or Rational with the first-class numeric types.

  • We should make 1 == 1L an error under strictEquality
  • We should allow custom types to participate in constant expression conversion using FromDigits

Giter8 0.12.0



I added a small app called giter8-launcher for Giter8 0.12.0. The purpose of the app is to make the behavior of the Giter8 template more predictable. Today, template authors may create a template for some version of Giter8 X, but the users might use some other version of Giter8 Y that ships with "sbt new."

Pamflet 0.8.2


Pamflet is a publishing application for short texts, particularly user documentation of open-source software.

Pamflet 0.8.2 updates its monospace typeface to SFMono, and undoes the incidental pink color that got introduced when I migrated from Blueprint to Bootstrap.

semantics of dependency resolvers


The semantics of a dependency resolver determine the concrete classpath based on the user-specified dependency constraints. Typically the differences in the details manifest as different way the version conflicts are resolved.

  • Maven uses nearest-wins strategy, which could downgrade transitive dependencies
  • Ivy uses latest-wins strategy
  • Coursier generally uses latest-wins strategy, but it's tries to enforce version range strictly
  • Ivy's version range handling goes to the Internet, which makes the build non-repeatable
  • Coursier orders version string completely differently from Ivy

Expecty 0.12.0 and 0.13.0


all your JDKs on Travis CI using SDKMAN!


This is a second post on installing your own JDKs on Travis CI. Previously I've written about jabba.

Today, let's look at SDKMAN!, an environment manager written by Marco Vermeulen (@marc0der) for JDKs and various tools on JVM, including Groovy, Spark, sbt, etc.

AdoptOpenJDK 11 and 8

Update 2019-11-06: Added sdkman_auto_selfupdate to workaround the update prompt blocking the CI. Also it adds || true on the sdk install line.

Pamflet 0.8.0


Over the holiday break I've implemented left TOC for Pamflet, and released it as Pamflet 0.8.0.

scopt 4


Here's how functional DSL looks like in scopt 4:

import scopt.OParser
val builder = OParser.builder[Config]
val parser1 = {
  import builder._
    head("scopt", "4.x"),
    // option -f, --foo
    opt[Int]('f', "foo")
      .action((x, c) => c.copy(foo = x))
      .text("foo is an integer property"),
    // more options here...
// OParser.parse returns Option[Config]
OParser.parse(parser1, args, Config()) match {
  case Some(config) =>
    // do something
  case _ =>
    // arguments are bad, error message will have been displayed

Instead of calling methods on OptionParser, the functional DSL first creates a builder based on your specific Config datatype, and calls opt[A](...) functions that returns OParser[A, Config].

These OParser[A, Config] parsers can be composed using OParser.sequence(...).

Syndicate content