Showing posts with label Learn Scala. Show all posts
Showing posts with label Learn Scala. Show all posts

Sunday, 30 October 2016

Control Structures : If Else Expressions : Day 6 Learnings

The Scala built-in control structures are if, while, for, try, and match expressions. Scala’s built-in control structures are sufficient to provide features that their imperative equivalents provide, but because all of Scala’s control structures (except while loops) result in some value, these control structures support functional approach as well.

If..Else Expression Blocks 


The If..Else conditional expression is a classic programming construct for choosing a branch of code based on whether an expression resolves to true or false


In many languages this takes the form of an “if .. else if .. else” block, which starts with an “if,” continues with zero to many else if ” sections, and ends with a final “else” catch-all statement.

As a matter of practice you can write these same “if .. else if .. else” blocks in Scala and they will work just as you have experienced them in Java and other languages. As a matter of formal syntax, however, Scala only supports a single “if ” and optional “else” block, and does not recognise the “else if ” block as a single construct.

So how do “else if ” blocks still work correctly in Scala? Because “if .. else” blocks are based on expression blocks, and expression blocks can be easily nested, an “if .. else if ..else” expression is equivalent to a nested “if .. else { if .. else }” expression. 

Logically this is exactly the same as an “if .. else if .. else” block, and as a matter of syntax Scala recognises the second “if else” as a nested expression of the outer “if .. else” block.

Let’s start exploring actual “if ” and “if .. else” blocks by looking at the syntax for the simple “if ” block.

If Expressions 


Syntax: Using an If Expression

if (<Boolean expression>) <expression>


The term Boolean expression here indicates an expression that will return either true or false .

Here is a simple if block that prints a notice if the Boolean expression is true:

scala> if ( 47 % 3 > 0 ) println("Not a multiple of 3")
Not a multiple of 3 


Of course 47 isn’t a multiple of 3, so the Boolean expression was true and the println was triggered. 

Although an if block can act as an expression, it is better suited for statements like this one. The problem with using if blocks as expressions is that they only conditionally return a value. If the Boolean expression returns false, what do you expect the if block to return? 

scala> val result = if ( false ) "what does this return?" 
result: Any = ()

The type of the result value in this example is unspecified so the compiler used type inference to determine the most appropriate type. Either a String or Unit could have been returned, so the compiler chose the root class Any . This is the one class common to both String (which extends AnyRef ) and to Unit (which extends AnyVal ). Unlike the solitary “if ” block, the “if .. else” block is well suited to working with expressions.


If-Else Expressions 


Syntax: If .. Else Expressions 

if (<Boolean expression>) <expression>
else <expression>


Here is an example: 


scala> val x = 10; val y = 20
x: Int = 10
y: Int = 20

scala> val max = if (x > y) x else y
max: Int = 20


You can see that the x and y values make up the entirety of the if and else expressions.  The resulting value is assigned to max , which we and the Scala compiler know will be an Int because both expressions have return values of type Int .

Note: Some wonder why Scala doesn’t have a ternary expression (popular in C and Java) where the punctuation characters ? and : act as a one-line if and else expression. It should be clear from this example that Scala doesn’t really need it because its if and else blocks can fit compactly on a single line (and, unlike in C and Java, they are already an expression).

Using a single expression without an expression block in if..else expressions works well if everything fits on one line. When your if..else expression doesn’t easily fit on a single line, however, consider using expression blocks to make your code more readable. if expressions without an else should always use curly braces, because they tend to be statements that create side effects.

if..else blocks are a simple and common way to write conditional logic. There are other, more elegant ways to do so in Scala, however, using match expressions.


Note: Sample examples on if..else

If Expression in Scala
scala> if (exp) println("yes")

Multi-line If Expression

scala> if (exp) {
     |  println("Line one")
     |  println("Line two")
     | }

Multi-line Else Expression

scala> if (exp) {
     |  println("Hello")
     |  } else {
     |  println("Line one")
     |  println("Line two")
     | }

Multiple If-Else and Else-If Expression
scala> if (exp1) {

     |  println("Line one")
     |  println("Line two")
     | } else if (exp2) {
     |  println("Line one")
     |  println("Line two")
     | } else if (exp3) {
     |  println("Line one")
     |  println("Line two")
     | } else {
     |  println("Line one")
     |  println("Line two")
     | }



Sunday, 23 October 2016

Learn more on Scala Types : Formatting Numbers and Currency : Day 4 Learnings

Formatting Numbers and Currency

You want to format numbers or currency to control decimal places and commas, typically for printed output.

