samurai

SAM-like syntax for scala 2.11

License

License

Categories

Categories

Scala Languages
GroupId

GroupId

io.scalaland
ArtifactId

ArtifactId

samurai_2.11
Last Version

Last Version

1.1
Release Date

Release Date

Type

Type

jar
Description

Description

samurai
SAM-like syntax for scala 2.11
Project Organization

Project Organization

io.scalaland
Source Code Management

Source Code Management

https://github.com/scalalandio/samurai

Download samurai_2.11

How to add to project

<!-- https://jarcasting.com/artifacts/io.scalaland/samurai_2.11/ -->
<dependency>
    <groupId>io.scalaland</groupId>
    <artifactId>samurai_2.11</artifactId>
    <version>1.1</version>
</dependency>
// https://jarcasting.com/artifacts/io.scalaland/samurai_2.11/
implementation 'io.scalaland:samurai_2.11:1.1'
// https://jarcasting.com/artifacts/io.scalaland/samurai_2.11/
implementation ("io.scalaland:samurai_2.11:1.1")
'io.scalaland:samurai_2.11:jar:1.1'
<dependency org="io.scalaland" name="samurai_2.11" rev="1.1">
  <artifact name="samurai_2.11" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.scalaland', module='samurai_2.11', version='1.1')
)
libraryDependencies += "io.scalaland" % "samurai_2.11" % "1.1"
[io.scalaland/samurai_2.11 "1.1"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.11.11
org.scala-lang : scala-reflect jar 2.11.11

test (1)

Group / Artifact Type Version
org.scalatest : scalatest_2.11 jar 3.0.3

Project Modules

There are no modules declared in this project.

Samurai

Build Status Maven Central License

SAM-like macro annotation for Scala

Note this project is experimental and probably doesn't cover all cases correctly.

You can use compiler-supported SAM even in Scala 2.11 with -Xexperimental flag.

This project will not be loger maintained.

Scala 2.12 introduced simplified syntax for defining instances of classes/traits that contain single abstract method. Considering following interface:

trait Show[T] {
  def show(x: T): String
}

Instead of

val intShow: Show[Int] = new Show[Int] {
  def show(x: Int): String = x.toString
}

we can simply write

val intShow: Show[Int] = (x: Int) => x.toString

Unfortunately, in Scala 2.11 such a syntax is not possible and for every type we have to either define separate helper function or live with this boilerplate. It's possible with -Xexperimental.

Samurai library defines macro annotation called @sam that brings this nice syntax also Scala 2.11.

Setup

You have to add following lines to your build.sbt:

libraryDependencies += "io.scalaland" %% "samurai" % "1.1" // triple %%% if you're on Scala.js

resolvers += Resolver.sonatypeRepo("releases")
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full)

Usage

Just prepend your val/def definitions with @sam annotation.

import samurai._
@sam val intShow: Show[Int] = (x: Int) => x.toString

This will expand in compile-time to the following piece of code:

val intShow: Show[Int] = new Show[Int] {
  def show(x: Int): String = x.toString
}

Advanced example

import samurai._
@sam implicit val intShow: Show[Int] = (x: Int) => x.toString
@sam implicit val intStr: Show[String] = (x: String) => x

@sam implicit def tupleInst[A: Show, B: Show]: Show[(A, B)] =
  (p: (A, B)) => s"(${implicitly[Show[A]].show(p._1)}, ${implicitly[Show[B]].show(p._2)})"

Last definition will be expanded to something similar to:

implicit def tupleInst[A, B](implicit s1: Show[A], s2: Show[B]): Show[(A, B)] = 
  new Show[(A, B)] {
    def show(s: (A, B)): String = s"(${s1.show(p._1)}, ${s2.show(p._2)})"
  }

Quirks

I observed that this approach might not work for every local type definition, because of the quirks of scala reflection API, so recommended approach is to define all your traits/abstract classes that you want to instantiate with @sam annotation as top-level ones.

Cross compilation

The library is cross-compiled on 2.11 and 2.12. On Scala 2.11 it performs real expansion described above, while on 2.12 it relies on native support provided by compiler, so it actually doesn't transform the original definition in any way.

io.scalaland

Scalaland.io

We have another fantastic day writing Scala

Versions

Version
1.1
1.0