El sitio web de tnotstar

Lectura: «Scala for the Impatient» ―Cay S. Horstmann

Fuente: horstmann.scala-impatient.bk.epub.

“Scala has a concise syntax that is refreshing after the Java boilerplate. It runs on the Java virtual machine, providing access to a huge set of libraries and tools. It embraces the functional programming style without abandoning object orientation, giving you an incremental learning path to a new paradigm. The Scala interpreter lets you run quick experiments, which makes learning Scala very enjoyable. Last but not least, Scala is statically typed, enabling the compiler to find errors, so that you don’t waste time finding them—or not—later in the running program”

“Scala is a big language, but you can use it effectively without knowing all of its details intimately”

“en if you don’t want to design your own libraries, knowing about the tools that Scala provides for library designers can make you a more effective library user”

“please visit http://horstmann.com/scala"

“To start the Scala interpreter”

“Install Scala”

“Make sure that the scala/bin directory is on the PATH”

“Open a command shell in your operating system”

“Type scala followed by the Enter key”

“Now type commands followed by Enter. Each time, the interpreter displays the answer”

“The answer is given the name res0. You can use that name in subsequent computations”

“As you can see, the interpreter also displays the type of the result”

“Depending on how you launched the interpreter, you may be able to use tab completion for method names”

“In most implementations, you will see the previously issued commands, and you can edit them”

“As you can see, the Scala interpreter reads an expression, evaluates it, prints it, and reads the next expression. This is called the read-eval-print loop, or REPL”

“Technically speaking, the scala program is not an interpreter. Behind the scenes, your input is quickly compiled into bytecode, and the bytecode is executed by the Java virtual machine”

“Declaring Values and Variables”

“you can define your own names”

“val answer = 8 * 5 + 2”

“You can use these names in subsequent expressions”

“answer”

“A value declared with val is actually a constant—you can’t change its contents”

“To declare a variable whose contents can vary, use a var”

“var counter = 0”

“In Scala, you are encouraged to use a val unless you really need to change the contents”

“Perhaps surprisingly for Java or C++ programmers, most programs don’t need many var variables”

“Note that you need not specify the type of a value or variable. It is inferred from the type of the expression with which you initialize it”

“It is an error to declare a value or variable without initializing it.”

“However, you can specify the type if necessary”

“In Scala, the type of a variable or function is always written after the name of the variable or function”

“In Scala, semicolons are only required if you have multiple statements on the same line.”

“You can declare multiple values or variables together:”

“val xmax, ymax = 100 // Sets xmax and ymax to 100”

“var greeting, message: String = null // greeting and message are both strings, initialized with null”

“Like Java, Scala has seven numeric types: Byte, Char, Short, Int, Long, Float, and Double, and a Boolean type”

“However, unlike Java, these types are classes”

“There is no distinction between primitive types and class types in Scala”

“1.toString() // Yields the string “1"”

“1.to(10) // Yields Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)”

“In Scala, there is no need for wrapper types”

“It is the job of the Scala compiler to convert between primitive types and wrappers”

“Scala relies on the underlying java.lang.String class for strings. However, it augments that class with well over a hundred operations in the StringOps class”

““Hello”.intersect(“World”) // Yields “lo””

“remember to look into the StringOps class when you use the Scala documentation”

“Similarly, there are classes RichInt, RichDouble, RichChar, and so on. Each of them has a small set of convenience methods for acting on their poor cousins—Int, Double, or Char”

“Finally, there are classes BigInt and BigDecimal for computations with an arbitrary (but finite) number of digits”

“These are backed by the java.math.BigInteger and java.math.BigDecimal classes”

“they are much more convenient because you can use them with the usual mathematical operators”

“In Scala, you use methods, not casts, to convert between numeric types”

“Arithmetic operators in Scala work just as you would expect in Java or C++”

“The + - * / % operators do their usual job, as do the bit operators & | ^ »

“There is just one surprising aspect: These operators are actually methods”

“a + b”

“a.+(b)”

“Here, + is the name of the method”

“Scala has no silly prejudice against non-alphanumeric characters in method names. You can define methods with just about any symbols for names”

“In general, you can write”

“a method b”

“as a shorthand for”

“a.method(b)”

“where method is a method with two parameters (one implicit, one explicit)”

“For example, instead of 1.to(10) you can write 1 to 10”

“Scala does not have ++ or – operators. Instead, simply use +=1 or -=1”

“counter+=1 // Increments counter—Scala has no ++”

“Note that you can’t simply implement a method called ++. Since the Int class is immutable, such a method cannot change an integer value.”

“You can use the usual mathematical operators with BigInt and BigDecimal”

“val x: BigInt = 1234567890 x * x * x // Yields 1881676371789154860897069000”

“Scala allows you to define operators, leaving it up to you to use this feature with restraint and good taste.”

“Scala has functions in addition to methods”

“you need not call static methods from a class”

“sqrt(2) // Yields 1.4142135623730951 pow(2, 4) // Yields 16.0 min(3, Pi) // Yields 3.0”