For basic number formatting, use the f string interpolator , “Sub‐
stituting Variables into Strings”:

scala> val pi = scala.math.Pi
pi: Double = 3.141592653589793

scala> println(f"$pi%1.5f")
3.14159


A few more examples demonstrate the technique:
scala> f"$pi%1.5f"
res0: String = 3.14159

scala> f"$pi%1.2f"
res1: String = 3.14

scala> f"$pi%06.2f"

res2: String = 003.14


If you’re using a version of Scala prior to 2.10, or prefer the explicit use of the format method, you can write the code like this instead:
scala> "%06.2f".format(pi)
res3: String = 003.14


A simple way to add commas is to use the getIntegerInstance method of the java.text.NumberFormat class:

scala> val formatter = java.text.NumberFormat.getIntegerInstance
formatter: java.text.NumberFormat = java.text.DecimalFormat@674dc

scala> formatter.format(10000)
res0: String = 10,000

scala> formatter.format(1000000)
res1: String = 1,000,000


You can also set a locale with the getIntegerInstance method:

scala> val locale = new java.util.Locale("de", "DE")
locale: java.util.Locale = de_DE

scala> val formatter = java.text.NumberFormat.getIntegerInstance(locale)
formatter: java.text.NumberFormat = java.text.DecimalFormat@674dc

scala> formatter.format(1000000)

res2: String = 1.000.000



You can handle floating-point values with a formatter returned by getInstance :

scala> val formatter = java.text.NumberFormat.getInstance
formatter: java.text.NumberFormat = java.text.DecimalFormat@674dc

scala> formatter.format(10000.33)
res0: String = 10,000.33


For currency output, use the getCurrencyInstance formatter:

scala> val formatter = java.text.NumberFormat.getCurrencyInstance
formatter: java.text.NumberFormat = java.text.DecimalFormat@67500

scala> println(formatter.format(123.456789))

$123.46

scala> println(formatter.format(1234.56789))
$1,234.57

scala> println(formatter.format(12345.6789))
$12,345.68

scala> println(formatter.format(123456.789))

$123,456.79


This approach handles international currency:

scala> import java.util.{Currency, Locale}
import java.util.{Currency, Locale}

scala> val de = Currency.getInstance(new Locale("de", "DE"))
de: java.util.Currency = EUR

scala> formatter.setCurrency(de)
scala> println(formatter.format(123456.789))

EUR123,456.79


Note: This recipe falls back to the Java approach for printing currency and other formatted numeric fields, though of course the currency solution depends on how you handle currency in your applications. In my work as a consultant, I’ve seen most companies
handle currency using the Java BigDecimal class, and others create their own custom currency classes, which are typically wrappers around BigDecimal

Learn more on Scala Types : Creating a Range, List, or Array of Numbers : Day 4 Learnings

Creating a Range, List, or Array of Numbers

You need to create a range, list, or array of numbers, such as in a for loop, or for testing purposes.

Use the to method of the Int class to create a Range with the desired elements:
scala> val r = 1 to 10
r: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5,
6, 7, 8, 9, 10)


You can set the step with the by method:
scala> val r = 1 to 10 by 2
r: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

scala> val r = 1 to 10 by 3
r: scala.collection.immutable.Range = Range(1, 4, 7, 10)

Ranges are commonly used in for loops:
scala> for (i <- 1 to 5) println(i)
1
2

3
4
5

When creating a Range , you can also use until instead of to :
scala> for (i <- 1 until 5) println(i)
1
2
3

4


Scala makes it easy to create a range of numbers. The first three examples shown in the Solution create a Range . 

You can easily convert a Range to other sequences, such as an Array or List , like this:

scala> val x = 1 to 10 toArray
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val x = 1 to 10 toList
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)


Although this infix notation syntax is clear in many situations (such as for loops), it’s generally preferable to use this syntax:

scala> val x = (1 to 10).toList
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val x = (1 to 10).toArray
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

The magic that makes this process work is the to and until methods, which you’ll find in the RichInt class. 

When you type the following portion of the code, you’re actually invoking the to method of the RichInt class:  
1 to

You can demonstrate that to is a method on an Int by using this syntax in the REPL:

1.to(10)


You can create a random-length range, which can be useful for testing:
scala> var range = 0 to scala.util.Random.nextInt(10)
range: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)


By using a range with the for / yield construct, you don’t have to limit your ranges to sequential numbers:
scala> for (i <- 1 to 5) yield i * 2
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)


You also don’t have to limit your ranges to just integers:
scala> for (i <- 1 to 5) yield i.toDouble
res1: scala.collection.immutable.IndexedSeq[Double] =

