Scala Short Learning Notes
These are various notes and snippets from various sources that i found useful while learning scala
Returns are discouraged
In fact, odd problems can occur if you use return statements in Scala because it changes the meaning of your program. For this reason, return statement usage is discouraged. The return keyword is not “optional” or “inferred”; it changes the meaning of your program, and you should never use it.
http://tpolecat.github.io/2014/05/09/return.html
Important thing in scala collection
Basic : Seq, MaP and Set In seq we
- Indexed
- Buffer
- Linear
Where indexed is of type : array, range, vector
Linear is of type : List, Stack, Queue
Buffer : ArrayBuffer and ListBuffer
For mutable seq where you want to keep changing elements, use the buffer type. Decide list or array based on whether accessing by index or traversing the elements
When to use listBuffer
If there is list that is constantly changing then use list buffer and later convert to list. List by itself is immutable. If however you accessing a random element like x(1000) then better use ArrayBuffer which is indexed.
What type should my API accept as input?
As general as possible. In most cases this will be Traversable <- Seq <- List. Explanation: We want our API consumers to be able to call our code without needing them to convert types. If our function takes a Traversable, the caller can put almost any type of collection. This is usually sufficient if we just map(), fold(), head(), tail(), drop(), find(), filter() or groupBy(). In case you want to use length(), make it a Seq. If you need to efficiently prepend with ::, use a List.
What type should my API return?
As specific as possible. Typically you want to return a List, Vector, Stack or Queue. Explanation: This will not put any constraints on your API consumers but will allow them to eventually process returned data in optimal way and worry less about conversions.
Vectors
vectors are faster than list for random access of elements . List is better when most of usage is around accessing the head or tail of the list vectors are immutable. The update method gives a new vector that differs in only single element vectors are implemented as tree
Should I use List or Vector?
You most probably want a Vector, unless your algorithm can be expressed only using ::, head and tail, then use a List.
Scala Vector has a very effective iteration implementation and, comparing to List is faster in traversing linearly (which is weird?), so unless you are planning to do quite some appending, Vector is a better choice. Additionally, Lists don’t work well with parallel algorithms, it’s hard to break them down into pieces and put together in an efficient way.
Useful factory methods on collections
http://www.scala-lang.org/docu/files/collections-api/collections_45.html
Scala Operators
->, | =, ++=, <=, ., ::, and :+=. |
http://stackoverflow.com/questions/7888944/what-do-all-of-scalas-symbolic-operators-mean
Lazy Val
Lazy val are evaluated once when they are used. They are only evaluated once. Sometimes its useful to have a lazy val than a function
lazy val x = { println(“do something”); “some value”}
The value of x will be evaluated only once when first used.
Partial functions
val t :PartialFunction[Int,String] = { case i:Int if i > 10 => i.toString}
This is partial since the function is defined only for few values of i
Chaining partial functions
The orElse method defined on the PartialFunction trait allows you to chain an arbitrary number of partial functions, creating a composite partial function. The first one, however, will only pass on to the next one if it isn’t defined for the given input.
val handler = fooHandler orElse barHandler orElse bazHandler
Where fooHandler, barHandler etc can come from different traits. So this allows composition
Infix operations in scala 1 + 52 is same as 1.+(52)
Apply
Every function in Scala can be treated as an object and it works the other way too - every object can be treated as a function, provided it has the apply method. Such objects can be used in the function notation:
This is useful for the factory pattern.
Package
package create a lexical namespace in which classes are declared. To help segregate code in such a way that it doesn’t conflict with one another.
you can use import anywhere inside the client Scala file, not just at the top of the file and correspondingly, will have scoped relevance
By using the underscore , you effectively tell the Scala compiler that all of the members inside BigInteger should be brought into scope.
Trait Self Annotation
self : Base =>
Consider the examples below where both the traits are providing same functionalities.
class Base { def magic = “bibbity bobbity boo!!” }
trait Extender extends Base { def myMethod = “I can “+magic }
trait SelfTyper { self : Base =>
def myMethod = “I can “+magic }
But the two are completely different. Extender can be mixed in with any class and adds both the “magic” and “myMethod” to the class it is mixed with. SelfTyper can only be mixed in with a class that extends Base and SelfTyper only adds the method “myMethod” NOT “magic”.
Why is the “self annotations” useful? Because it allows several provides a way of declaring dependencies. One can think of the self annotation declaration as the phrase “I am useable with” or “I require a”.
implicit
http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html
Use Option not null
Option is an abstract class in Scala and defines two subclasses, Some and None. Every now and then you encounter a situation where a method needs to return a value or nothing. But in the case of Scala, Option is the recommended way to go when you have a function return an instance of Some or otherwise return None. You can use Option with pattern matching in Scala, and it also defines methods like map, filter, and flatMap so that you can easily use it in a for-comprehension.
Use get for getting the map values
Convert scala list to java list
Scala list and java list are not compatible. When interfacing with java libarary you have to convert it from one form to another def toJavaList(scalaList: List[BasicNameValuePair]) = { java.util.Arrays.asList(scalaList.toArray:_) } _ is required to get all all the values of the list
Use require inside class to enforce
require(args.size >= 2, “at minimum you should specify action(post, get, delete, options) and url”)
Convert tuple to map key and value
Exists
Type of constructors
primary constructor : the class body is primary constructor
auxiliary constructor:
Slice
Zip
dropWhile and takeWhile
Use dropWhile and takeWhile when you want to longest seqeunce from start when the predicate is true
collect
predicate
A predicate is a anonymous function that takes one or more arguments and returns boolean
filter(predicate)
eg: List(1,2,3,4).filter(p => p % 2 == 0) or List(1,2,3,4).filter(_ % 2 == 0)
Mutable Hashmap
For dictionary use the mutable HashMap
collection.mutable.Map[String, String]
flatMap
Array To List
a.toList
Count (based on predicate) Array(1,2,3,4,5,6).count(x => x > 3)
Exists (based on predicate) Array(1,2,3,4,5,6).exists(x => x == 3)
anonymous function
Scala functions as arguments
Functions vs Method
Scala curry functions
Scala multiple parameters per list
def multipleParametersPerList(num : Int*) = num.sum
multipleParametersPerList(1,2,3) // will give 6
Prepending and appending to list
var x = 4 :: List(1,2)
x = x :+ 0
For and foreach
Function Literals
Add to list
Traits
Breaking up your application into small, focused traits is a powerful way to create reusable, scalable abstractions and “components.” Complex behaviors can be built up through declarative composition of traits.
But also splitting objects into too many fine-grained traits can obscure the order of execution in your code!
Less Exception Handling
Scala encourages a coding style that lessens the need for exceptions and exception handling.
Map
Map by default are immutable . Import mutable map
Companion object
Companions must be defined together with class
Join a list of strings
strings.mkstring
traits vs abstract class
There are two main reasons to use an abstract class in Scala: You want to create a base class that requires constructor arguments.
The code will be called from Java code.