“The mathematical functions are defined in the scala.math package. You can import them with the statement”

“import scala.math._ // In Scala, the _ character is a “wildcard,” like * in Java”

“To use a package that starts with scala., you can omit the scala prefix. For example, import math._ is equivalent to import scala.math._, and math.sqrt(2) is the same as scala.math.sqrt(2).”

“Scala doesn’t have static methods, but it has a similar feature, called singleton objects”

“Often, a class has a companion object whose methods act just like static methods do in Java”

“For example, the BigInt companion object to the BigInt class has a method probablePrime that generates a random prime number with a given number of bits:”

“BigInt.probablePrime(100, scala.util.Random)”

“Note that the call BigInt.probablePrime is similar to a static method call in Java”

“Here, Random is a singleton random number generator object, defined in the scala.util package. This is one of the few situations where a singleton object is better than a class”

“Scala methods without parameters often don’t use parentheses”

““Hello”.distinct”

“The rule of thumb is that a parameterless method that doesn’t modify the object has no parentheses”

“In Scala, it is common to use a syntax that looks like a function call. For example, if s is a string, then s(i) is the ith character of the string”

““Hello”(4) // Yields ‘o’”

“You can think of this as an overloaded form of the () operator. It is implemented as a method with the name apply.”

“That is, “Hello”(4) is a shortcut for”

““Hello”.apply(4)”

“When you look at the documentation for the BigInt companion object, you will see apply methods that let you convert strings or numbers to BigInt objects”

“BigInt(“1234567890”)”

“It yields a new BigInt object, without having to use new”

“Using the apply method of a companion object is a common Scala idiom for constructing objects”

“Java programmers use Javadoc to navigate the Java API. Scala has its own variant, called Scaladoc”

“You can browse Scaladoc online at www.scala-lang.org/api, but it is a good idea to download a copy from www.scala-lang.org/downloads#api and install it locally”

“Scaladoc can be a bit overwhelming. Keep these tips in mind”

“Remember to look into RichInt, RichDouble, and so on”

“The mathematical functions are in the package scala.math”

“Sometimes, you’ll see functions with funny names”

“A method tagged as implicit is an automatic conversion”

“Methods can have functions as parameters”

“You supply a function, often in a very compact notation, when you call the method”

“As an example, the call s.count(_.isUpper) counts the number of uppercase characters”

“You’ll occasionally run into classes such as Range or Seq[Char]. They mean what your intuition tells you—a range of numbers, a sequence of characters”

“Don’t get discouraged that there are so many methods. It’s the Scala way to provide lots of methods for every conceivable use case”

“don’t worry if you run into the occasional indecipherable incantation”

“In Java or C++, we differentiate between expressions (such as 3 + 4) and statements (for example, an if statement). An expression has a value; a statement carries out an action”

“In Scala, almost all constructs have values. This feature can make programs more concise and easier to read”

“An if expression has a value”

“A block has a value—the value of its last expression”

“The Scala for loop is like an “enhanced” Java for loop”

“Semicolons are (mostly) optional”

“The void type is Unit”

“Avoid using return in a function”

“Beware of missing = in a function definition”

“Exceptions work just like in Java or C++, but you use a “pattern matching” syntax for catch”

“Scala has no checked exceptions”

“Scala has an if/else construct with the same syntax as in Java or C++”

“in Scala, an if/else has a value, namely the value of the expression that follows the if or els”

“if (x > 0) 1 else -1”

“val s = if (x > 0) 1 else -1”

“This has the same effect as”

“if (x > 0) s = 1 else s = -1”

“the first form is better because it can be used to initialize a val. In the second form, s needs to be a var”

“As already mentioned, semicolons are mostly optional in Scala”

“The Scala if/else combines the if/else and ?: constructs that are separate in Java and C++”

“In Scala, every expression has a type”

“The type of a mixed-type expression, such as if (x > 0) “positive” else -1 is the common supertype of both branches”

“In this example, one branch is a java.lang.String, and the other an Int. Their common supertype is called Any”

“If the else part is omitted, for example in if (x > 0) 1 then it is possible that the if statement yields no value”

“in Scala, every expression is supposed to have some value. This is finessed by introducing a class Unit that has one value, written as ()”

“The if statement without an else is equivalent to”

“if (x > 0) 1 else ()”

“Think of () as a placeholder for “no useful value,” and think of Unit as the analog of void in Java or C++”

“Technically speaking, void has no value whereas Unit has one value that signifies “no value””

“Scala has no switch statement, but it has a much more powerful pattern matching mechanism”

“The REPL is more nearsighted than the compiler—it only sees one line of code at a time”

“when you type if (x > 0) 1 else if (x == 0) 0 else -1 the REPL executes if (x > 0) 1 and shows the answer”

“If you want to break the line before the else, use braces: if (x > 0) { 1 } else if (x == 0) 0 else -1”

“If you want to paste a block of code into the REPL without worrying about its nearsightedness, use paste mode. Type :paste”

“Then paste in the code block and type Ctrl+K. The REPL will then analyze the block in its entirety”