Vector(1.0, 2.0, 3.0, 4.0, 5.0)

Learn more on Scala Types : Generating Random Numbers : Day 3 Learnings

Generating Random Numbers

You need to create random numbers, such as when testing an application, performing a simulation, and many other situations.

Create random numbers with the Scala scala.util.Random class. You can create random integers:
scala> val r = scala.util.Random
r: scala.util.Random = scala.util.Random@13eb41e5

scala> r.nextInt
res0: Int = −1323477914


You can limit the random numbers to a maximum value:
scala> r.nextInt(100)
res1: Int = 58

In this use, the Int returned is between 0 (inclusive) and the value you specify (exclusive), so specifying 100 returns an Int from 0 to 99 .


You can also create random Float values:
// returns a value between 0.0 and 1.0
scala> r.nextFloat
res2: Float = 0.50317204

You can create random Double values:
// returns a value between 0.0 and 1.0
scala> r.nextDouble
res3: Double = 0.6946000981900997


You can set the seed value using an Int or Long when creating the Random object:
scala> val r = new scala.util.Random(100)
r: scala.util.Random = scala.util.Random@bbf4061


You can also set the seed value after a Random object has been created:
r.setSeed(1000L)


The Random class handles all the usual use cases, including creating numbers, setting the maximum value of a random number range, and setting a seed value. You can also generate random characters:

// random characters

scala> r.nextPrintableChar
res0: Char = H

scala> r.nextPrintableChar
res1: Char = r


Scala makes it easy to create a random-length range of numbers, which is especially useful for testing:

// create a random length range
scala> var range = 0 to r.nextInt(10)
range: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)

scala> range = 0 to r.nextInt(10)
range: scala.collection.immutable.Range.Inclusive = Range(0, 1)


You can add a for / yield loop to modify the numbers:

scala> for (i <- 0 to r.nextInt(10)) yield i * 2

res0: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4)

You can easily create random-length ranges of other types. Here’s a random-length collection of up to 10 Float values:

scala> for (i <- 0 to r.nextInt(10)) yield (i * r.nextFloat)
res1: scala.collection.immutable.IndexedSeq[Float] =
Vector(0.0, 0.71370363, 1.0783684)


Here’s a random-length collection of “printable characters”:

scala> for (i <- 0 to r.nextInt(10)) yield r.nextPrintableChar
res2: scala.collection.immutable.IndexedSeq[Char] = Vector(x, K, ^, z, w)

Be careful with the nextPrintableChar method. A better approach may be to control the characters you use, as shown in my “How to create a list of alpha or alphanumeric characters” article, shown in the See Also.

Conversely, you can create a sequence of known length, filled with random numbers:

scala> for (i <- 1 to 5) yield r.nextInt(100)

res3: scala.collection.immutable.IndexedSeq[Int] = Vector(88, 94, 58, 96, 82)




Learn more on Scala Types : Handling Very Large Numbers : Day 3 Learnings

Handling Very Large Numbers

You’re writing an application and need to use very large integer or decimal numbers.


Use the Scala BigInt and BigDecimal classes. 

You can create a BigInt :

scala> var b = BigInt(1234567890)
b: scala.math.BigInt = 1234567890

You can create a BigDecimal :

scala> var b = BigDecimal(123456.789)
b: scala.math.BigDecimal = 123456.789

Unlike their Java equivalents, these classes support all the operators you’re used to using with numeric types:


scala> b + b
res0: scala.math.BigInt = 2469135780

scala> b * b
res1: scala.math.BigInt = 1524157875019052100

scala> b += 1
scala> println(b)
1234567891


You can convert them to other numeric types:

scala> b.toInt
res2: Int = 1234567891

scala> b.toLong
res3: Long = 1234567891

scala> b.toFloat
res4: Float = 1.23456794E9

scala> b.toDouble
res5: Double = 1.234567891E9

To help avoid errors, you can also test them first to see if they can be converted to other numeric types:

scala> b.isValidByte
res6: Boolean = false

scala> b.isValidChar
res7: Boolean = false

scala> b.isValidShort
res8: Boolean = false

scala> if (b.isValidInt) b.toInt
res9: AnyVal = 1234567890


Although the Scala BigInt and BigDecimal classes are backed by the Java BigInteger and BigDecimal classes, they are simpler to use than their Java counterparts.

As you can see in the examples, they work just like other numeric types, and they’re also mutable (as you saw in the += example). These are nice improvements over the Java classes.

