enableIf.scala alternatives and similar packages
Based on the "Extensions" category.
Alternatively, view enableIf.scala alternatives based on common mentions on social networks and blogs.
-
cats
Lightweight, modular, and extensible library for functional programming. -
Cassovary
Cassovary is a simple big graph processing library for the JVM -
scala.meta
Library to read, analyze, transform and generate Scala programs -
Enumeratum
A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations. -
Scala-Logging
Convenient and performant logging library for Scala wrapping SLF4J. -
Chimney
Scala library for boilerplate-free, type-safe data transformations -
Simulacrum
First class syntax support for type classes in Scala -
Freestyle
A cohesive & pragmatic framework of FP centric Scala libraries -
tinylog
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android -
Scala Graph
Graph for Scala is intended to provide basic graph functionality seamlessly fitting into the Scala Collection Library. Like the well known members of scala.collection, Graph for Scala is an in-memory graph library aiming at editing and traversing graphs, finding cycles etc. in a user-friendly way. -
scribe
The fastest logging library in the world. Built from scratch in Scala and programmatically configurable. -
Each
A macro library that converts native imperative syntax to scalaz's monadic expressions -
Rapture
a collection of libraries for common, everyday programming tasks (I/O, JSON, i18n, etc.) -
Stateless Future
Asynchronous programming in fully featured Scala syntax. -
Scala Blitz
Scala framework for efficient sequential and data-parallel collections - -
Squid
Squid – type-safe metaprogramming and compilation framework for Scala -
Records for Scala
Labeled records for Scala based on structural refinement types and macros. -
Play monadic actions
A simple scala DSL to allow clean and monadic style for Play! Actions -
Lamma
Lamma schedule generator for Scala is a professional schedule generation library for periodic schedules like fixed income coupon payment, equity deravitive fixing date generation etc. -
Freasy Monad
Easy way to create Free Monad using Scala macros with first-class Intellij support. -
wvlet-log
A library for enhancing your application logs with colors and source code locations. -
Freedsl
Practical effect composition library based on abstract wrapping type and the free monad -
Resolvable
A library to optimize fetching immutable data structures from several endpoints in several formats.
Tired of breaking your main and manually rebasing outdated pull requests?
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of enableIf.scala or a related project?
README
enableIf.scala
enableIf.scala is a library that switches Scala code at compile-time, like #if
in C/C++.
Motivation
Suppose you want to create a library for both Scala 2.10 and Scala 2.11. When you implement the library, you may want to call the flatMap
method on TailRec
. However, the method does not exist on Scala 2.10.
With the help of this library, You can create your own implementation of flatMap
for Scala 2.10 target, and the Scala 2.11 target should still use the flatMap
method implemented by Scala standard library.
Usage
Step 1: Add the library dependency in your build.sbt
// Enable macro annotation by scalac flags for Scala 2.13
scalacOptions ++= {
import Ordering.Implicits._
if (VersionNumber(scalaVersion.value).numbers >= Seq(2L, 13L)) {
Seq("-Ymacro-annotations")
} else {
Nil
}
}
// Enable macro annotation by compiler plugins for Scala 2.12
libraryDependencies ++= {
import Ordering.Implicits._
if (VersionNumber(scalaVersion.value).numbers >= Seq(2L, 13L)) {
Nil
} else {
Seq(compilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full))
}
}
libraryDependencies += "com.thoughtworks.enableIf" %% "enableif" % "latest.release"
Step 2: Create an implicit class for Scala 2.10
import com.thoughtworks.enableIf
@enableIf(scala.util.Properties.versionNumberString.startsWith("2.10."))
implicit class FlatMapForTailRec[A](underlying: TailRec[A]) {
final def flatMap[B](f: A => TailRec[B]): TailRec[B] = {
tailcall(f(underlying.result))
}
}
The @enableIf
annotation accepts a Boolean
expression that indicates if the FlatMapForTailRec
definition should be compiled. The Boolean
expression is evaluated at compile-time instead of run-time.
Step 3: Call the flatMap
method on your TailRec
import scala.util.control.TailCalls._
def ten = done(10)
def tenPlusOne = ten.flatMap(i => done(i + 1))
assert(tenPlusOne.result == 11)
For Scala 2.10, the expression scala.util.Properties.versionNumberString.startsWith("2.10.")
is evaluated to true
, hence the FlatMapForTailRec
definition will be enabled. As a result, ten.flatMap
will call to flatMap
of the implicit class FlatMapForTailRec
.
For Scala 2.11, the expression scala.util.Properties.versionNumberString.startsWith("2.10.")
is evaluated to false
, hence the FlatMapForTailRec
definition will be disabled. As a result, ten.flatMap
will call the native TailRec.flatmap
.
Limitation
- The
enableIf
annotation does not work for top level traits, classes and objects. - The boolean condition been evaluated must refer
class
s orobject
s via fully quantified names from dependency libraries - The boolean condition been evaluated must not refer other
class
s orobject
s from the same library.
Enable different code for Scala.js and JVM targets
Suppose you want to create a Buffer-like collection, you may want create an ArrayBuffer
for JVM target, and the native js.Array
for Scala.js target.
/**
* Enable members in `Jvm` if no Scala.js plugin is found (i.e. Normal JVM target)
*/
@enableMembersIf(c => !c.compilerSettings.exists(_.matches("""^-Xplugin:.*scalajs-compiler_[0-9\.\-]*\.jar$""")))
private object Jvm {
def newBuffer[A] = collection.mutable.ArrayBuffer.empty[A]
}
/**
* Enable members in `Js` if a Scala.js plugin is found (i.e. Scala.js target)
*/
@enableMembersIf(c => c.compilerSettings.exists(_.matches("""^-Xplugin:.*scalajs-compiler_[0-9\.\-]*\.jar$""")))
private object Js {
@inline def newBuffer[A] = new scalajs.js.Array[A]
@inline implicit final class ReduceToSizeOps[A] @inline()(array: scalajs.js.Array[A]) {
@inline def reduceToSize(newSize: Int) = array.length = newSize
}
}
import Js._
import Jvm._
val optimizedBuffer = newBuffer[Int]
optimizedBuffer += 1
optimizedBuffer += 2
optimizedBuffer += 3
// resolved to native ArrayBuffer.reduceToSize for JVM, implicitly converted to ReduceToSizeOps for Scala.js
optimizedBuffer.reduceToSize(1)
You can define a c
parameter because the enableIf
annotation accepts either a Boolean
expression or a scala.reflect.macros.Context => Boolean
function. You can extract information from the macro context c
.