Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What are the hidden features of Scala that every Scala developer should be aware of?
One hidden feature per answer, please.
Okay, I had to add one more. Every Regex object in Scala has an extractor (see answer from oxbox_lakes above) that gives you access to the match groups. So you can do something like:
// Regex to split a date in the format Y/M/D.
val regex = "(\\d+)/(\\d+)/(\\d+)".r
val regex(year, month, day) = "2010/1/13"
The second line looks confusing if you're not used to using pattern matching and extractors. Whenever you define a val or var, what comes after the keyword is not simply an identifier but rather a pattern. That's why this works:
val (a, b, c) = (1, 3.14159, "Hello, world")
The right hand expression creates a Tuple3[Int, Double, String] which can match the pattern (a, b, c).
Most of the time your patterns use extractors that are members of singleton objects. For example, if you write a pattern like
Some(value)
then you're implicitly calling the extractor Some.unapply.
But you can also use class instances in patterns, and that is what's happening here. The val regex is an instance of Regex, and when you use it in a pattern, you're implicitly calling regex.unapplySeq (unapply versus unapplySeq is beyond the scope of this answer), which extracts the match groups into a Seq[String], the elements of which are assigned in order to the variables year, month, and day.
Structural type definitions - i.e. a type described by what methods it supports. For example:
object Closer {
def using(closeable: { def close(): Unit }, f: => Unit) {
try {
f
} finally { closeable.close }
}
}
Notice that the type of the parameter closeable is not defined other than it has a close method
Type-Constructor Polymorphism (a.k.a. higher-kinded types)
Without this feature you can, for example, express the idea of mapping a function over a list to return another list, or mapping a function over a tree to return another tree. But you can't express this idea generally without higher kinds.
With higher kinds, you can capture the idea of any type that's parameterised with another type. A type constructor that takes one parameter is said to be of kind (*->*). For example, List. A type constructor that returns another type constructor is said to be of kind (*->*->*). For example, Function1. But in Scala, we have higher kinds, so we can have type constructors that are parameterised with other type constructors. So they're of kinds like ((*->*)->*).
For example:
trait Functor[F[_]] {
def fmap[A, B](f: A => B, fa: F[A]): F[B]
}
Now, if you have a Functor[List], you can map over lists. If you have a Functor[Tree], you can map over trees. But more importantly, if you have Functor[A] for any A of kind (*->*), you can map a function over A.
Extractors which allow you to replace messy if-elseif-else style code with patterns. I know that these are not exactly hidden but I've been using Scala for a few months without really understanding the power of them. For (a long) example I can replace:
val code: String = ...
val ps: ProductService = ...
var p: Product = null
if (code.endsWith("=")) {
p = ps.findCash(code.substring(0, 3)) //e.g. USD=, GBP= etc
}
else if (code.endsWith(".FWD")) {
//e.g. GBP20090625.FWD
p = ps.findForward(code.substring(0,3), code.substring(3, 9))
}
else {
p = ps.lookupProductByRic(code)
}
With this, which is much clearer in my opinion
implicit val ps: ProductService = ...
val p = code match {
case SyntheticCodes.Cash(c) => c
case SyntheticCodes.Forward(f) => f
case _ => ps.lookupProductByRic(code)
}
I have to do a bit of legwork in the background...
object SyntheticCodes {
// Synthetic Code for a CashProduct
object Cash extends (CashProduct => String) {
def apply(p: CashProduct) = p.currency.name + "="
//EXTRACTOR
def unapply(s: String)(implicit ps: ProductService): Option[CashProduct] = {
if (s.endsWith("=")
Some(ps.findCash(s.substring(0,3)))
else None
}
}
//Synthetic Code for a ForwardProduct
object Forward extends (ForwardProduct => String) {
def apply(p: ForwardProduct) = p.currency.name + p.date.toString + ".FWD"
//EXTRACTOR
def unapply(s: String)(implicit ps: ProductService): Option[ForwardProduct] = {
if (s.endsWith(".FWD")
Some(ps.findForward(s.substring(0,3), s.substring(3, 9))
else None
}
}
But the legwork is worth it for the fact that it separates a piece of business logic into a sensible place. I can implement my Product.getCode methods as follows..
class CashProduct {
def getCode = SyntheticCodes.Cash(this)
}
class ForwardProduct {
def getCode = SyntheticCodes.Forward(this)
}
Manifests which are a sort of way at getting the type information at runtime, as if Scala had reified types.
In scala 2.8 you can have tail-recursive methods by using the package scala.util.control.TailCalls (in fact it's trampolining).
An example:
def u(n:Int):TailRec[Int] = {
if (n==0) done(1)
else tailcall(v(n/2))
}
def v(n:Int):TailRec[Int] = {
if (n==0) done(5)
else tailcall(u(n-1))
}
val l=for(n<-0 to 5) yield (n,u(n).result,v(n).result)
println(l)
Case classes automatically mixin the Product trait, providing untyped, indexed access to the fields without any reflection:
case class Person(name: String, age: Int)
val p = Person("Aaron", 28)
val name = p.productElement(0) // name = "Aaron": Any
val age = p.productElement(1) // age = 28: Any
val fields = p.productIterator.toList // fields = List[Any]("Aaron", 28)
This feature also provides a simplified way to alter the output of the toString method:
case class Person(name: String, age: Int) {
override def productPrefix = "person: "
}
// prints "person: (Aaron,28)" instead of "Person(Aaron, 28)"
println(Person("Aaron", 28))
It's not exactly hidden, but certainly a under advertised feature: scalac -Xprint.
As a illustration of the use consider the following source:
class A { "xx".r }
Compiling this with scalac -Xprint:typer outputs:
package <empty> {
class A extends java.lang.Object with ScalaObject {
def this(): A = {
A.super.this();
()
};
scala.this.Predef.augmentString("xx").r
}
}
Notice scala.this.Predef.augmentString("xx").r, which is a the application of the implicit def augmentString present in Predef.scala.
scalac -Xprint:<phase> will print the syntax tree after some compiler phase. To see the available phases use scalac -Xshow-phases.
This is a great way to learn what is going on behind the scenes.
Try with
case class X(a:Int,b:String)
using the typer phase to really feel how useful it is.
You can define your own control structures. It's really just functions and objects and some syntactic sugar, but they look and behave like the real thing.
For example, the following code defines dont {...} unless (cond) and dont {...} until (cond):
def dont(code: => Unit) = new DontCommand(code)
class DontCommand(code: => Unit) {
def unless(condition: => Boolean) =
if (condition) code
def until(condition: => Boolean) = {
while (!condition) {}
code
}
}
Now you can do the following:
/* This will only get executed if the condition is true */
dont {
println("Yep, 2 really is greater than 1.")
} unless (2 > 1)
/* Just a helper function */
var number = 0;
def nextNumber() = {
number += 1
println(number)
number
}
/* This will not be printed until the condition is met. */
dont {
println("Done counting to 5!")
} until (nextNumber() == 5)
#switch annotation in Scala 2.8:
An annotation to be applied to a match
expression. If present, the compiler
will verify that the match has been
compiled to a tableswitch or
lookupswitch, and issue an error if it
instead compiles into a series of
conditional expressions.
Example:
scala> val n = 3
n: Int = 3
scala> import annotation.switch
import annotation.switch
scala> val s = (n: #switch) match {
| case 3 => "Three"
| case _ => "NoThree"
| }
<console>:6: error: could not emit switch for #switch annotated match
val s = (n: #switch) match {
Dunno if this is really hidden, but I find it quite nice.
Typeconstructors that take 2 type parameters can be written in infix notation
object Main {
class FooBar[A, B]
def main(args: Array[String]): Unit = {
var x: FooBar[Int, BigInt] = null
var y: Int FooBar BigInt = null
}
}
Scala 2.8 introduced default and named arguments, which made possible the addition of a new "copy" method that Scala adds to case classes. If you define this:
case class Foo(a: Int, b: Int, c: Int, ... z:Int)
and you want to create a new Foo that's like an existing Foo, only with a different "n" value, then you can just say:
foo.copy(n = 3)
in scala 2.8 you can add #specialized to your generic classes/methods. This will create special versions of the class for primitive types (extending AnyVal) and save the cost of un-necessary boxing/unboxing :
class Foo[#specialized T]...
You can select a subset of AnyVals :
class Foo[#specialized(Int,Boolean) T]...
Extending the language. I always wanted to do something like this in Java (couldn't). But in Scala I can have:
def timed[T](thunk: => T) = {
val t1 = System.nanoTime
val ret = thunk
val time = System.nanoTime - t1
println("Executed in: " + time/1000000.0 + " millisec")
ret
}
and then write:
val numbers = List(12, 42, 3, 11, 6, 3, 77, 44)
val sorted = timed { // "timed" is a new "keyword"!
numbers.sortWith(_<_)
}
println(sorted)
and get
Executed in: 6.410311 millisec
List(3, 3, 6, 11, 12, 42, 44, 77)
You can designate a call-by-name parameter (EDITED: this is different then a lazy parameter!) to a function and it will not be evaluated until used by the function (EDIT: in fact, it will be reevaluated every time it is used). See this faq for details
class Bar(i:Int) {
println("constructing bar " + i)
override def toString():String = {
"bar with value: " + i
}
}
// NOTE the => in the method declaration. It indicates a lazy paramter
def foo(x: => Bar) = {
println("foo called")
println("bar: " + x)
}
foo(new Bar(22))
/*
prints the following:
foo called
constructing bar 22
bar with value: 22
*/
You can use locally to introduce a local block without causing semicolon inference issues.
Usage:
scala> case class Dog(name: String) {
| def bark() {
| println("Bow Vow")
| }
| }
defined class Dog
scala> val d = Dog("Barnie")
d: Dog = Dog(Barnie)
scala> locally {
| import d._
| bark()
| bark()
| }
Bow Vow
Bow Vow
locally is defined in "Predef.scala" as:
#inline def locally[T](x: T): T = x
Being inline, it does not impose any additional overhead.
Early Initialization:
trait AbstractT2 {
println("In AbstractT2:")
val value: Int
val inverse = 1.0/value
println("AbstractT2: value = "+value+", inverse = "+inverse)
}
val c2c = new {
// Only initializations are allowed in pre-init. blocks.
// println("In c2c:")
val value = 10
} with AbstractT2
println("c2c.value = "+c2c.value+", inverse = "+c2c.inverse)
Output:
In AbstractT2:
AbstractT2: value = 10, inverse = 0.1
c2c.value = 10, inverse = 0.1
We instantiate an anonymous inner
class, initializing the value field
in the block, before the with
AbstractT2 clause. This guarantees
that value is initialized before the
body of AbstractT2 is executed, as
shown when you run the script.
You can compose structural types with the 'with' keyword
object Main {
type A = {def foo: Unit}
type B = {def bar: Unit}
type C = A with B
class myA {
def foo: Unit = println("myA.foo")
}
class myB {
def bar: Unit = println("myB.bar")
}
class myC extends myB {
def foo: Unit = println("myC.foo")
}
def main(args: Array[String]): Unit = {
val a: A = new myA
a.foo
val b: C = new myC
b.bar
b.foo
}
}
placeholder syntax for anonymous functions
From The Scala Language Specification:
SimpleExpr1 ::= '_'
An expression (of syntactic category Expr) may contain embedded underscore symbols _ at places where identifiers are legal. Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters.
From Scala Language Changes:
_ + 1 x => x + 1
_ * _ (x1, x2) => x1 * x2
(_: Int) * 2 (x: Int) => x * 2
if (_) x else y z => if (z) x else y
_.map(f) x => x.map(f)
_.map(_ + 1) x => x.map(y => y + 1)
Using this you could do something like:
def filesEnding(query: String) =
filesMatching(_.endsWith(query))
Implicit definitions, particularly conversions.
For example, assume a function which will format an input string to fit to a size, by replacing the middle of it with "...":
def sizeBoundedString(s: String, n: Int): String = {
if (n < 5 && n < s.length) throw new IllegalArgumentException
if (s.length > n) {
val trailLength = ((n - 3) / 2) min 3
val headLength = n - 3 - trailLength
s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
} else s
}
You can use that with any String, and, of course, use the toString method to convert anything. But you could also write it like this:
def sizeBoundedString[T](s: T, n: Int)(implicit toStr: T => String): String = {
if (n < 5 && n < s.length) throw new IllegalArgumentException
if (s.length > n) {
val trailLength = ((n - 3) / 2) min 3
val headLength = n - 3 - trailLength
s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
} else s
}
And then, you could pass classes of other types by doing this:
implicit def double2String(d: Double) = d.toString
Now you can call that function passing a double:
sizeBoundedString(12345.12345D, 8)
The last argument is implicit, and is being passed automatically because of the implicit de declaration. Furthermore, "s" is being treated like a String inside sizeBoundedString because there is an implicit conversion from it to String.
Implicits of this type are better defined for uncommon types to avoid unexpected conversions. You can also explictly pass a conversion, and it will still be implicitly used inside sizeBoundedString:
sizeBoundedString(1234567890L, 8)((l : Long) => l.toString)
You can also have multiple implicit arguments, but then you must either pass all of them, or not pass any of them. There is also a shortcut syntax for implicit conversions:
def sizeBoundedString[T <% String](s: T, n: Int): String = {
if (n < 5 && n < s.length) throw new IllegalArgumentException
if (s.length > n) {
val trailLength = ((n - 3) / 2) min 3
val headLength = n - 3 - trailLength
s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
} else s
}
This is used exactly the same way.
Implicits can have any value. They can be used, for instance, to hide library information. Take the following example, for instance:
case class Daemon(name: String) {
def log(msg: String) = println(name+": "+msg)
}
object DefaultDaemon extends Daemon("Default")
trait Logger {
private var logd: Option[Daemon] = None
implicit def daemon: Daemon = logd getOrElse DefaultDaemon
def logTo(daemon: Daemon) =
if (logd == None) logd = Some(daemon)
else throw new IllegalArgumentException
def log(msg: String)(implicit daemon: Daemon) = daemon.log(msg)
}
class X extends Logger {
logTo(Daemon("X Daemon"))
def f = {
log("f called")
println("Stuff")
}
def g = {
log("g called")(DefaultDaemon)
}
}
class Y extends Logger {
def f = {
log("f called")
println("Stuff")
}
}
In this example, calling "f" in an Y object will send the log to the default daemon, and on an instance of X to the Daemon X daemon. But calling g on an instance of X will send the log to the explicitly given DefaultDaemon.
While this simple example can be re-written with overload and private state, implicits do not require private state, and can be brought into context with imports.
Maybe not too hidden, but I think this is useful:
#scala.reflect.BeanProperty
var firstName:String = _
This will automatically generate a getter and setter for the field that matches bean convention.
Further description at developerworks
Implicit arguments in closures.
A function argument can be marked as implicit just as with methods. Within the scope of the body of the function the implicit parameter is visible and eligible for implicit resolution:
trait Foo { def bar }
trait Base {
def callBar(implicit foo: Foo) = foo.bar
}
object Test extends Base {
val f: Foo => Unit = { implicit foo =>
callBar
}
def test = f(new Foo {
def bar = println("Hello")
})
}
Build infinite data structures with Scala's Streams :
http://www.codecommit.com/blog/scala/infinite-lists-for-the-finitely-patient
Result types are dependent on implicit resolution. This can give you a form of multiple dispatch:
scala> trait PerformFunc[A,B] { def perform(a : A) : B }
defined trait PerformFunc
scala> implicit val stringToInt = new PerformFunc[String,Int] {
def perform(a : String) = 5
}
stringToInt: java.lang.Object with PerformFunc[String,Int] = $anon$1#13ccf137
scala> implicit val intToDouble = new PerformFunc[Int,Double] {
def perform(a : Int) = 1.0
}
intToDouble: java.lang.Object with PerformFunc[Int,Double] = $anon$1#74e551a4
scala> def foo[A, B](x : A)(implicit z : PerformFunc[A,B]) : B = z.perform(x)
foo: [A,B](x: A)(implicit z: PerformFunc[A,B])B
scala> foo("HAI")
res16: Int = 5
scala> foo(1)
res17: Double = 1.0
Scala's equivalent of Java double brace initializer.
Scala allows you to create an anonymous subclass with the body of the class (the constructor) containing statements to initialize the instance of that class.
This pattern is very useful when building component-based user interfaces (for example Swing , Vaadin) as it allows to create UI components and declare their properties more concisely.
See http://spot.colorado.edu/~reids/papers/how-scala-experience-improved-our-java-development-reid-2011.pdf for more information.
Here is an example of creating a Vaadin button:
val button = new Button("Click me"){
setWidth("20px")
setDescription("Click on this")
setIcon(new ThemeResource("icons/ok.png"))
}
Excluding members from import statements
Suppose you want to use a Logger that contains a println and a printerr method, but you only want to use the one for error messages, and keep the good old Predef.println for standard output. You could do this:
val logger = new Logger(...)
import logger.printerr
but if logger also contains another twelve methods that you would like to import and use, it becomes inconvenient to list them. You could instead try:
import logger.{println => donotuseprintlnt, _}
but this still "pollutes" the list of imported members. Enter the über-powerful wildcard:
import logger.{println => _, _}
and that will do just the right thing™.
require method (defined in Predef) that allow you to define additional function constraints that would be checked during run-time. Imagine that you developing yet another twitter client and you need to limit tweet length up to 140 symbols. Moreover you can't post empty tweet.
def post(tweet: String) = {
require(tweet.length < 140 && tweet.length > 0)
println(tweet)
}
Now calling post with inappropriate length argument will cause an exception:
scala> post("that's ok")
that's ok
scala> post("")
java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:145)
at .post(<console>:8)
scala> post("way to looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong tweet")
java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:145)
at .post(<console>:8)
You can write multiple requirements or even add description to each:
def post(tweet: String) = {
require(tweet.length > 0, "too short message")
require(tweet.length < 140, "too long message")
println(tweet)
}
Now exceptions are verbose:
scala> post("")
java.lang.IllegalArgumentException: requirement failed: too short message
at scala.Predef$.require(Predef.scala:157)
at .post(<console>:8)
One more example is here.
Bonus
You can perform an action every time requirement fails:
scala> var errorcount = 0
errorcount: Int = 0
def post(tweet: String) = {
require(tweet.length > 0, {errorcount+=1})
println(tweet)
}
scala> errorcount
res14: Int = 0
scala> post("")
java.lang.IllegalArgumentException: requirement failed: ()
at scala.Predef$.require(Predef.scala:157)
at .post(<console>:9)
...
scala> errorcount
res16: Int = 1
Traits with abstract override methods are a feature in Scala that is as not widely advertised as many others. The intend of methods with the abstract override modifier is to do some operations and delegating the call to super. Then these traits have to be mixed-in with concrete implementations of their abstract override methods.
trait A {
def a(s : String) : String
}
trait TimingA extends A {
abstract override def a(s : String) = {
val start = System.currentTimeMillis
val result = super.a(s)
val dur = System.currentTimeMillis-start
println("Executed a in %s ms".format(dur))
result
}
}
trait ParameterPrintingA extends A {
abstract override def a(s : String) = {
println("Called a with s=%s".format(s))
super.a(s)
}
}
trait ImplementingA extends A {
def a(s: String) = s.reverse
}
scala> val a = new ImplementingA with TimingA with ParameterPrintingA
scala> a.a("a lotta as")
Called a with s=a lotta as
Executed a in 0 ms
res4: String = sa attol a
While my example is really not much more than a poor mans AOP, I used these Stackable Traits much to my liking to build Scala interpreter instances with predefined imports, custom bindings and classpathes. The Stackable Traits made it possible to create my factory along the lines of new InterpreterFactory with JsonLibs with LuceneLibs and then have useful imports and scope varibles for the users scripts.
Related
How to override equals to check value equivalence of functions in specific cases? For example, say we have the following f and g functions
val f = (x: Int) => "worf" + x
val g = (x: Int) => "worf" + x
How could we make assert(f == g) pass?
I tried extending Function1 and implemented equality via generator like so
trait Function1Equals extends (Int => String) {
override def equals(obj: Any): Boolean = {
val b = obj.asInstanceOf[Function1Equals]
(1 to 100).forall { _ =>
val input = scala.util.Random.nextInt
apply(input) == b(input)
}
}
}
implicit def functionEquality(f: Int => String): Function1Equals = (x: Int) => f(x)
but could not get implicit conversion to work on == perhaps due to this. Scalactics's TripleEquals comes close
import org.scalactic.TripleEquals._
import org.scalactic.Equality
implicit val functionEquality = new Equality[Int => String] {
override def areEqual(a: Int => String, b: Any): Boolean =
b match {
case p: (Int => String) =>
(1 to 100).forall { _ =>
val input = scala.util.Random.nextInt
a(input) == p(input)
}
case _ => false
}
}
val f = (x: Int) => "worf" + x
val g = (x: Int) => "worf" + x
val h = (x: Int) => "picard" + x
assert(f === g) // pass
assert(f === h) // fail
How would you go about implementing equality of functions, preferably using regular ==?
First of all, function equality is not a simple topic (spoiler: it cannot be implemented correctly; see e.g. this question and the corresponding answer), but let's assume that your method of "asserting same output for a hundred random inputs" is good enough.
The problem with overriding == is that it's already implemented for Function1 instances. So you have two options:
define a custom trait (your approach) and use ==
define a typeclass with operation isEqual and implement it for Function1
Both options have trade-offs.
In the first case, instead of using standard Scala Function1 trait, you have to wrap each function into your custom trait instead. You did that, but then you tried to implement an implicit conversion that will do the conversion from standard Function1 to Function1Equals for you "behind the scenes". But as you realised yourself, that cannot work. Why? Because there already exists a method == for Function1 instances, so there's no reason for the compiler to kick off the implicit conversion. You have to wrap each Function1 instance into your custom wrapper so that the overridden == gets called.
Here's the example code:
trait MyFunction extends Function1[Int, String] {
override def apply(a: Int): String
override def equals(obj: Any) = {
val b = obj.asInstanceOf[MyFunction]
(1 to 100).forall { _ =>
val input = scala.util.Random.nextInt
apply(input) == b(input)
}
}
}
val f = new MyFunction {
override def apply(x: Int) = "worf" + x
}
val g = new MyFunction {
override def apply(x: Int) = "worf" + x
}
val h = new MyFunction {
override def apply(x: Int) = "picard" + x
}
assert(f == g) // pass
assert(f == h) // fail
Your second option is to keep working with standard Function1 instances, but to use a custom method for equality comparison. This can be easily implemented with a typeclass approach:
define a generic trait MyEquals[A] which will have the needed method (let's call it isEqual)
define an implicit value which implements that trait for Function1[Int, String]
define a helper implicit class which will provide the method isEqual for some value of type A as long as there exists an implicit implementation of MyEquals[A] (and we made sure in the previous step that there is one for MyEquals[Function1[Int, String]])
Then the code looks like this:
trait MyEquals[A] {
def isEqual(a1: A, a2: A): Boolean
}
implicit val function1EqualsIntString = new MyEquals[Int => String] {
def isEqual(f1: Int => String, f2: Int => String) =
(1 to 100).forall { _ =>
val input = scala.util.Random.nextInt
f1(input) == f2(input)
}
}
implicit class MyEqualsOps[A: MyEquals](a1: A) {
def isEqual(a2: A) = implicitly[MyEquals[A]].isEqual(a1, a2)
}
val f = (x: Int) => "worf" + x
val g = (x: Int) => "worf" + x
val h = (x: Int) => "picard" + x
assert(f isEqual g) // pass
assert(f isEqual h) // fail
But as I said, keeping the advantages of first approach (using ==) and second approach (using standard Function1 trait) is not possible. I would argue however that using == isn't even an advantage. Read on to find out why.
This is a good demonstration of why typeclasses are useful and more powerful than inheritance. Instead of inheriting == from some superclass object and overriding it, which is problematic for types we cannot modify (such as Function1), there should instead be a typeclass (let's call it Equal) which provides the equality method for a lot of types.
So if an implicit instance of Equal[Function1] doesn't already exist in the scope, we simply provide our own (like we did in my second snippet) and the compiler will use it. On the other hand, if an implicit instance of Equal[Function1] already does exist somewhere (e.g. in the standard library), it changes nothing for us - we still simply need to provide our own, and it will "override" the existing one.
And now the best part: such typeclass already exists in both scalaz and cats. It is called Equal and Eq respectively, and they both named their equality comparison method ===. This is why I said earlier that I wouldn't even consider being able to use == as an advantage. Who needs == anyway? :) Using scalaz or cats in your codebase consistently would mean that you would rely on === instead of == everywhere, and your life would be simple(r).
But don't count on function equality; that whole requirement is weird and not good. I answered your question pretending that it's fine in order to provide some insights, but the best answer would have been - don't rely on function equality at all.
I am currently reading Hutton's and Meijer's paper on parsing combinators in Haskell http://www.cs.nott.ac.uk/~pszgmh/monparsing.pdf. For the sake of it I am trying to implement them in scala. I would like to construct something easy to code, extend and also simple and elegant. I have come up with two solutions for the following haskell code
/* Haskell Code */
type Parser a = String -> [(a,String)]
result :: a -> Parser a
result v = \inp -> [(v,inp)]
zero :: Parser a
zero = \inp -> []
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
/* Scala Code */
object Hutton1 {
type Parser[A] = String => List[(A, String)]
def Result[A](v: A): Parser[A] = str => List((v, str))
def Zero[A]: Parser[A] = str => List()
def Character: Parser[Char] = str => if (str.isEmpty) List() else List((str.head, str.tail))
}
object Hutton2 {
trait Parser[A] extends (String => List[(A, String)])
case class Result[A](v: A) extends Parser[A] {
def apply(str: String) = List((v, str))
}
case object Zero extends Parser[T forSome {type T}] {
def apply(str: String) = List()
}
case object Character extends Parser[Char] {
def apply(str: String) = if (str.isEmpty) List() else List((str.head, str.tail))
}
}
object Hutton extends App {
object T1 {
import Hutton1._
def run = {
val r: List[(Int, String)] = Zero("test") ++ Result(5)("test")
println(r.map(x => x._1 + 1) == List(6))
println(Character("abc") == List(('a', "bc")))
}
}
object T2 {
import Hutton2._
def run = {
val r: List[(Int, String)] = Zero("test") ++ Result(5)("test")
println(r.map(x => x._1 + 1) == List(6))
println(Character("abc") == List(('a', "bc")))
}
}
T1.run
T2.run
}
Question 1
In Haskell, zero is a function value that can be used as it is, expessing all failed parsers whether they are of type Parser[Int] or Parser[String]. In scala we achieve the same by calling the function Zero (1st approach) but in this way I believe that I just generate a different function everytime Zero is called. Is this statement true? Is there a way to mitigate this?
Question 2
In the second approach, the Zero case object is extending Parser with the usage of existential types Parser[T forSome {type T}] . If I replace the type with Parser[_] I get the compile error
Error:(19, 28) class type required but Hutton2.Parser[_] found
case object Zero extends Parser[_] {
^
I thought these two expressions where equivalent. Is this the case?
Question 3
Which approach out of the two do you think that will yield better results in expressing the combinators in terms of elegance and simplicity?
I use scala 2.11.8
Note: I didn't compile it, but I know the problem and can propose two solutions.
The more Haskellish way would be to not use subtyping, but to define zero as a polymorphic value. In that style, I would propose to define parsers not as objects deriving from a function type, but as values of one case class:
final case class Parser[T](run: String => List[(T, String)])
def zero[T]: Parser[T] = Parser(...)
As shown by #Alec, yes, this will produce a new value every time, since a def is compiled to a method.
If you want to use subtyping, you need to make Parser covariant. Then you can give zero a bottom result type:
trait Parser[+A] extends (String => List[(A, String)])
case object Zero extends Parser[Nothing] {...}
These are in some way quite related; in system F_<:, which is the base of what Scala uses, the types _|_ (aka Nothing) and \/T <: Any. T behave the same (this hinted at in Types and Programming Languages, chapter 28). The two possibilities given here are a consequence of this fact.
With existentials I'm not so familiar with, but I think that while unbounded T forSome {type T} will behave like Nothing, Scala does not allow inhertance from an existential type.
Question 1
I think that you are right, and here is why: Zero1 below prints hello every time you use it. The solution, Zero2, involves using a val instead.
def Zero1[A]: Parser[A] = { println("hi"); str => List() }
val Zero2: Parser[Nothing] = str => List()
Question 2
No idea. I'm still just starting out with Scala. Hope someone answers this.
Question 3
The trait one will play better with Scala's for (since you can define custom flatMap and map), which turns out to be (somewhat) like Haskell's do. The following is all you need.
trait Parser[A] extends (String => List[(A, String)]) {
def flatMap[B](f: A => Parser[B]): Parser[B] = {
val p1 = this
new Parser[B] {
def apply(s1: String) = for {
(a,s2) <- p1(s1)
p2 = f(a)
(b,s3) <- p2(s2)
} yield (b,s3)
}
}
def map[B](f: A => B): Parser[B] = {
val p = this
new Parser[B] {
def apply(s1: String) = for ((a,s2) <- p(s1)) yield (f(a),s2)
}
}
}
Of course, to do anything interesting you need more parsers. I'll propose to you one simple parser combinator: Choice(p1: Parser[A], p2: Parser[A]): Parser[A] which tries both parsers. (And rewrite your existing parsers more to my style).
def choice[A](p1: Parser[A], p2: Parser[A]): Parser[A] = new Parser[A] {
def apply(s: String): List[(A,String)] = { p1(s) ++ p2(s) }
}
def unit[A](x: A): Parser[A] = new Parser[A] {
def apply(s: String): List[(A,String)] = List((x,s))
}
val character: Parser[Char] = new Parser[Char] {
def apply(s: String): List[(Char,String)] = List((s.head,s.tail))
}
Then, you can write something like the following:
val parser: Parser[(Char,Char)] = for {
x <- choice(unit('x'),char)
y <- char
} yield (x,y)
And calling parser("xyz") gives you List((('x','x'),"yz"), (('x','y'),"z")).
When programming in java, I always log input parameter and return value of a method, but in scala, the last line of a method is the return value. so I have to do something like:
def myFunc() = {
val rs = calcSomeResult()
logger.info("result is:" + rs)
rs
}
in order to make it easy, I write a utility:
class LogUtil(val f: (String) => Unit) {
def logWithValue[T](msg: String, value: T): T = { f(msg); value }
}
object LogUtil {
def withValue[T](f: String => Unit): ((String, T) => T) = new LogUtil(f).logWithValue _
}
Then I used it as:
val rs = calcSomeResult()
withValue(logger.info)("result is:" + rs, rs)
it will log the value and return it. it works for me,but seems wierd. as I am a old java programmer, but new to scala, I don't know whether there is a more idiomatic way to do this in scala.
thanks for your help, now I create a better util using Kestrel combinator metioned by romusz
object LogUtil {
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
def logV[A](f: String => Unit)(s: String, x: A) = kestrel(x) { y => f(s + ": " + y)}
}
I add f parameter so that I can pass it a logger from slf4j, and the test case is:
class LogUtilSpec extends FlatSpec with ShouldMatchers {
val logger = LoggerFactory.getLogger(this.getClass())
import LogUtil._
"LogUtil" should "print log info and keep the value, and the calc for value should only be called once" in {
def calcValue = { println("calcValue"); 100 } // to confirm it's called only once
val v = logV(logger.info)("result is", calcValue)
v should be === 100
}
}
What you're looking for is called Kestrel combinator (K combinator): Kxy = x. You can do all kinds of side-effect operations (not only logging) while returning the value passed to it. Read https://github.com/raganwald/homoiconic/blob/master/2008-10-29/kestrel.markdown#readme
In Scala the simplest way to implement it is:
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
Then you can define your printing/logging function as:
def logging[A](x: A) = kestrel(x)(println)
def logging[A](s: String, x: A) = kestrel(x){ y => println(s + ": " + y) }
And use it like:
logging(1 + 2) + logging(3 + 4)
your example function becomes a one-liner:
def myFunc() = logging("result is", calcSomeResult())
If you prefer OO notation you can use implicits as shown in other answers, but the problem with such approach is that you'll create a new object every time you want to log something, which may cause performance degradation if you do it often enough. But for completeness, it looks like this:
implicit def anyToLogging[A](a: A) = new {
def log = logging(a)
def log(msg: String) = logging(msg, a)
}
Use it like:
def myFunc() = calcSomeResult().log("result is")
You have the basic idea right--you just need to tidy it up a little bit to make it maximally convenient.
class GenericLogger[A](a: A) {
def log(logger: String => Unit)(str: A => String): A = { logger(str(a)); a }
}
implicit def anything_can_log[A](a: A) = new GenericLogger(a)
Now you can
scala> (47+92).log(println)("The answer is " + _)
The answer is 139
res0: Int = 139
This way you don't need to repeat yourself (e.g. no rs twice).
If you like a more generic approach better, you could define
implicit def idToSideEffect[A](a: A) = new {
def withSideEffect(fun: A => Unit): A = { fun(a); a }
def |!>(fun: A => Unit): A = withSideEffect(fun) // forward pipe-like
def tap(fun: A => Unit): A = withSideEffect(fun) // public demand & ruby standard
}
and use it like
calcSomeResult() |!> { rs => logger.info("result is:" + rs) }
calcSomeResult() tap println
Starting Scala 2.13, the chaining operation tap can be used to apply a side effect (in this case some logging) on any value while returning the original value:
def tap[U](f: (A) => U): A
For instance:
scala> val a = 42.tap(println)
42
a: Int = 42
or in our case:
import scala.util.chaining._
def myFunc() = calcSomeResult().tap(x => logger.info(s"result is: $x"))
Let's say you already have a base class for all you loggers:
abstract class Logger {
def info(msg:String):Unit
}
Then you could extend String with the ## logging method:
object ExpressionLog {
// default logger
implicit val logger = new Logger {
def info(s:String) {println(s)}
}
// adding ## method to all String objects
implicit def stringToLog (msg: String) (implicit logger: Logger) = new {
def ## [T] (exp: T) = {
logger.info(msg + " = " + exp)
exp
}
}
}
To use the logging you'd have to import members of ExpressionLog object and then you could easily log expressions using the following notation:
import ExpressionLog._
def sum (a:Int, b:Int) = "sum result" ## (a+b)
val c = sum("a" ## 1, "b" ##2)
Will print:
a = 1
b = 2
sum result = 3
This works because every time when you call a ## method on a String compiler realises that String doesn't have the method and silently converts it into an object with anonymous type that has the ## method defined (see stringToLog). As part of the conversion compiler picks the desired logger as an implicit parameter, this way you don't have to keep passing on the logger to the ## every time yet you retain full control over which logger needs to be used every time.
As far as precedence goes when ## method is used in infix notation it has the highest priority making it easier to reason about what will be logged.
So what if you wanted to use a different logger in one of your methods? This is very simple:
import ExpressionLog.{logger=>_,_} // import everything but default logger
// define specific local logger
// this can be as simple as: implicit val logger = new MyLogger
implicit val logger = new Logger {
var lineno = 1
def info(s:String) {
println("%03d".format(lineno) + ": " + s)
lineno+=1
}
}
// start logging
def sum (a:Int, b:Int) = a+b
val c = "sum result" ## sum("a" ## 1, "b" ##2)
Will output:
001: a = 1
002: b = 2
003: sum result = 3
Compiling all the answers, pros and cons, I came up with this (context is a Play application):
import play.api.LoggerLike
object LogUtils {
implicit class LogAny2[T](val value : T) extends AnyVal {
def ##(str : String)(implicit logger : LoggerLike) : T = {
logger.debug(str);
value
}
def ##(f : T => String)(implicit logger : LoggerLike) : T = {
logger.debug(f(value))
value
}
}
As you can see, LogAny is an AnyVal so there shouldn't be any overhead of new object creation.
You can use it like this:
scala> import utils.LogUtils._
scala> val a = 5
scala> val b = 7
scala> implicit val logger = play.api.Logger
scala> val c = a + b ## { c => s"result of $a + $b = $c" }
c: Int = 12
Or if you don't need a reference to the result, just use:
scala> val c = a + b ## "Finished this very complex calculation"
c: Int = 12
Any downsides to this implementation?
Edit:
I've made this available with some improvements in a gist here
When programming in java, I always log input parameter and return value of a method, but in scala, the last line of a method is the return value. so I have to do something like:
def myFunc() = {
val rs = calcSomeResult()
logger.info("result is:" + rs)
rs
}
in order to make it easy, I write a utility:
class LogUtil(val f: (String) => Unit) {
def logWithValue[T](msg: String, value: T): T = { f(msg); value }
}
object LogUtil {
def withValue[T](f: String => Unit): ((String, T) => T) = new LogUtil(f).logWithValue _
}
Then I used it as:
val rs = calcSomeResult()
withValue(logger.info)("result is:" + rs, rs)
it will log the value and return it. it works for me,but seems wierd. as I am a old java programmer, but new to scala, I don't know whether there is a more idiomatic way to do this in scala.
thanks for your help, now I create a better util using Kestrel combinator metioned by romusz
object LogUtil {
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
def logV[A](f: String => Unit)(s: String, x: A) = kestrel(x) { y => f(s + ": " + y)}
}
I add f parameter so that I can pass it a logger from slf4j, and the test case is:
class LogUtilSpec extends FlatSpec with ShouldMatchers {
val logger = LoggerFactory.getLogger(this.getClass())
import LogUtil._
"LogUtil" should "print log info and keep the value, and the calc for value should only be called once" in {
def calcValue = { println("calcValue"); 100 } // to confirm it's called only once
val v = logV(logger.info)("result is", calcValue)
v should be === 100
}
}
What you're looking for is called Kestrel combinator (K combinator): Kxy = x. You can do all kinds of side-effect operations (not only logging) while returning the value passed to it. Read https://github.com/raganwald/homoiconic/blob/master/2008-10-29/kestrel.markdown#readme
In Scala the simplest way to implement it is:
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
Then you can define your printing/logging function as:
def logging[A](x: A) = kestrel(x)(println)
def logging[A](s: String, x: A) = kestrel(x){ y => println(s + ": " + y) }
And use it like:
logging(1 + 2) + logging(3 + 4)
your example function becomes a one-liner:
def myFunc() = logging("result is", calcSomeResult())
If you prefer OO notation you can use implicits as shown in other answers, but the problem with such approach is that you'll create a new object every time you want to log something, which may cause performance degradation if you do it often enough. But for completeness, it looks like this:
implicit def anyToLogging[A](a: A) = new {
def log = logging(a)
def log(msg: String) = logging(msg, a)
}
Use it like:
def myFunc() = calcSomeResult().log("result is")
You have the basic idea right--you just need to tidy it up a little bit to make it maximally convenient.
class GenericLogger[A](a: A) {
def log(logger: String => Unit)(str: A => String): A = { logger(str(a)); a }
}
implicit def anything_can_log[A](a: A) = new GenericLogger(a)
Now you can
scala> (47+92).log(println)("The answer is " + _)
The answer is 139
res0: Int = 139
This way you don't need to repeat yourself (e.g. no rs twice).
If you like a more generic approach better, you could define
implicit def idToSideEffect[A](a: A) = new {
def withSideEffect(fun: A => Unit): A = { fun(a); a }
def |!>(fun: A => Unit): A = withSideEffect(fun) // forward pipe-like
def tap(fun: A => Unit): A = withSideEffect(fun) // public demand & ruby standard
}
and use it like
calcSomeResult() |!> { rs => logger.info("result is:" + rs) }
calcSomeResult() tap println
Starting Scala 2.13, the chaining operation tap can be used to apply a side effect (in this case some logging) on any value while returning the original value:
def tap[U](f: (A) => U): A
For instance:
scala> val a = 42.tap(println)
42
a: Int = 42
or in our case:
import scala.util.chaining._
def myFunc() = calcSomeResult().tap(x => logger.info(s"result is: $x"))
Let's say you already have a base class for all you loggers:
abstract class Logger {
def info(msg:String):Unit
}
Then you could extend String with the ## logging method:
object ExpressionLog {
// default logger
implicit val logger = new Logger {
def info(s:String) {println(s)}
}
// adding ## method to all String objects
implicit def stringToLog (msg: String) (implicit logger: Logger) = new {
def ## [T] (exp: T) = {
logger.info(msg + " = " + exp)
exp
}
}
}
To use the logging you'd have to import members of ExpressionLog object and then you could easily log expressions using the following notation:
import ExpressionLog._
def sum (a:Int, b:Int) = "sum result" ## (a+b)
val c = sum("a" ## 1, "b" ##2)
Will print:
a = 1
b = 2
sum result = 3
This works because every time when you call a ## method on a String compiler realises that String doesn't have the method and silently converts it into an object with anonymous type that has the ## method defined (see stringToLog). As part of the conversion compiler picks the desired logger as an implicit parameter, this way you don't have to keep passing on the logger to the ## every time yet you retain full control over which logger needs to be used every time.
As far as precedence goes when ## method is used in infix notation it has the highest priority making it easier to reason about what will be logged.
So what if you wanted to use a different logger in one of your methods? This is very simple:
import ExpressionLog.{logger=>_,_} // import everything but default logger
// define specific local logger
// this can be as simple as: implicit val logger = new MyLogger
implicit val logger = new Logger {
var lineno = 1
def info(s:String) {
println("%03d".format(lineno) + ": " + s)
lineno+=1
}
}
// start logging
def sum (a:Int, b:Int) = a+b
val c = "sum result" ## sum("a" ## 1, "b" ##2)
Will output:
001: a = 1
002: b = 2
003: sum result = 3
Compiling all the answers, pros and cons, I came up with this (context is a Play application):
import play.api.LoggerLike
object LogUtils {
implicit class LogAny2[T](val value : T) extends AnyVal {
def ##(str : String)(implicit logger : LoggerLike) : T = {
logger.debug(str);
value
}
def ##(f : T => String)(implicit logger : LoggerLike) : T = {
logger.debug(f(value))
value
}
}
As you can see, LogAny is an AnyVal so there shouldn't be any overhead of new object creation.
You can use it like this:
scala> import utils.LogUtils._
scala> val a = 5
scala> val b = 7
scala> implicit val logger = play.api.Logger
scala> val c = a + b ## { c => s"result of $a + $b = $c" }
c: Int = 12
Or if you don't need a reference to the result, just use:
scala> val c = a + b ## "Finished this very complex calculation"
c: Int = 12
Any downsides to this implementation?
Edit:
I've made this available with some improvements in a gist here
What are all the instances of syntactic sugar in Scala?
They are hard to search for since most/all of them are purely symbols and are thus hard to search for without knowing the name of the concept.
TODO:
Implicit conversions
_ syntax for anonymous functions
Other things I'm forgetting
Basics:
a b is equivalent to a.b.
a b c is equivalent to a.b(c), except when b ends in :. In that case, a b c is equivalent to c.b(a).
a(b) is equivalent to a.apply(b) This is why the following definitions for an anonymous functions are identical:
val square1 = (x: Int) => x*x
val square2 = new Function1[Int,Int] {
def apply(x: Int) = x*x
}
When calling square1(y), you are actually calling square1.apply(y) which square1 must have as specified by the Function1 trait (or Function2, etc...)
a(b) = c is equivalent to a.update(b,c). Likewise, a(b,c) = d is equivalent to a.update(b,c,d) and so on.
a.b = c is equivalent to a.b_=(c). When you create a val/var x in a Class/Object, Scala creates the methods x and x_= for you. You can define these yourself, but if you define y_= you must define y or it will not compile, for example:
scala> val b = new Object{ def set_=(a: Int) = println(a) }
b: java.lang.Object{def set_=(Int): Unit} = $anon$1#17e4cec
scala> b.set = 5
<console>:6: error: value set is not a member of java.lang.Object{def set_=(Int): Unit}
b.set = 5
^
scala> val c = new Object{ def set = 0 ; def set_=(a:Int) = println(a) }
c: java.lang.Object{def set: Int; def set_=(Int): Unit} = $anon$1#95a253
scala> c.set = 5
5
-a corresponds to a.unary_-. Likewise for +a,~a, and !a.
a <operator>= b, where <operator> is some set of special characters, is equivalent to a = a <operator> b only if a doesn't have the <operator>= method, for example:
class test(val x:Int) {
def %%(y: Int) = new test(x*y)
}
var a = new test(10)
a.x // 10
a %%= 5 // Equivalent to a = a %% 5
a.x // 50
Special Classes: Tuples and Symbols
As mentioned by Rahul G, tuples and symbols get a slightly special syntax.
Symbols: the syntax 'x is short for Symbol("x")
Tuples: (p1,p2,..,pn) is short for a case class Tuplen[T1,T2,..,Tn](p1,p2,..,pn)
For example, the following two are equivalent.
val tuple1 = ("Hello",1)
val tuple2 = Tuple2[String,Int]("Hello",1)
In addition to Jaxkson's answer:
type F[A,B] can be used as A F B.
For example:
type ->[A,B] = (A,B)
def foo(f: String -> String)
Using => type in a method definition makes the compiler wrap expressions inside the method call in a function thunk.
For example
def until(cond: => Boolean)(body: => Unit) = while(!cond) body
var a = 0
until (a > 5) {a += 1}
Extractors:
There are two methods used for extractors, unapply and unapplySeq. These are used in multiple variable assignments and pattern matching.
The first use case is where unapply takes the object it is supposed to match and returns a Boolean based on whether or not it matches, for example,
trait Gender
trait Male extends Gender
trait Female extends Gender
object Male extends Male
object Female extends Female
class Person(val g: Gender, val age: Int)
object Adult {
def unapply(p: Person) = p.age >= 18
}
def check(p: Person) = p match {
case Adult() => println("An Adult")
case _ => println("A Child")
}
//Will print: An Adult since Adult.unapply returns true.
check(new Person(Female, 18))
//Will print: A Child as it falls through to the _ case.
check(new Person(Male, 17))
Honestly, I don't really get the purpose of the above syntax since it can be done almost just as easily by just putting the code in the case statements. Of course if you have a better example, leave a comment below
The general case where unapply takes some fixed-number of parameters and returns either an Option[T] for a single parameter or a Option[(p1,p2,...)] for multiple, i.e. a Tuple with the matched values, for example, continuing from the above code:
object Person {
def apply(g: Gender, age: Int) = new Person(g, age)
def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age))
}
//Using Person.apply as described in the Basics section
val alice = Person(Female, 30)
val bob = Person(Male, 25)
//This calls Person.unapply(alice), which returns Some((Female, 30)).
//alice_gender is assigned Female and alice_age 30.
val Person(alice_gender, alice_age) = alice
bob match {
//Calls Person.unapply(bob), but sees that g is Male, so no match.
case Person(Female, _) => println("Hello ma'am")
//Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass
//the 'if' statement, so it doesn't match here either.
case Person(Male, age) if age < 18 => println("Hey dude")
//So bob falls through to here
case _ => println("Hello Sir")
}
Person(Male,-1) match {
//Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0.
//Therefore this case will not match.
case Person(_, _) => println("Hello person")
//Thus it falls through to here.
case _ => println("Are you Human?")
}
Note: Case classes do all those apply/unapply definitions for you (as well as other stuff) so use them whenver possible to save time and reduce code.
unapplySeq. This works similarly to unapply as above, except it must return an Option of some kind of sequence.
As a quick example,
scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))
Anonymous functions:
_ + _ is short for (a, b) => a + b
Context bounds desugar into implicit parameters, e.g. consider a function that leverages the Monoid type class:
def suml[T: Monoid](xs: List[T]) = {
val T = implicitly[Monoid[T]]
xs.foldLeft(T.mzero)(T.mplus)
}
where the : Monoid part is a context bound, gets translated to:
def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = {
...
}
therefore the following compiles, too:
def suml[T: Monoid](xs: List[T]) = {
val T = evidence$1
...
}