scala> Byte.MaxValue
res0: Byte = 127

scala> Short.MaxValue
res1: Short = 32767

scala> Int.MaxValue
res2: Int = 2147483647

scala> Long.MaxValue
res3: Long = 9223372036854775807

scala> Double.MaxValue
res4: Double = 1.7976931348623157E308


Depending on your needs, you may also be able to use the PositiveInfinity and NegativeInfinity of the standard numeric types:

scala> Double.PositiveInfinity
res0: Double = Infinity

scala> Double.NegativeInfinity
res1: Double = -Infinity

scala> 1.7976931348623157E308 > Double.PositiveInfinity
res45: Boolean = false



Learn more on Scala Types : Comparing Floating-Point Numbers : Day 3 Learnings

Comparing Floating-Point Numbers

You need to compare two floating-point numbers, but as in some other programming languages, two floating-point numbers that should be equivalent may not be.

As in Java and many other languages, you solve this problem by creating a method that lets you specify the precision for your comparison. The following “approximately equals” method demonstrates the approach:

def ~=(x: Double, y: Double, precision: Double) = {
   if ((x - y).abs < precision) true else false
}

You can use this method like this:

scala> val a = 0.3
a: Double = 0.3

scala> val b = 0.1 + 0.2
b: Double = 0.30000000000000004

scala> ~=(a, b, 0.0001)
res0: Boolean = true

scala> ~=(b, a, 0.0001)
res1: Boolean = true


When you begin working with floating-point numbers, you quickly learn that 0.1 plus 0.1 is 0.2 :

scala> 0.1 + 0.1
res38: Double = 0.2

But 0.1 plus 0.2 isn’t exactly 0.3 :

scala> 0.1 + 0.2
res37: Double = 0.30000000000000004


This subtle inaccuracy makes comparing two floating-point numbers a real problem:

scala> val a = 0.3
a: Double = 0.3

scala> val b = 0.1 + 0.2
b: Double = 0.30000000000000004

scala> a == b
res0: Boolean = false

As a result, you end up writing your own functions to compare floating-point numbers with a precision (or tolerance).

Learn more on Scala Types : Replacements for ++ and −− : Day 3 Learnings

Replacements for ++ and −−

You want to increment or decrement numbers using operators like ++ and −− that are 
available in other languages, but Scala doesn’t have these operators.

Because val fields are immutable, they can’t be incremented or decremented, but 
var Int fields can be mutated with the += and −= methods

scala> var a = 1
a: Int = 1

scala> a += 1
scala> println(a)
2

scala> a −= 1
scala> println(a)
1


As an added benefit, you use similar methods for multiplication and division

scala> var i = 1
i: Int = 1

scala> i *= 2
scala> println(i)
2

scala> i *= 2
scala> println(i)
4

scala> i /= 2
scala> println(i)
2


Note that these symbols aren’t operators; they’re implemented as methods that are available on Int fields declared as a var . Attempting to use them on val fields results in a compile-time error:

scala> val x = 1
x: Int = 1

scala> x += 1
<console>:9: error: value += is not a member of Int
     x += 1
        ^


Note: As mentioned, the symbols += , −= , *= , and /= aren’t operators, they’re methods. This approach of building functionality with libraries instead of operators is a consistent pattern in Scala. Actors, for instance, are not built into the language, but are instead implemented as a library. See the Dr. Dobbs link in the See Also for Martin Odersky’s discussion of this philosophy.


Another benefit of this approach is that you can call methods of the same name on other types besides Int . For instance, the Double and Float classes have methods of the same name:

scala> var x = 1d
x: Double = 1.0

scala> x += 1
scala> println(x)
2.0

scala> var x = 1f
x: Float = 1.0

scala> x += 1
scala> println(x)
2.0


Learn more on Scala Types : Overriding the Default Numeric Types : Day 3 Learnings

Overriding the Default Numeric Types

Scala automatically assigns types to numeric values when you assign them, and you need to override the default type it assigns as you create a numeric field

If you assign 1 to a variable, Scala assigns it the type Int :
scala> val a = 1
a: Int = 1

The following examples show one way to override simple numeric types:

scala> val a = 1d
a: Double = 1.0

scala> val a = 1f
a: Float = 1.0

scala> val a = 1000L
a: Long = 1000


Another approach is to annotate the variable with a type, like this:

scala> val a = 0: Byte
a: Byte = 0

scala> val a = 0: Int
a: Int = 0

scala> val a = 0: Short
a: Short = 0

scala> val a = 0: Double
a: Double = 0.0