“In Scala—like in JavaScript and other scripting languages—a semicolon is never required if it falls just before the end of the line”

“A semicolon is also optional before an }, an else, and similar locations where it is clear from context that the end of a statement has been reached”

“However, if you want to have more than one statement on a single line, you need to separate them with semicolons”

“if (n > 0) { r = r * n; n -= 1 }”

“If you want to continue a long statement over two lines, you need to make sure that the first line ends in a symbol that cannot be the end of a statement”

“s = s0 + (v - v0) * t + // The + tells the parser that this is not the end 0.5 * (a - a0) * t * t”

“In the same spirit, Scala programmers favor the Kernighan & Ritchie brace style”

“if (n > 0) { r = r * n n -= 1 }”

“Many programmers coming from Java or C++ are initially uncomfortable about omitting semicolons. If you prefer to have them, just put them in—they do no harm”

“In Scala, a { } block contains a sequence of expressions, and the result is also an expression”

“The value of the block is the value of the last expression”

“This feature can be useful if the initialization of a val takes more than one step.”

“For example, Click here to view code image val distance = { val dx = x - x0; val dy = y - y0; sqrt(dx * dx + dy * dy) } The value of the { } block is the last expression, shown here in bold. The variables dx and dy, which were only needed as intermediate values in the computation, are neatly hidden from the rest of the program.”

“In Scala, assignments have no value—or, strictly speaking, they have a value of type Unit”

“A block that ends with an assignment statement, such as { r = r * n; n -= 1 } has a Unit value”

“Since assignments have Unit value, don’t chain them together. x = y = 1 // No The value of y = 1 is (), and it’s highly unlikely that you wanted to assign a Unit to x”

“To print a value, use the print or println function. The latter adds a newline character after the printout”

“There is also a printf function with a C-style format string”

“You can read a line of input from the console with the readLine function. To read a numeric, Boolean, or character value, use readInt, readDouble, readByte, readShort, readLong, readFloat, readBoolean, or readChar”

“The readLine method, but not the other ones, takes a prompt string: Click here to view code image val name = readLine(“Your name: “) print(“Your age: “) val age = readInt() printf(“Hello, %s! Next year, you will be %d.\n”, name, age + 1)”

“Scala has the same while and do loops as Java and C++”

“Scala has no direct analog of the for (initialize; test; update) loop”

“You can use a while loop. Or, you can use a for statement like this: for (i “The construct for (i “There is no val or var before the variable in the for loop”

“The type of the variable is the element type of the collection”

“The scope of the loop variable extends until the end of the loop”

“When traversing a string or array, you often need a range from 0 to n – 1. In that case, use the until method instead of the to method. It returns a range that doesn’t include the upper bound. Click here to view code image val s = “Hello” var sum = 0 for (i “var sum = 0 for (ch “In Scala, loops are not used as often as in other languages”

“Scala has no break or continue statements to break out of a loop”

“Here are a few options: 1. Use a Boolean control variable instead. 2. Use nested functions—you can return from the middle of a function. 3. Use the break method in the Breaks object: Click here to view code image import scala.util.control.Breaks._ breakable { for (…) { if (…) break; // Exits the breakable block … } }”

“You can have multiple generators of the form variable “Each generator can have a guard, a Boolean condition preceded by if: Click here to view code image for (i “You can have any number of definitions, introducing variables that can be used inside the loop: Click here to view code image for (i “When the body of the for loop starts with yield, then the loop constructs a collection of values, one for each iteration: Click here to view code image for (i “The generated collection is compatible with the first generator. Click here to view code image for (c “If you prefer, you can enclose the generators, guards, and definitions of a for loop inside braces, and you can use newlines instead of semicolons to separate them: for { i “Scala has functions in addition to methods. A method operates on an object, but a function doesn’t”

“To define a function, you specify the function’s name, parameters, and body like this: Click here to view code image def abs(x: Double) = if (x >= 0) x else -x”

“You must specify the types of all parameters. However, as long as the function is not recursive, you need not specify the return type”

“If the body of the function requires more than one expression, use a block. The last expression of the block becomes the value that the function returns”

“For example, the following function returns the value of r after the for loop. def fac(n : Int) = { var r = 1 for (i “It is possible to use return as in Java or C++, to exit a function immediately, but that is not commonly done in Scala”

“While there is nothing wrong with using return in a named function (except the waste of seven keystrokes), it is a good idea to get used to life without return”

“Pretty soon, you will be using lots of anonymous functions, and there, return doesn’t return a value to the caller. It breaks out to the enclosing named function. Think of return as a kind of break statement for functions, and only use it when you want that breakout functionality.”

“With a recursive function, you must specify the return type”

“For example, Click here to view code image def fac(n: Int): Int = if (n “Some programming languages (such as ML and Haskell) can infer the type of a recursive function, using the Hindley-Milner algorithm. However, this doesn’t work well in an object-oriented language. Extending the Hindley-Milner algorithm so it can handle subtypes is still a research problem.”