scala> val a = 0: Float
a: Float = 0.0


Spacing after the colon isn’t important, so you can use this format, if preferred: val a = 0:Byte

According to the Scala Style Guide, those examples show the preferred style for annotating types, but personally I prefer the following syntax when assigning types to variables, specifying the type after the variable name:

scala> val a:Byte = 0
a: Byte = 0

scala> val a:Int = 0
a: Int = 0


You can create hex values by preceding the number with a leading 0x or 0X , and you can store them as an Int or Long :

scala> val a = 0x20
a: Int = 32

// if you want to store the value as a Long
scala> val a = 0x20L
a: Long = 32


It’s helpful to know about this approach when creating object instances. The general syntax looks like this:

// general case
var [name]:[Type] = [initial value]

// example
var a:Short = 0

This form can be helpful when you need to initialize numeric var fields in a class:

class Foo {
      var a: Short = 0   // specify a default value
       var b: Short = _   // defaults to 0
}

As shown, you can use the underscore character as a placeholder when assigning an initial value. This works when creating class variables, but doesn’t work in other places, such as inside a method. For numeric types this isn’t an issue - you can just assign the
type the value zero - but with most other types, you can use this approach inside a method:

var name = null.asInstanceOf[String]

Better yet, use the Option / Some / None pattern. It helps eliminate null values from your code, which is a very good thing. You’ll see this pattern used in the best Scala libraries and frameworks, such as the Play Framework.


Learn more on Scala Types : Converting Between Numeric Types : Day 3 Learnings

Converting Between Numeric Types (Casting)

You want to convert from one numeric type to another, such as from an Int to a Double . 

Instead of using the “cast” approach in Java, use the to* methods that are available on all numeric types. These methods can be demonstrated in the REPL (note that you need to hit Tab at the end of the first example):

scala> val b = a.to[Tab]
toByte     toChar      toDouble     toFloat    
toInt        toShort     toString       toLong

scala> 19.45.toInt
res0: Int = 19

scala> 19.toFloat
res1: Float = 19.0

scala> 19.toDouble
res2: Double = 19.0

scala> 19.toLong
res3: Long = 19

scala> val b = a.toFloat
b: Float = 1945.0

Note: In Java, you convert from one numeric type to another by casting the types, like this: 
int a = (int) 100.00;

But in Scala, you use the to* methods, as shown in this recipe.

If you want to avoid potential conversion errors when casting from one numeric type to another, you can use the related isValid methods to test whether the type can be converted before attempting the conversion.

For instance, a Double object (via RichDouble ) has methods like isValidInt and isValidShort :

scala> val a = 1000L
a: Long = 1000

scala> a.isValidByte
res0: Boolean = false

scala> a.isValidShort
res1: Boolean = true




Learn more on Scala Types : Parsing a Number from a String : Day 3 Learnings

You want to convert a String to one of Scala’s numeric types:

Use the to* methods that are available on a String (courtesy of the StringLike trait):

scala> "100".toInt
res0: Int = 100

scala> "100".toDouble
res1: Double = 100.0

scala> "100".toFloat
res2: Float = 100.0

scala> "1".toLong
res3: Long = 1

scala> "1".toShort
res4: Short = 1

scala> "1".toByte
res5: Byte = 1

Be careful, because these methods can throw the usual Java NumberFormatException :

scala> "foo".toInt
java.lang.NumberFormatException: For input string: "foo"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java)
at java.lang.Integer.parseInt(Integer.java:449)
... more output here ...

BigInt and BigDecimal instances can also be created directly from strings (and can also throw a NumberFormatException ):

scala> val b = BigInt("1")
b: scala.math.BigInt = 1

scala> val b = BigDecimal("3.14159")
b: scala.math.BigDecimal = 3.14159


Handling a base and radix

If you need to perform calculations using bases other than 10 , you’ll find the toInt method in the Scala Int class doesn’t have a method that lets you pass in a base and radix

To solve this problem, use the parseInt method in the java.lang.Integer class, as shown in these examples:

scala> Integer.parseInt("1", 2)
res0: Int = 1

scala> Integer.parseInt("10", 2)
res1: Int = 2

scala> Integer.parseInt("100", 2)
res2: Int = 4

scala> Integer.parseInt("1", 8)
res3: Int = 1

scala> Integer.parseInt("10", 8)
res4: Int = 8


Implicit conversions

If you’re a fan of implicit conversions, you can create an implicit class and method to help solve the problem.

Add Your Own Methods to the String Class” create the implicit conversion as follows:

implicit class StringToInt(s: String) {
 def toInt(radix: Int) = Integer.parseInt(s, radix)
}

Defining this implicit class (and bringing it into scope) adds a toInt method that takes a radix argument to the String class, which you can now call instead of calling Integer.parseInt :

scala> implicit class StringToInt(s: String) {
        |  def toInt(radix: Int) = Integer.parseInt(s, radix)
        | }
defined class StringToInt

scala> "1".toInt(2)
res0: Int = 1

scala> "10".toInt(2)
res1: Int = 2

scala> "100".toInt(2)
res2: Int = 4

scala> "100".toInt(8)
res3: Int = 64

scala> "100".toInt(16)
res4: Int = 256








Learn more on Scala Types : Numeric Literals : Day 3 Learnings

Displays Scala’s numeric literals:

LiteralTypeDescription
5IntUnadorned integer literals are Int by default
0x0fIntThe “0x” prefix denotes hexadecimal notation
5lLongThe “l” suffix denotes a Long type
5.0DoubleUnadorned decimal literals are Double by default
5fFloatThe “f” suffix denotes a Float type
5dDoubleThe “d suffix denotes a Double type


Integer Literals

You indicate a negative number by prefixing the literal with a – sign.

For Long literals, it is necessary to append the L or l character at the end of the literal, unless you are assigning the value to a variable declared to be Long . Otherwise, Int is inferred.

compile-time error occurs if an integer literal number is specified that is outside these ranges, as in the following examples:

scala> val i = 1234567890123
<console>:1: error: integer number too large
      val i = 12345678901234567890
                 ^

scala> val i = 1234567890123L
i: Long = 1234567890123

scala> val b: Byte = 128
<console>:19: error: type mismatch;
found : Int(128)
required: Byte
        val b: Byte = 128
                              ^
scala> val b: Byte = 127
b: Byte = 127

Floating-Point Literals

Floating-point literals are expressions with an optional minus sign, zero or more digits, followed by a period ( . ), followed by one or more digits. For Float literals, append the F or f character at the end of the literal. Otherwise, a Double is assumed. You can optionally append a D or d for a Double .

Floating-point literals can be expressed with or without exponentials. The format of the exponential part is e or E , followed by an optional + or – , followed by one or more digits.

Here are some example floating-point literals, where Double is inferred unless the declared variable is Float or an f or F suffix is used:

.14
3.14
3.14f
3.14F
3.14d
3.14D
3e5
3E5
3.14e+5
3.14e-5
3.14e-5
3.14e-5f
3.14e-5F
3.14e-5d
3.14e-5D


Float consists of all IEEE 754 32-bit, single-precision binary floating-point values.

Double consists of all IEEE 754 64-bit, double-precision binary floating-point values.

Before Scala 2.10, floating-point literals without a digit after the period were allowed, e.g., 3. and 3.e5 . This syntax leads to some ambiguities, where it can be interpreted as the period before a method name. 

How should 1.toString be parsed? Is it 1 the Int or 1.0 the Double ? Hence, literals without at least one digit after the period are deprecated in 2.10 and disallowed in 2.11

Boolean Literals

The Boolean literals are true and false . The type of the variable to which they are assigned will be inferred to be Boolean :

scala> val b1 = true
b1: Boolean = true

scala> val b2 = false
b2: Boolean = false

Character Literals

A character literal is either a printable Unicode character or an escape sequence, written between single quotes. A character with a Unicode value between 0 and 255 may also be represented by an octal escape, i.e., a backslash ( \ ) followed by a sequence of up to
three octal characters. 

It is a compile-time error if a backslash character in a character or string literal does not start a valid escape sequence.

Here are some examples:
'A'
'\u0041'   // 'A' in Unicode
'\n'
'\012'       // '\n' in octal
'\t'

The valid escape sequences are shown in below Table

SequenceMeaning
\bBackspace (BS
\tHorizontal tab (HT)
\nLine feed (LF)
\fForm feed (FF)
\rCarriage return (CR)
\"Double quote ( " )
\’Single quote ( ’ )
\\Backslash ( \ )

Note that nonprintable Unicode characters like \u0009 (tab) are not allowed. Use the equivalents like \t . Recall that three Unicode characters were mentioned in above Table as valid replacements for corresponding ASCII sequences, ⇒ for => , → for -> , and ←
for <- .


String Literals

A string literal is a sequence of characters enclosed in double quotes or triples of double quotes, i.e., """...""" .

For string literals in double quotes, the allowed characters are the same as the character literals. However, if a double quote ( " ) character appears in the string, it must be “escaped” with a \ character. 

Here are some examples:

"Learn\nScala"
"He exclaimed, \"Scala is great!\""
"First\tSecond"

The string literals bounded by triples of double quotes are also called multiline string literals. These strings can cover several lines; the line feeds will be part of the string. They can include any characters, including one or two double quotes together, but not
three together. They are useful for strings with \ characters that don’t form valid Unicode or escape sequences, like the valid sequences listed in above Table. Regular expressions are
a good example, which use lots of escaped characters with special meanings. Conversely, if escape sequences appear, they aren’t interpreted.

Here are three example strings:

"""Learn\nScala"""

"""He exclaimed, "Scala is great!" """

"""First line\n
Second line\t
Fourth line"""

Note that we had to add a space before the trailing """ in the second example to prevent a parse error. Trying to escape the second " that ends the "Scala is great!" quote, i.e., "Scala is great!\" , doesn’t work.

When using multiline strings in code, you’ll want to indent the substrings for proper code formatting, yet you probably don’t want that extra whitespace in the actual string output. String.stripMargin solves this problem. It removes all whitespace in the substrings up to and including the first occurrence of a vertical bar, | . If you want some whitespace indentation, put the whitespace you want after the | . 

Consider this example:

def hello(name: String) = s"""Welcome!
   Hello, $name!
   * (Gratuitous Star!!)
  |We're glad you're here.
  | Have some extra whitespace.""".stripMargin

hello("Learn Scala")

It prints the following:

Welcome!
   Hello, Learn Scala!
   * (Gratuitous Star!!)

We're glad you're here.
 Have some extra whitespace.

Note where leading whitespace is removed and where it isn’t.


Symbol Literals

Scala supports symbols, which are interned strings, meaning that two symbols with the same “name” (i.e., the same character sequence) will actually refer to the same object in memory. Symbols are used less often in Scala compared to some other languages, like Ruby and Lisp.

A symbol literal is a single quote ( ' ), followed by one or more digits, letters, or underscores (“_”), except the first character can’t be a digit. So, an expression like '1symbol is invalid.

A symbol literal 'id is a shorthand for the expression scala.Symbol("id") . If you want to create a symbol that contains whitespace, use Symbol.apply , e.g., Symbol(" Learn Scala ") . All the whitespace is preserved.


Function Literals


We’ve seen function literals already, but to recap, 
(i: Int, s: String) => s+i 
is a function literal of type 
Function2[Int,String,String]
( String is returned).

You can even use the literal syntax for a type declaration. The following declarations are equivalent:


val f1: (Int,String) => String            = (i, s) => s+i
val f2: Function2[Int,String,String] = (i, s) => s+i



Tuple Literals


How many times have you wanted to return two or more values from a method? In many languages, like Java, you only have a few options, none of which is very appealing.

You could pass in parameters to the method that will be modified for use as the “return” values, which is ugly. (Some languages even use keywords to indicate which parameters are input versus output.) You could declare some small “structural” class that holds the
two or more values, then return an instance of that class.

The Scala library includes TupleN classes (e.g., Tuple2 ), for grouping N items, with the literal syntax of a comma-separated list of the items inside parentheses. There are separate TupleN classes for N between 1 and 22, inclusive (though this upper bound may
be eliminated eventually in a future version of Scala).

For example, val tup = ("Learn Scala", 2014) defines a Tuple2 instance with String inferred for the first element and Int inferred for the second element. Tuple instances are immutable, first-class values (because they are objects like any custom type you define), so you can assign them to variables, pass them as values, and return them from methods.

You can also use the literal syntax for Tuple type declarations:

val t1: (Int,String)  = (1, "two")
val t2: Tuple2[Int,String] = (1, "two")

The following example demonstrates working with tuples:

1. Use the literal syntax to construct a three-element tuple of type Tuple3
val t = ("Hello", 1, 2.3)
println( "Print the whole tuple: " + t )

Output: Print the whole tuple: (Hello,1,2.3)

2. Extract the first element of the tuple (counting from 1, not 0). 
println( ""Print the first item: " + t._1 )

Output: Print the first item: Hello

3. Extract the second element of the tuple (counting from 1, not 0). 
println( "Print the second item: " + t._2 )

Output: Print the second item: 1

4. Extract the third element of the tuple (counting from 1, not 0). 
println( "Print the third item: " + t ._3)

Output: Print the third item: 2.3

5. On the fly declare three values, t1 , t2 , and t3 , that are assigned the three corresponding fields from the tuple.
val (t1, t2, t3) = ("World", '!', 0x22)
println( t1 + ", " + t2 + ", " + t3 )

Output: World, !, 34

6. Use the Tuple3 “factory” method to construct a tuple.
val (t4, t5, t6) = Tuple3("World", '!', 0x22)
println( t4 + ", " + t5 + ", " + t6 )

Output: World, !, 34


The expression t._n retrieves the n th item from tuple t , starting at one, not zero, following historical conventions.

There are several ways to define a two-element tuple, which is sometimes called a pair for short. In addition to the syntax that uses a parenthesized list of values, you can also use the “arrow operator” between two values, as well as special factory methods on the tuple-related classes:

(1, "one")
1 -> "one"
1 → "one"    // Using → character instead of ->
Tuple2(1, "one")

The arrow operator is only available for two-element tuples.






Learn more on Scala Types : Numeric Data Types : Day 3 Learnings

Displays Scala’s numeric data types:

NameDescriptionSizeMinMax
ByteSigned integer1 byte-127128
ShortSigned integer2 bytes-3276832767
IntSigned integer4 bytes-2^312^31 - 1
LongSigned integer8 bytes-2^632^63 - 1
FloatSigned floating point4 bytesn/an/a
DoubleSigned floating point8 bytesn/an/a



Examples on Numeric Data Types:


Let’s try this out by creating values of different types and automatically converting them to higher-ranked types:

scala> val b: Byte = 30
b: Byte = 30

scala> val s: Short = b
s: Short = 10

scala> val d: Double = s
d: Double = 10.0

The b and s values here were assigned to new values that had a higher rank, and so were automatically converted (or upconverted” as some say) to the higher ranks.


Scala does not allow automatic conversion from higher ranked types to lower ranked types. This makes sense, because you could otherwise lose data if you convert to a type with less storage.

Here is an example of trying to automatically convert a higher ranked type to a lower ranked type and the ensuing error:

scala> val l: Long = 20
l: Long = 20

scala> val i: Int = l
<console>:8: error: type mismatch;
found : Long
required: Int
    val i: Int = l

You can choose to manually convert between types using the toType methods available on all numeric types. Although this makes it possible to lose data by converting to a lesser ranked type, it is useful when you know that the data is compatible with the lower ranked type

For example, here is a Long value that can be safely converted to type Int using the toInt method, because its data is within the storage bounds of an Int :

scala> val l: Long = 20
l: Long = 20

scala> val i: Int = l.toInt
i: Int = 20

If you ever need to know the exact values of the data ranges, you can find them in the Scala REPL:

scala> Short.MinValue
res0: Short = −32768

scala> Short.MaxValue
res1: Short = 32767

scala> Int.MinValue
res2: Int = −2147483648

scala> Float.MinValue
res3: Float = −3.4028235E38



Thursday, 20 October 2016

Basics of Scala : Defining a Types in Scala : Day 2 Learnings

Scala has both numeric (e.g., Int and Double ) and nonnumeric types (e.g., String ) that can be used to define values and variables. These core types are the building blocks for all other types including objects and collections, and are themselves objects that have methods and operators that act on their data. 

Unlike Java and C there is no concept of a primitive type in Scala. While the Java Virtual Machine supports the primitive integer type int and the integer class Integer , Scala only supports its own integer class, Int .


Displays Scala’s numeric data types:


Name Description Size Min Max
Byte Signed integer 1 byte -127 128
Short Signed integer 2 bytes -32768 32767
Int Signed integer 4 bytes -2^31 2^31 - 1
Long Signed integer 8 bytes -2^63 2^63 - 1
Float Signed floating point 4 bytes n/a n/a
Double Signed floating point 8 bytes n/a n/a



In addition to those types, Boolean can have the values true or false.

Scala supports the ability to automatically convert numbers from one type to another in the order
Byte ➤ Short ➤ Int ➤ Long ➤ Float ➤ Double



Note: See the API documentation for java.lang.Float and java.lang.Double for a description of the calculated maximum and minimum values for these floating-point numbers.


Displays Scala’s numeric literals:

Literal Type Description
5 Int Unadorned integer literals are Int by default
0x0f Int The “0x” prefix denotes hexadecimal notation
5l Long The “l” suffix denotes a Long type
5.0 Double Unadorned decimal literals are Double by default
5f Float The “f” suffix denotes a Float type
5d Double The “d suffix denotes a Double type

Note: You can use either lowercase or uppercase letters in Scala’s literal types. The literal number 5L is the same as the literal number 5l .




I will cover each type in depth next articles.





Related Posts Plugin for WordPress, Blogger...