9780596155957
IntroducingScala.html

Chapter 1. Zero to Sixty: Introducing Scala

Why Scala?

Today’s enterprise and Internet applications must balance a number of concerns. They must be implemented quickly and reliably. New features must be added in short, incremental cycles. Beyond simply providing business logic, applications must support secure access, persistence of data, transactional behavior, and other advanced features. Applications must be highly available and scalable, requiring designs that support concurrency and distribution. Applications are networked and provide interfaces for both people and other applications to use.

To meet these challenges, many developers are looking for new languages and tools. Venerable standbys like Java, C#, and C++ are no longer optimal for developing the next generation of applications.

If You Are a Java Programmer…

Java was officially introduced by Sun Microsystems in May of 1995, at the advent of widespread interest in the Internet. Java was immediately hailed as an ideal language for writing browser-based applets, where a secure, portable, and developer-friendly application language was needed. The reigning language of the day, C++, was not suitable for this domain.

Today, Java is more often used for server-side applications. It is one of the most popular languages in use for the development of web and enterprise applications.

However, Java was a child of its time. Now it shows its age. In 1995, Java provided a syntax similar enough to C++ to entice C++ developers, while avoiding many of that language’s deficiencies and “sharp edges”. Java adopted the most useful ideas for the development problems of its era, such as object-oriented programming (OOP), while discarding more troublesome techniques, such as manual memory management. These design choices struck an excellent balance that minimized complexity and maximized developer productivity, while trading-off performance compared to natively-compiled code. While Java has evolved since its birth, many people believe it has grown too complex without adequately addressing some newer development challenges.

Developers want languages that are more succinct and flexible to improve their productivity. This is one reason why so-called “scripting” languages like Ruby and Python have become more popular recently.

The never-ending need to scale is driving architectures towards pervasive concurrency. However, Java’s concurrency model, which is based on synchronized access to shared, mutable state, results in complex and error-prone programs.

While the Java language is showing its age, the Java Virtual Machine (JVM) on which it runs continues to shine. The optimizations performed by today’s JVM are extraordinary, allowing byte code to outperform natively-compiled code in many cases. Today, many developers believe that using the JVM with new languages is the path forward. Sun is embracing this trend by employing many of the lead developers of JRuby and Jython, which are JVM ports of Ruby and Python, respectively.

The appeal of Scala for the Java developer is that it gives you a newer, more modern language, while leveraging the JVM’s amazing performance and the wealth of Java libraries that have been developed for over a decade.

If You Are a Ruby, Python, etc. Programmer…

Dynamically typed languages like Ruby, Python, Groovy, JavaScript, and Smalltalk offer very high productivity due to their flexibility, powerful metaprogramming, and elegance.

Despite their productivity advantages, dynamic languages may not be the best choices for all applications, particularly for very large code bases and high-performance applications. There is a longstanding, spirited debate in the programming community about the relative merits of dynamic vs. static typing. Many of the points of comparison are somewhat subjective. We won’t go through all the arguments here, but we will offer a few thoughts for consideration.

Optimizing the performance of a dynamic language is more challenging than for a static language. In a static language, optimizers can exploit the type information to make decisions. In a dynamic language, fewer such clues are available for the optimizer, making optimization choices harder. While recent advancements in optimizations for dynamic languages are promising, they lag behind the state of the art for static languages. So, if you require very high performance, static languages are probably a safer choice.

Static languages can also benefit the development process. IDE features like autocompletion (sometimes called code sense) are easier to implement for static languages, again because of the extra type information available. The more explicit type information in static code promotes better “self-documentation”, which can be important for communicating intent among developers, especially as a project grows.

When using a static language, you have to think about appropriate type choices more often, which forces you to weigh design choices more carefully. While this may slow down daily design decisions, thinking through the types in the application can result in a more coherent design over time.

Another small benefit of static languages is the extra checking the compiler performs. We think this advantage is often oversold, as type mismatch errors are a small fraction of the runtime errors you typically see. The compiler can’t find logic errors, which are far more significant. Only a comprehensive, automated test suite can find logic errors. For dynamically typed languages, the tests must cover possible type errors, too. If you are coming from a dynamically typed language, you may find that your test suites are a little smaller, as a result, but not that much smaller.

Many developers who find static languages too verbose often blame static typing for the verbosity when the real problem is a lack of type inference. In type inference, the compiler infers the types of values based on the context. For example, the compiler will recognize that x = 1 + 3 means that x must be an integer. Type inference reduces verbosity significantly, making the code feel more like code written in a dynamic language.

We have worked with both static and dynamic languages, at various times. We find both kinds of languages compelling for different reasons. We believe the modern software developer must master a range of languages and tools. Sometimes, a dynamic language will be the right tool for the job. At other times, a static language like Scala is just what you need.

Introducing Scala

Scala is a language that addresses the major needs of the modern developer. It is a statically typed, mixed-paradigm, JVM language with a succinct, elegant, and flexible syntax, a sophisticated type system, and idioms that promote scalability from small, interpreted scripts to large, sophisticated applications. That’s a mouthful, so let’s look at each of those ideas in more detail.

Statically Typed

As we described in the previous section, a statically typed language binds the type to a variable for the lifetime of that variable. In contrast dynamically typed languages bind the type to the actual value referenced by a variable, meaning that the type of a variable can change along with the value it references.

Of the set of newer JVM languages, Scala is one of the few that is statically typed and it is the best known among them.

Mixed Paradigm - Object Oriented Programming

Scala fully supports Object Oriented Programming (OOP). Scala improves upon Java’s support for OOP with the addition of traits, a clean way of implementing classes using mixin composition. Scala’s traits work much like Ruby’s modules. If you’re a Java programmer, think of traits as unifying interfaces with their implementations.

In Scala, everything is really an object. Scala does not have primitive types, like Java. Instead all numeric types are true objects. However, for optimal performance, Scala uses the underlying primitives types of the runtime whenever possible. Also, Scala does not support “static” or class-level members of types, since they are not associated with an actual instance. Instead, Scala supports a singleton object construct to support those cases where exactly one instance of a type is needed.

Mixed Paradigm - Functional Programming

Scala fully supports Functional Programming (FP). FP is a programming paradigm that is older than OOP, but it has been sheltered in the ivory towers of academia until recently. Interest in FP is increasing because of the ways it simplifies certain design problems, especially concurrency. “Pure” functional languages don’t allow for any mutable state, thereby avoiding the need for synchronization on shared access to mutable state. Instead, programs written in pure functional languages communicate by passing messages between concurrent, autonomous processes. Scala supports this model with its Actors library, but it allows for both mutable and immutable variables.

Functions are “first-class” citizens in FP, meaning they can be assigned to variables, passed to other functions, etc., just like other values. This feature promotes composition of advanced behavior using primitive operations. Because Scala adheres to the dictum that everything is an object, functions are themselves objects in Scala.

Scala also offers closures, a feature that dynamic languages like Python and Ruby have adopted from the functional programming world, and one sadly absent from recent versions of Java. Closures are functions that reference variables from the scope enclosing the function definition. That is, the variables aren’t passed in as arguments or defined as local variables within the function. A closure "closes around" these references, so the function invocation can safely refer to the variables even when the variables have gone out of scope! Closures are such a powerful abstraction that object systems and fundamental control structures are often implemented using them.

A JVM and .NET Language

While Scala is primarily known as a JVM language, meaning that Scala generates JVM byte code, a .NET version of Scala is also under development that generates CLR byte code. When we refer to the underlying “runtime”, we will usually discuss the JVM, but most of what we will say applies equally to both runtimes. When we discuss JVM-specific details, they generalize to the .NET version, except where noted.

The Scala compiler uses clever techniques to map Scala extensions to valid byte-code idioms. From Scala, you can easily invoke byte code that originated as Java source (for the JVM) or C# source (for .NET). Conversely, you can invoke Scala code from Java, C#, etc.. Running on the JVM and CLR allows the Scala developer to leverage available libraries and to interoperate with other languages hosted on those runtimes.

A Succinct, Elegant, and Flexible Syntax

Java syntax can be verbose. Scala uses a number of techniques to minimize unnecessary syntax, making Scala code as succinct as code in most dynamically typed languages. Type inference minimizes the need for explicit type information in many contexts. Declarations of types and functions are very concise.

Scala allows function names to include non-alphanumeric characters. Combined with some syntactic sugar, this feature permits the user to define methods that look and behave like operators. As a result, libraries outside the core of the language can feel “native” to users.

A Sophisticated Type System
Scala extends the type system of Java with more flexible generics and a number of more advanced typing constructs. The type system can be intimidating at first, but most of the time you won’t need to worry about the advanced constructs. Type inference helps by automatically inferring type signatures, so that the user doesn’t have to provide trivial type information manually. When you need them, though, the advanced type features provide you with greater flexibility for solving design problems in a type-safe way.
Scalable - Architectures

Scala is designed to scale from small, interpreted scripts to large, distributed applications. Scala provides four language mechanisms that promote scalable composition of systems: 1) explicit selftypes, 2) abstract type members and generics, 3) nested classes, and 4) mixin composition using traits.

No other language provides all these mechanisms. Together, they allow applications to be constructed from reusable “components” in a type-safe and succinct manner. As we will see, many common design patterns and architectural techniques like dependency injection are easy to implement in Scala without the boilerplate code or lengthy XML configuration files that can make Java development tedious.

Scalable - Performance
Because Scala code runs on the JVM and the CLR, it benefits from all the performance optimizations provided by those runtimes and all the third-party tools that support performance and scalability, such as profilers, distributed cache libraries, clustering mechanisms, etc. If you trust Java’s and C#'s performance, you can trust Scala’s performance. Of course, some particular constructs in the language and some parts of the library may perform significantly better or worse than alternative options in other languages. As always, you should profile your code and optimize it when necessary.

It might appear that OOP and FP are incompatible. In fact, a design philosophy of Scala is that OOP and FP are more synergistic than opposed. The features of one approach can enhance the other.

In FP, functions have no side effects and variables are immutable, while in OOP, mutable state and side effects are common, even encouraged. Scala lets you choose the approach that best fits your design problems. Functional programming is especially useful for concurrency, since it eliminates the need to synchronize access to mutable state. However, “pure” FP can be restrictive. Some design problems are easier to solve with mutable objects.

The name Scala is a contraction of the words scalable language. While this suggests that the pronunciation should be scale-ah, the creators of Scala actually pronounce it scah-lah, like the Italian word for “stairs”. That is, the two “a’s” are pronounced the same.

Scala was started by Martin Odersky in 2001. Martin is a professor in the School of Computer and Communication Sciences at the Ecole Polytechnique Fédérale de Lausanne (EPFL). He spent his graduate years working in the group headed by Niklaus Wirth, of Pascal fame. Martin worked on Pizza, an early functional language on the JVM. He later worked on GJ, a prototype of what later became Generics in Java, with Philip Wadler of Haskell fame. Martin was hired by Sun Microsystems to produce the reference implementation of javac, the Java compiler that ships with the Java Developer Kit (JDK) today.

Martin Odersky’s background and experience are evident in the language. As you learn Scala, you come to understand that it is the product of carefully considered design decisions, exploiting the state of the art in type theory, OOP and FP. Martin’s experience with the JVM is evident in Scala’s elegant integration with that platform. The synthesis it creates between OOP and FP is an excellent "best of both worlds" solution.

The Seductions of Scala

Today, our industry is fortunate to have a wide variety of language options. The power, flexibility, and elegance of dynamically typed languages have made them very popular again. Yet, the wealth of Java and .NET libraries and the performance of the JVM and CLR meet many practical needs for enterprise and Internet projects.

Scala is compelling because it feels like a dynamically typed scripting language, due to its succinct syntax and type inference. Yet, Scala gives you all the benefits of static typing, a modern object model, functional programming, and an advanced type system. These tools let you build scalable, modular applications that can reuse legacy Java and .NET APIs and leverage the performance of the JVM and CLR.

Scala is a language for professional developers. Compared to languages like Java and Ruby, Scala is a more difficult language to master, because it requires competency with OOP, FP, and static typing to use it most effectively. It is tempting to prefer the relative simplicity of dynamically-typed languages. Yet, this simplicity can be deceptive. In a dynamically typed language, it is often necessary to use metaprogramming features to implement advanced designs. While metaprogramming is powerful, using it well takes experience and the resulting code tends to be hard to understand, maintain, and debug. In Scala, many of the same design goals can be achieved in a type-safe manner by exploiting its type system and mixin composition through traits.

We feel that the extra effort required day to day to use Scala will promote more careful reflection about your designs. Over time, this discipline will yield more coherent, modular, and maintainable applications. Fortunately, you don’t need all of the sophistication of Scala all of the time. Much of your code will have the simplicity and clarity of code written in your favorite dynamically-typed language.

An alternative strategy is to combine several, simpler languages, e.g., Java for object-oriented code and Erlang for functional, concurrent code. Such a decomposition can work, but only if your system decomposes cleanly into such discrete parts and your team can manage a heterogeneous environment. Scala is attractive for situations where a single, all-in-one language is preferred. That said, Scala code can happily coexist with other languages, especially on the JVM or .NET.

Installing Scala

To get up and running as quickly as possible, this section describes how to install the command line tools for Scala, which are all you need to work with the examples in the book. For details on using Scala in various editors and IDEs, see Integration with IDEs in Chapter 14, Scala Tools, Libraries and IDE Support. The examples used in this book were written and compiled using Scala version 2.7.5.final, the latest release at the time of this writing, and “nightly builds” of Scala version 2.8.0, which may be finalized by the time you read this.

Note

Version 2.8 introduces many new features, which we will highlight throughout the book.

We will work with the JVM version of Scala in this book. First, you must have Java 1.4 or greater installed (1.5 or greater is recommended). If you need to install Java, go to http://www.java.com/en/download/manual.jsp and follow the instructions to install Java on your machine.

The official Scala web site is http://www.scala-lang.org/. To install Scala, go to the downloads page, http://www.scala-lang.org/downloads. Download the installer for your environment and follow the instructions on the downloads page.

The easiest cross-platform installer is the IzPack installer. Download the Scala jar file, either scala-2.7.5.final-installer.jar or scala-2.8.0.N-installer.jar, where N is the latest release of the 2.8.0 version. Go to the download directory in a terminal window, and install Scala with the java command. Assuming you downloaded scala-2.8.0.final-installer.jar, run the following command, which will guide you through the process.

java -jar scala-2.8.0.final-installer.jar

Tip

On Mac OS X, the easiest route to a working Scala installation is via MacPorts. Follow the installation instructions at http://www.macports.org/, then sudo port install scala. You’ll be up and running in a few minutes.

Throughout this book, we will use the symbol scala-home to refer to the “root” directory of your Scala installation.

Note

On Unix, Linux, and Mac OS X systems, you will need to run this command as the root user or using the sudo command if you want to install Scala under a system directory, e.g., scala-home = /usr/local/scala-2.8.0.final.

As an alternative, you can download and expand the compressed tar file (e.g., scala-2.8.0.final.tgz) or zip file (scala-2.8.0.final.zip). On Unix-like systems, expand the compressed file into a location of your choosing. Afterwards, add the scala-home/bin subdirectory in the new directory to your PATH. For example, if you installed into /usr/local/scala-2.8.0.final, then add /usr/local/scala-2.8.0.final/bin to your PATH.

To test your installation, run the following command on a command line.

scala -version

We’ll learn more about the scala command-line tool later. You should get something like the following output:

Scala code runner version 2.8.0.final -- Copyright 2002-2009, LAMP/EPFL

Of course, the version number you see will be different if you installed a different release. From now on, when we show command output that contains the version number, we’ll show it as version 2.8.0.final.

Congratulations, you have installed Scala! If you get an error message along the lines of scala: command not found, make sure your environment’s PATH is set properly to include the correct bin directory.

Note

Scala versions 2.7.X and earlier are compatible with JDK 1.4 and later. Scala version 2.8 drops 1.4 compatibility. Note that Scala uses many JDK classes as its own, for example, the String class. On .NET, Scala uses the corresponding .NET classes.

You can also find downloads for the API documentation and the sources for Scala itself on the same downloads page.

For More Information

As you explore Scala, you will find other useful resources that are available on http://scala-lang.org. You will find links for development support tools and libraries, tutorials, the language specification [ScalaSpec2009], and academic papers that describe features of the language.

The documentation for the Scala tools and APIs are especially useful. You can browse the API at http://www.scala-lang.org/docu/files/api/index.html. This documentation was generated using the scaladoc tool, analogous to Java’s javadoc tool. See the section called “The scaladoc Command Line Tool” in Chapter 14, Scala Tools, Libraries and IDE Support for more information.

You can also download a compressed file of the API documentation for local browsing using the appropriate link on the downloads page, http://www.scala-lang.org/downloads, or you can install it with the sbaz package tool, as follows.

sbaz install scala-devel-docs

sbaz is installed in the same bin directory as the scala and scalac command-line tools. The installed documentation also includes details on the scala tool chain (including sbaz) and code examples. For more information on the Scala command-line tools and other resources, see Chapter 14, Scala Tools, Libraries and IDE Support.

A Taste of Scala

It’s time to whet your appetite with some real Scala code. In the following examples, we’ll describe just enough of the details so you understand what’s going on. The goal is to give you a sense of what programming in Scala is like. We’ll explore the details of the features in subsequent chapters.

For our first example, you could run it one of two ways, interactively or as a “script”.

Let’s start with the interactive mode. Start the scala interpreter by typing scala and the return key on your command line. You’ll see the following output. (Some of the version numbers may vary.)

Welcome to Scala version 2.8.0.final (Java ...).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

The last line is the prompt that is waiting for your input. The interactive mode of the scala command is very convenient for experimentation (see the section called “The scala Command Line Tool” in Chapter 14, Scala Tools, Libraries and IDE Support for more details). An interactive interpreter like this is called a REPL: Read, Evaluate, Print, Loop.

Type in the following two lines of code.

val book = "Programming Scala"
println(book)

The actual input and output should look like the following.

scala> val book = "Programming Scala"
book: java.lang.String = Programming Scala

scala> println(book)
Programming Scala

scala>

The first line uses the val keyword to declare a read-only variable named book. Note that the output returned from the interpreter shows you the type and value of book. This can be very handy for understanding complex declarations. The second line prints the value of book, which is “Programming Scala”.

Tip

Experimenting with the scala command in the interactive mode (REPL) is a great way to learn the details of Scala.

Many of the examples in this book can be executed in the interpreter like this. However, it’s often more convenient to use the second option we mentioned, writing Scala scripts in a text editor or IDE and executing them with the same scala command. We’ll do that for most of the remaining examples in this chapter.

In your text editor of choice, save the Scala code in the following example to a file named upper1-script.scala in a directory of your choosing.

// code-examples/IntroducingScala/upper1-script.scala

class Upper {
  def upper(strings: String*): Seq[String] = {
    strings.map((s:String) => s.toUpperCase())
  }
}

val up = new Upper
Console.println(up.upper("A", "First", "Scala", "Program"))

This Scala script converts strings to upper case.

By the way, that’s a comment on the first line (with the name of the source file for the code example). Scala follows the same comment conventions as Java, C#, C++, etc. A // comment goes to the end of a line, while a /* comment */ can cross line boundaries.

To run this script, go to a command window, change to the same directory and run the following command.

scala upper1-script.scala

The file is interpreted, meaning it is compiled and executed in one step. You should get the following output:

Array(A, FIRST, SCALA, PROGRAM)

In this example, the upper method in the Upper class (no pun intended) converts the input strings to upper case and returns them in an array. The last line in the example converts four strings and prints the resulting Array.

Let’s examine the code in detail, so we can begin to learn Scala syntax. There are a lot of details in just six lines of code! We’ll explain the general ideas here. All the ideas used in this example will be explained more thoroughly in later sections of the book.

In the example, the Upper class begins with the class keyword. The class body is inside the outer most curly braces {…}.

The upper method definition begins on the second line with the def keyword, followed by the method name and an argument list, the return type of the method, an equals sign ‘=’, then the method body.

The argument list in parentheses is actually a variable-length argument list of String's, indicated by the String* type following the colon. That is, you can pass in as many comma-separated strings as you want (including an empty list). These strings are stored in a parameter named strings. Inside the method, strings is actually an Array.

Note

When explicit type information for variables is written in the code, these type annotations follow the colon after the item name (i.e., Pascal-like syntax). Why doesn’t Scala follow Java conventions? Recall that type information is often inferred in Scala (unlike Java), meaning we don’t always show type annotations explicitly. Compared to Java’s type item convention, the item: type convention is easier for the compiler to analyze unambiguously when you omit the colon and the type annotation and just write item.

The method return type appears after the argument list. In this case, the return type is Seq[String], where Seq ("sequence") is a particular kind of collection. It is a parameterized type (like a generic type in Java), parameterized here with String. Note that Scala uses square brackets […] for parameterized types, while Java uses angle brackets <…>.

Note

Scala allows angle brackets to be used in method names, e.g., naming a “less than” method < is common. So, to avoid ambiguities, Scala uses square brackets instead for parameterized types. They can’t be used in method names. Allowing < and > in method names is why Scala doesn’t follow Java’s convention for angle brackets.

The body of the upper method comes after the equals sign ‘=’. Why an equals sign? Why not just curly braces {…}, like in Java? Because semicolons, function return types, method arguments lists, and even the curly braces are sometimes omitted, using an equals sign prevents several possible parsing ambiguities. Using an equals sign also reminds us that even functions are values in Scala, which is consistent with Scala’s support of functional programming, described in more detail in Chapter 8, Functional Programming in Scala.

The method body calls the map method on the strings array, which takes a function literal as an argument. Function literals are “anonymous” functions. They are similar to lambdas, closures, blocks, or procs in other languages. In Java, you would have to use an anonymous inner class here that implements a method defined by an interface, etc.

In this case, we passed in the following function literal.

(s:String) => s.toUpperCase()

It takes an argument list with a single String argument named s. The body of the function literal is after the “arrow”, =>. It calls toUpperCase() on s. The result of this call is returned by the function literal. In Scala, the last expression in a function is the return value, although you can have return statements elsewhere, too. The return keyword is optional here and it is rarely used, except when returning out of the middle of a block (e.g., in an if statement).

Note

The value of the last expression is the default return value of a function. No return is required.

So, map passes each String in strings to the function literal and builds up a new collection with the results returned by the function literal.

To exercise the code, we create a new Upper instance and assign it to a variable named up. As in Java, C#, and similar languages, the syntax new Upper creates a new instance. The up variable is declared as a read-only “value” using the val keyword.

Finally, we call the upper method on a list of strings, and print out the result with Console.println(…), which is equivalent to Java’s System.out.println(…).

We can actually simplify our script even further. Consider this simplified version of the script.

// code-examples/IntroducingScala/upper2-script.scala

object Upper {
  def upper(strings: String*) = strings.map(_.toUpperCase())
}

println(Upper.upper("A", "First", "Scala", "Program"))

This code does exactly the same thing, but with a third fewer characters.

On the first line, Upper is now declared as an object, which is a singleton. We are declaring a class, but the Scala runtime will only ever create one instance of Upper. (You can’t write new Upper, for example.) Scala uses objects for situations where other languages would use “class-level” members, like statics in Java. We don’t really need more than one instance here, so a singleton is fine.

Note

Why doesn’t Scala support statics? Since everything is an object in Scala, the object construct keeps this policy consistent. Java’s static methods and fields are not tied to an actual instance.

Note that this code is fully thread safe. We don’t declare any variables that might cause thread-safety issues. The API methods we use are also thread-safe. Therefore, we don’t need multiple instances. A singleton object works fine.

The implementation of upper on the second line is also simpler. Scala can usually infer the return type of the method (but not the types of the method arguments), so we drop the explicit declaration. Also, because there is only one expression in the method body, we drop the braces and put the entire method definition on one line. The equals sign before the method body tells the compiler, as well as the human reader, where the method body begins.

We have also exploited a short-hand for the function literal. Previously we wrote it as follows.

(s:String) => s.toUpperCase()

We can shorten it to the following expression.

_.toUpperCase()

Because map takes one argument, a function, we can use the “placeholder” indicator _ instead of a named parameter. That is, the _ acts like an anonymous variable, to which each string will be assigned before toUpperCase is called. Note that the String type is inferred for us, too. As we will see, Scala uses _ as a “wild card” in several contexts.

You can also use this short-hand syntax in some more complex function literals, as we will see in Chapter 3, Rounding Out the Essentials.

On the last line, using an object rather than a class simplifies the code. Instead of creating an instance with new Upper, we can just call the upper method on the Upper object directly (note how this looks like the syntax you would use when calling static methods in a Java class).

Finally, Scala automatically imports many methods for I/O, like println, so we don’t need to call Console.println(). We can just use println by itself. (See the section called “The Predef Object” in Chapter 7, The Scala Object System for details on the types and methods that are automatically imported or defined.)

Let’s do one last refactoring; let’s convert the script into a compiled, command-line tool.

// code-examples/IntroducingScala/upper3.scala

object Upper {
  def main(args: Array[String]) = {
    args.map(_.toUpperCase()).foreach(printf("%s ",_))
    println("")
  }
}

Now the upper method has been renamed main. Because Upper is an object, this main method works exactly like a static main method in a Java class. It is the entry point to the Upper application.

Note

In Scala, main must be a method in an object. (In Java, main must be a static method in a class.) The command line arguments for the application are passed to main in an array of strings, e.g., args: Array[String].

The first line inside the main method uses the same short-hand notation for map that we just examined.

args.map(_.toUpperCase())...

The call to map returns a new collection. We iterate through it with foreach. We use a _ placeholder shortcut again in another function literal that we pass to foreach. In this case, each string in the collection is passed as an argument to printf.

...foreach(printf("%s ",_))

To be clear, these two uses of ‘_’ are completely independent of each other. Method chaining and function-literal shorthands, as in this example, can take some getting used to, but once you are comfortable with them, they yield very readable code with minimal use of temporary variables.

The last line in main adds a final linefeed to the output.

This time, you must first compile the code to a JVM .class file using scalac.

scalac upper3.scala

You should now have a file named Upper.class, just as if you had just compiled a Java class.

Note

You may have noticed that the compiler did not complain when the file was named upper3.scala and the object was named Upper. Unlike Java, the file name doesn’t have to match the name of the type with public scope. (We’ll explore the visibility rules in the section called “Visibility Rules” in Chapter 5, Basic Object-Oriented Programming in Scala.) In fact, unlike Java, you can have as many public types in a single file as you want. Furthermore, the directory location of a file doesn’t have to match the package declaration. However, you can certainly follow the Java conventions, if you want to.

Now, you can execute this command for any list of strings. Here is an example.

scala -cp . Upper Hello World!

The -cp . option adds the current directory to the search “class path”. You should get the following output.

 HELLO WORLD!

Therefore, we have met the requirement a programming language book must start with a “hello world” program.

A Taste of Concurrency

There are many reasons to be seduced by Scala. One reason is the Actors API included in the Scala library, which is based on the robust Actors concurrency model built into Erlang [Haller2007]. Here is an example to whet your appetite.

In the Actor model of concurrency [Agha1987], independent software entities called actors share no state information with each other. Instead, they communicate by exchanging messages. By eliminating the need to synchronize access to shared, mutable state, it is far easier to write robust, concurrent applications.

In this example, instances in a geometric Shape hierarchy are sent to an actor for drawing on a display. Imagine a scenario where a rendering “farm” generates scenes in an animation. As the rendering of a scene is completed, the shape “primitives” that are part of the scene are sent to an actor for a display subsystem.

To begin, we define a Shape class hierarchy.

// code-examples/IntroducingScala/shapes.scala

package shapes {
  class Point(val x: Double, val y: Double) {
    override def toString() = "Point(" + x + "," + y + ")"
  }

  abstract class Shape() {
    def draw(): Unit
  }

  class Circle(val center: Point, val radius: Double) extends Shape {
    def draw() = println("Circle.draw: " + this)
    override def toString() = "Circle(" + center + "," + radius + ")"
  }

  class Rectangle(val lowerLeft: Point, val height: Double, val width: Double)
        extends Shape {
    def draw() = println("Rectangle.draw: " + this)
    override def toString() =
      "Rectangle(" + lowerLeft + "," + height + "," + width + ")"
  }

  class Triangle(val point1: Point, val point2: Point, val point3: Point)
        extends Shape {
    def draw() = println("Triangle.draw: " + this)
    override def toString() =
      "Triangle(" + point1 + "," + point2 + "," + point3 + ")"
  }
}

The Shape class hierarchy is defined in a shapes package. You can declare the package using Java syntax, but Scala also supports a syntax similar to C#'s “namespace” syntax, where the entire declaration is scoped using curly braces, as used here. The Java-style package declaration syntax is far more commonly used, however, being both compact and readable.

The Point class represents a two-dimensional point on a plane. Note the argument list after the class name. Those are constructor parameters. In Scala, the whole class body is the constructor, so you list the arguments for the primary constructor after the class name and before the class body. (We’ll see how to define auxiliary constructors in the section called “Constructors in Scala” in Chapter 5, Basic Object-Oriented Programming in Scala.) Because we put the val keyword before each parameter declaration, they are automatically converted to read-only fields with the same names with public reader methods of the same name. That is, when you instantiate a Point instance, e.g., point, you can read the fields using point.x and point.y. If you want mutable fields, then use the keyword var. We’ll explore variable declarations and the val and var keywords in the section called “Variable Declarations” in Chapter 2, Type Less, Do More.

The body of Point defines one method, an override of the familiar toString method in Java (like ToString in C#). Note that Scala, like C#, requires the override keyword whenever you override a concrete method. Unlike C#, you don’t have to use a virtual keyword on the original concrete method. In fact, there is no virtual keyword in Scala. As before, we omit the curly braces "{…}" around the body of toString, since it has only one expression.

Shape is an abstract class. Abstract classes in Scala are similar to those in Java and C#. We can’t instantiate instances of abstract classes, even when all their field and method members are concrete.

In this case, Shape declares an abstract draw method. We know it is abstract because it has no body. No abstract keyword is required on the method. Abstract methods in Scala are just like abstract methods in Java and C#. (See the section called “Overriding Members of Classes and Traits” in Chapter 6, Advanced Object-Oriented Programming In Scala for more details.)

The draw method returns Unit, which is a type that is roughly equivalent to void in C-derived languages like Java, etc. (See the section called “The Scala Type Hierarchy” in Chapter 7, The Scala Object System for more details.)

Circle is declared as a concrete subclass of Shape. It defines the draw method to simply print a message to the console. Circle also overrides toString.

Rectangle is also a concrete subclass of Shape that defines draw and overrides toString. For simplicity, we assume it is not rotated relative to the X and Y axes. Hence, all we need is one point, the lower left-hand point will do, and the height and width of the rectangle.

Triangle follows the same pattern. It takes three Points as its constructor arguments.

Both draw methods in Circle, Rectangle, and Triangle use this. As in Java and C#, this is how an instance refers to itself. In this context, where this is the right-hand side of a String concatenation expression (using the plus sign), this.toString is invoked implicitly.

Note

Of course, in a real application, you would not implement drawing in “domain model” classes like this, since the implementations would depend on details like the operating system platform, graphics API, etc. We will see a better design approach when we discuss traits in Chapter 4, Traits.

Now that we have defined our shapes types, let’s return to actors. We define an Actor that receives “messages” that are shapes to draw.

// code-examples/IntroducingScala/shapes-actor.scala

package shapes {
  import scala.actors._
  import scala.actors.Actor._

  object ShapeDrawingActor extends Actor {
    def act() {
      loop {
        receive {
          case s: Shape => s.draw()
          case "exit"   => println("exiting..."); exit
          case x: Any   => println("Error: Unknown message! " + x)
        }
      }
    }
  }
}

The actor is declared to be part of the shapes package. Next, we have two import statements.

The first import statement imports all the types in the scala.actors package. In Scala, the underscore _ is used the way the star * is used in Java.

Note

Because * is a valid character for a function name, it can’t be used as the import wild card. Instead, _ is reserved for this purpose.

All the methods and public fields from Actor are imported. These are not static imports from the Actor type, as they would be in Java. Rather, they are imported from an object that is also named Actor. The class and object can have the same name, as we will see in the section called “Companion Objects” in Chapter 6, Advanced Object-Oriented Programming In Scala.

Our actor class definition, ShapeDrawingActor, is an object that extends Actor (the type, not the object). The act method is overridden to do the unique work of the actor. Because act is an abstract method, we don’t need to explicitly override it with the override keyword. Our actor loops indefinitely, waiting for incoming messages.

During each pass in the loop, the receive method is called. It blocks until a new message arrives. Why is the code after receive enclosed in curly braces ({…}) and not parentheses ((…))? We will learn later that there are cases where this substitution is allowed and it is quite useful (see Chapter 3, Rounding Out the Essentials). For now, what you need to know is that the expressions inside the braces constitute a single function literal that is passed to receive. This function literal does a pattern match on the message instance to decide how to handle the message. Because of the case clauses, it looks like a typical switch statement in Java, for example, and the behavior is very similar.

The first case does a type comparison with the message. (There is no explicit variable for the message instance in the code; it is inferred.) If the message is of type Shape, the first case matches. The message instance is cast to a Shape and assigned to the variable s, then the draw method is called on it.

If the message is not a Shape, the second case is tried. If the message is the string "exit", the actor prints a message and terminates execution. Actors should usually have a way to exit gracefully!

The last case clause handles any other message instance, thereby functioning as the default case. The actor reports an error and then drops the message. Any is the parent of all types in the Scala type hierarchy, like Object is the root type in Java and other languages. Hence, this case clause will match any message of any type. Pattern matching is eager; we have to put this case clause at the end, so it doesn’t consume the messages we are expecting!

Recall that we declared draw as an abstract method in Shape and we implemented draw in the concrete subclasses. Hence, the code in the first case statement invokes a polymorphic operation.

Finally, here is a script that uses the ShapeDrawingActor actor.

// code-examples/IntroducingScala/shapes-actor-script.scala

import shapes._

ShapeDrawingActor.start()

ShapeDrawingActor ! new Circle(new Point(0.0,0.0), 1.0)
ShapeDrawingActor ! new Rectangle(new Point(0.0,0.0), 2, 5)
ShapeDrawingActor ! new Triangle(new Point(0.0,0.0),
                                 new Point(1.0,0.0),
                                 new Point(0.0,1.0))
ShapeDrawingActor ! 3.14159

ShapeDrawingActor ! "exit"

The shapes in the shapes package are imported.

The ShapeDrawingActor actor is started. By default, it runs in its own thread (there are alternatives we will discuss in Chapter 9, Robust, Scalable Concurrency with Actors), waiting for messages.

Five messages are sent to the actor, using the syntax actor ! message. The first message sends a Circle instance. The actor “draws” the circle. The second message sends a Rectangle message. The actor “draws” the rectangle. The third message does the same thing for a Triangle. The fourth message sends a Double that is approximately equal to Pi. This is an unknown message for the actor, so it just prints an error message. The final message sends an “exit” string, which causes the actor to terminate.

To try out the actor example, start by compiling the first two files. You can get the sources from the O’Reilly download site (see the section called “Getting the Code Examples” in the Preface for details) or you can create them yourself.

Use the following command to compile the files.

 scalac shapes.scala shapes-actor.scala

While the source file names and locations don’t have to match the file contents, you will notice that the generated class files are written to a shapes directory and there is one class file for each class we defined. The class file names and locations must conform to the JVM requirements.

Now you can run the script to see the actor in action.

 scala -cp . shapes-actor-script.scala

You should see the following output.

Circle.draw: Circle(Point(0.0,0.0),1.0)
Rectangle.draw: Rectangle(Point(0.0,0.0),2.0,5.0)
Triangle.draw: Triangle(Point(0.0,0.0),Point(1.0,0.0),Point(0.0,1.0))
Error: Unknown message! 3.14159
exiting...

For more on Actors, see Chapter 9, Robust, Scalable Concurrency with Actors.

Recap and What’s Next

We made the case for Scala and got you started with two sample Scala programs, one of which gave you a taste of Scala’s Actors library for concurrency. Next, we’ll dive into more Scala syntax, emphasizing various keystroke-economical ways of getting lots of work done.

Site last updated on: April 15, 2011 at 06:39:28 AM PDT
Cover for Programming Scala

View 3 comments

  1. prawsthorne – Posted May 26, 2009

    Don't quite know where to put this comment, but would be nice to see mention of where a scalable language fits within a cloud filled internet. I like things to scale (duhhh) and it may be worthwhile to include how scala could fit within an ASP cloud model of deployment.

  2. deanwampler – Posted June 3, 2009

    Not sure where to discuss it either. I guess the "default" answer is that Scala fills the same niche as Java, C#, etc. while perhaps also covering some territory for which a "pure" scripting language like Ruby would be an optimal fit.

  3. deanmarc – Posted Sept. 24, 2009

    I am still also trying to work my head around the concise meaning and concept of 'scalable language' as compared to scalable design, scalable infrastructure, and etc.

Add a comment

View 1 comment

  1. derekmahar – Posted July 7, 2009

    Favour active over passive voice: change "Scala was started by Martin Odersky in 2001" to "Martin Odersky started Scala in 2001".

Add a comment

View 3 comments

  1. clojure – Posted May 20, 2009

    Scala's syntax is not particularly succinct, even for statically typed language, compare it to Haskell, or ML based languages.

  2. derekmahar – Posted July 7, 2009

    Scala is succinct relative to Java. Which ML languages run on the JVM? Is Clojure, a LISP dialect for the JVM, more concise than Scala?

  3. deanmarc – Posted Sept. 24, 2009

    To be honest, I am currently trying to promote and evangelize colleagues in companies I consult for, staff in Javasparks(our small company focusing on Java and now Scala), partners, peers, and I am even planning a Scala R&D lab here in the Philippines called ScaLab =D. I have taught many classes and spoke in several talks before.

    Apparently, one of the key defining characteristic I find people respond to is sexiness. When converting people COBOL and NATURAL for example to C or C++ or Java, they seem to respond immediately, not with the conciseness but with the readability of it.

    I am still trying to get my head around this also. I would appreciate some ideas though.

Add a comment

View 5 comments

  1. clojure – Posted May 20, 2009

    Don't you have kind of a contradiction there: "Scala is more difficult to master" and "While metaprogramming is powerful, using it well takes experience, etc"

    What does mastering really mean anyway. To get the same thing done in Scala or Ruby can be as hard if done properly (with good maintainability etc), or do you disagree?

  2. deanwampler – Posted June 3, 2009

    Both Scala and metaprogramming like in Ruby take time to master. Assuming equal teams of "experts", I'm asserting that Scala code will be easier to maintain and evolve over the long-term than roughly-equivalent ruby metaprogramming code. That's my gut feeling...

  3. psalvitti – Posted June 6, 2009

    I might tone this down a bit ... I mean comparatively speaking, C++, Java, Ruby, et al (statically typed languages) all require competency in OOP, FP and static typing that you indicate for Scala. As Henrik said, what does "mastering" really mean? I can point to "experienced" developers (name the language) that still write horrible code.

  4. derekmahar – Posted July 7, 2009

    Put a different way: how do you measure the level of difficulty of a programming language and how this may translate to programmer productivity or suitability to solve particular problems? Experience? Empirical evidence? Anecdotal evidence? Programmer surveys? Programming language popularity?

    Unfortunately, programming language choice seems largely driven by familiarity, popularity, and perceived ease of learning rather than by suitability to task and longer term program maintainability.

  5. deanmarc – Posted Sept. 24, 2009

    As with many new languages that became mainstream, I have this observation that most people's consideration boils down to paradigm, feature, transition, and perceived benefit to career.

    Mastery is really difficult to assess without knowing from what perspective.

    Teaching Java was, at the beginning, quite awkward compared to C or C++, but then after sometime, it becomes easier to elaborate and associate.

    Statistically, mastery becomes easier for most not because it easy in its essence but when a few mavericks and pioneers gain enough experience in simplifying it to a level where they can replicate themselves quicker.

    I'm not sure if I am articulating myself well, here. =)

Add a comment

View 1 comment

  1. psalvitti – Posted June 6, 2009

    Ah, by "extra effort" do you mean proper design to begin with?

Add a comment

View 1 comment

  1. asookazian – Posted July 8, 2009

    You may want to point out that using Java and Erlang for the same project is most likely a poor alternative to using Java and/or Scala on their own. E.g. how would a Java class/component call an Erlang method (i.e. integration issues)?

    This is the advantage of using Groovy or Scala (or other JVM-compatible languages) for integration with existing JEE or .NET systems.

Add a comment

View 1 comment

  1. AmigoNico – Posted March 25, 2011

    As of the end of March 2011, the RC1 of 2.9.0 is available. 2.8.0 was an important release which overhauled the collections API and added significant enhancements. There was also a 2.8.1 release which fixed some bugs in 2.8.0. The main new feature of 2.9.0 is the ability to easily parallelize operations on collections.

Add a comment

View 1 comment

  1. AmigoNico – Posted March 25, 2011

    For security reasons, it's important to keep your Java installation up to date. 1.5 is really quite old; there have been a couple of dozen Java 6 releases. Performance has improved as well.

Add a comment

View 2 comments

  1. ranbo – Posted Oct. 3, 2010

    On Mac OS X 10.6, macports didn't work for me. I downloaded the installer jar and used "sudo java -jar scala-2.8.0.final-installer.jar" from the terminal. I chose the location /usr/local/scala. Then I had to edit ~/.bash_profile to do "export PATH=$PATH:/usr/local/scala/bin". At that point, "scala -version" worked.

  2. mike_english – Posted March 29, 2011

    The scala macports package has been replaced by numbered versions so the correct command to fetch and install the package is now something like: sudo port install scala27

Add a comment

View 2 comments

  1. xsolomon – Posted Sept. 28, 2009

    Shouldn't that be scala_home rather than scala-home (underscore rather than hyphen)?

  2. emptist – Posted May 10, 2010

    export PATH=$PATH:/usr/local/scala-2.8.0.final/bin

Add a comment

View 1 comment

  1. bz7 – Posted May 21, 2009

    Test

Add a comment

View 3 comments

  1. prasincs – Posted Feb. 23, 2010

    It has to be strings.toList.map((s:String) => s.toUpperCase())

  2. John_Svazic – Posted Dec. 4, 2010

    Unfortunately this code does not compile. Is the code that follows the class definition need to be in it's own method perhaps?

  3. John_Svazic – Posted Dec. 4, 2010

    Here are the errors that I'm seeing with Scala 2.7.7:

    (virtual file):1: error: '}' expected but eof found. object Main { ^ one error found !!! discarding discarding (fragment of upper1-script.scala) john@john-desktop:~/source/scala$ scala upper1-script.scala (virtual file):1: error: '}' expected but eof found. object Main { ^ one error found !!! discarding discarding (fragment of upper1-script.scala)

Add a comment

View 4 comments

  1. Alexei – Posted Feb. 19, 2011

    the // comment can be nested

  2. Alexei – Posted Feb. 19, 2011

    and can contain nested comments

  3. Alexei – Posted Feb. 19, 2011

    comments could be nested

  4. Alexei – Posted Feb. 19, 2011
    • A comment can contain nested comments

Add a comment

View 5 comments

  1. delitescere – Posted May 23, 2009

    As it's one of Scala's selling points, might as well keep things as concise as possible (or at least make a note of not being so to aid with initial learning).

    • (s:String) the type specification is redundant
    • Console. is also redundant
  2. delitescere – Posted May 23, 2009

    Of course you point this out half a page down. Ah well. :-)

  3. diathesis – Posted June 20, 2009

    This example doesn't seem to work in the current Eclipse IDE; it's fine at the command-line, but shows that the IDE support is still suspect. :/

  4. deanwampler – Posted July 9, 2009

    @Geoffrey, I didn't try it any of the IDEs. We tried to avoid any dependencies on using them.

  5. MidGe – Posted Sept. 30, 2009

    Ok, first stumbling block... I am getting a "Unable to establish connection to compilation daemon" message. Using Kubuntu Jaunty and Scala code runner version 2.7.3final. Since invoking scala -version works, I must be missing something else. Since there has been no introduction to the architecture of Scala, I will have to do some searching. It may be good to have an broader introduction about the installation of the various modules (?) of Scala.

    Ummm... trying to compile(?) using scalac upper1-script.scala throws compilation errors!

    I think I must find some other tutorial that deal with basic issues, first, and then I may come back to this one. Sorry guys!

Add a comment

View 3 comments

  1. jungho – Posted May 23, 2009

    C# venerable? Please qualify... Given the evolution of C# language from 1.0 - next major version 4.0, not to mention enhancements to the class library and the CLR, it is not clear to me how C# can be viewed as venerable...

  2. deanwampler – Posted June 3, 2009

    It's true that Microsoft has kept C# moving forward at a faster rate than Java. However, It is still based on design choices that I think are sub-optimal, like not using type inferencing from the very beginning. C# won't be able to move to more comprehensive type inferencing than it supports now because of the potential parsing ambiguities its syntax would cause.

  3. asookazian – Posted July 8, 2009

    as I understand it, the significant advantage that Erlang and Scala offer over Java and C#, for example, are concurrent programming for use in multi-core envmts. And Scala is even more attractive in a J2SE or J2EE platform because it runs in a JVM (compiles to Java bytecode).

    Microsoft .NET has just recently implemented the MVC design pattern in ASP.NET:

    http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx

    In many ways, .NET is far behind but traction in JEE frameworks other than Spring and Hibnerate (e.g. Seam 2.x) is very low and EE 6 with Web Beans may not have a high adoption rate in the enterprise deployments either...

Add a comment

View 4 comments

  1. brl – Posted May 19, 2009

    It seems a little bit strange to describe garbage collection as 'discarding more troublesome techniques such as manual memory management'. Maybe you could name garbage collection directly as one of the useful ideas that Java adopted.

  2. ederandres_an – Posted May 29, 2009

    Java solved many plumbing problems related with C++ programming such as static and dynamic memory management. Also, Java developers had a more legible, well looked sintaxis. So we can say that Java is a cleaner version of C++.

    -- this is based on Andrew Troelsen's book: http://books.google.com/books?id=VGT1_UJzjM0C&pg=PA1371&dq=.NET+Apress#PPA7,M1

  3. ederandres_an – Posted May 29, 2009

    oops. Page 8: http://books.google.com/books?id=VGT1_UJzjM0C&pg=PA1371&dq=.NET+Apress#PPA8,M1

  4. deanwampler – Posted June 3, 2009

    Yea, our intention isn't to provide a detailed comparison between C++ and Java, but just to indicate the sea change Java represented at the time and to argue that we need another sea change now.

Add a comment

View 4 comments

  1. Leonidas – Posted May 20, 2009

    I'd say that not only Ruby has become more popular, but also Python and Clojure, another new popular language for the JVM.

  2. deanwampler – Posted June 3, 2009

    Will make this statement more 'inclusive".

  3. asookazian – Posted July 8, 2009

    what about Groovy? we can use Groovy in Seam apps...

    "I can honestly say if someone had shown me the Programming Scala book by by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy."

    http://java.dzone.com/articles/scala-long-term-replacement

  4. deanmarc – Posted Sept. 24, 2009

    :D Groovy... ...

Add a comment

View 4 comments

  1. clojure – Posted May 20, 2009

    Scala is OO based which is almost inherently embraces mutability. This is a long way from Clojure's approach. Actors model is sufficient only for a limited segment of problems.

  2. deanwampler – Posted June 3, 2009

    I think we'll see clojure style mutability approaches, like STM, work their way back into Scala and maybe even Java, as options.

  3. maddalab – Posted July 26, 2009

    Just a comment on the writing, this line is difficult to understand

    The never-ending need to scale is driving architectures towards pervasive concurrency.

    I think you meant the following The never-ending need to scale "software" is driving "application" architectures towards pervasive concurrency.

    and I would rather like The never-ending need to scale software is driving application developers towards concurrent architectures.

    scale Hardware/Software? architectures Hardware/Software/

    Am I to read the original line as

    The never-ending need to scale software is driving software architectures towards pervasive concurrency.

    The never-ending need to scale software is driving hardware architectures towards pervasive concurrency.

    The never-ending need to scale hardware is driving hardware architectures towards pervasive concurrency.

    or one of the alternatives

  4. deanmarc – Posted Sept. 24, 2009

    I agree with the ambiguity with the first sentence.

Add a comment

View 8 comments

  1. GarrickWest – Posted Aug. 25, 2009

    You may may want to update "Sun is embracing this trend..." to "Sun has embraced this trend..." given that the full JRuby team jumped ship to Engine Yard last month (see http://www.pcworld.com/article/169145/suns_jruby_team_jumps_ship_to_engine_yard.html).

  2. nathany – Posted April 3, 2010

    Since this writing, the JRuby developers have moved to being employed by EngineYard.

  3. gsauthof – Posted May 15, 2010

    Please name three cases, where JVM byte code outperforms natively-compiled code in time and space.

  4. hugo – Posted May 21, 2010

    "Sun" is gone, folks :)

  5. dennisn – Posted June 18, 2010

    I believe the early implementations of Groovy (which also compiles to JVM code) were also supported by Sun, although it has more recently been purchase by Spring Frameworks.

  6. Frank – Posted July 2, 2010

    This is just not true. Bytecode will never outperform natively-compiled-code. You could argue that the optimizaion of bytecode is better but can you proof that for a secific case.

  7. jnorrid – Posted Feb. 13, 2011

    Sun is no longer free-standing corporate entity. Should reference Oracle Corporation as the current owner/maintainer of the Java Language, Java SDK, and Java Virtual Machine (JVM) / Java Runtime Environment (JRE) technologies. Might also add something in there about how the recent acquisition has created what is perceived by many as a divide between Big Software and the Open Source teams that have contributed so much to the language over the past 16 years through the JCP or Java Community Process. It's yet another reason Java is showing it's age: the fact that using it has become political.

  8. jnorrid – Posted Feb. 13, 2011

    Oracle owns Java, not Sun.

Add a comment

View 1 comment

  1. RahulG – Posted Feb. 5, 2010

    I feel you have mistaken "statically typed" and "dynamically typed" for "strongly typed" and "weakly typed" respectively.

Add a comment

View 5 comments

  1. ricky_clarkson – Posted May 20, 2009

    I'd say that static typing isn't only about what types variables have, but also what types expressions have.

  2. gedb – Posted July 8, 2009

    Given the headings, a Java programmer may skip this section thinking that it is not relevant to them. If they do, they will miss the whole Static vs Dynamic discussion.

  3. sjk – Posted Sept. 2, 2009

    Minor quibble, but: You say "Informally, in static typing, a variable is bound to a particular type for its lifetime." I don't like the word "bound" in this context, since variable binding should refer to its value (or more precisely, location where that value exists) and not its type.

  4. vasanth – Posted April 5, 2010

    dynamic languages are easier to program but harder to maintain

  5. fijimf – Posted Feb. 13, 2012

    That quote from Pierce is wrong. It should read: "A type system is a tractable syntactic method for proving the absence of certain program behaviors."

Add a comment

View 1 comment

  1. darkcloud – Posted Aug. 21, 2011

    IDE features like autocompletion (sometimes called code sense) are easier to implement for static languages,

    Just look at PyCharm, a Python IDE. It does such a good job at autocompletion, and all other features, that latest NetBeans and RSA (Eclipse based) does not shine at all. So IMO this whole section is only an opinion, not a fact.

Add a comment

View 3 comments

  1. maddalab – Posted July 26, 2009

    As you mentioned previously pro and cons of static and dynamic typing are subjective, but this paragraph is a flame bait

    "forces you to weigh design choices more carefully."

    Caring about your craft forces you to weigh design choices more carefully and lead to coherent design over time.

    I have seen plenty of code in Java that returns Object and invokes methods using reflection over the returned typed. What was needed was an interface that all the returned types returned. Static typing does not by itself lead to better design.

  2. deanmarc – Posted Sept. 24, 2009

    I agree with this totally.

  3. toddmowen – Posted April 9, 2011

    On the other hand, static typing can sometimes also result in a less coherent design, when additional entities have to be introduced merely to satisfy the type checker.

Add a comment

View 2 comments

  1. smn – Posted April 26, 2010

    Don't you mean "If you are coming from a static typed language....test suites are a little smaller"? As you pointed out above: dyn language tests: logic errors + type errors static language tests : logic errors

  2. verisimilidude – Posted June 15, 2010

    Back in the early 90's I was on the backend team that wrote (in C) a network interface for the front end of a PC application. The front end was written in Smalltalk and in three months the front end team got all the screens programmed, a task I would have estimated to take 9 months with a similar sized team working in C and win32. It then took us six months of testing to get all the type errors out.

Add a comment

View 1 comment

  1. clojure – Posted May 20, 2009

    This paragraph could be made much concise without losing meaning.

Add a comment

View 2 comments

  1. derekmahar – Posted July 6, 2009

    Statically typed languages also bind a type to every value (or object). Otherwise, polymorphism through dynamic binding would not be possible.

  2. maddalab – Posted July 26, 2009

    Surprised you did no mention type inference here (or any of the sub-sections below). Isn't Scala also one of the few "type-inferenced" languages on the JVM?

Add a comment

View 2 comments

  1. diathesis – Posted June 19, 2009

    As a Java programmer, I don't find the idea of unifying interfaces with implementations to be an illuminating metaphor. It just makes traits sound like classes. Mixin is a clearer term, as is the reference to Ruby modules.

  2. stevenelliottjr – Posted Sept. 15, 2010

    It sounds like everything ruby wants to be at the end of the day. I think Ruby is a fine language, but I am a big fan of static typing. To be able have the best of OO and static typing sounds wonderful.

Add a comment

View 2 comments

  1. deanmarc – Posted Sept. 24, 2009

    Whatever happened to closures in Java?

  2. nathany – Posted April 3, 2010

    "functional languages communicate by passing messages" - that's a generalization based on how some functional languages (like Erlang) work.

Add a comment

View 1 comment

  1. robertkuhar – Posted Sept. 8, 2009

    What are "explicit selftypes"? Please explain.

Add a comment

View 4 comments

  1. Leonidas – Posted May 20, 2009

    You could elaborate about the OOP bits a litte bit more, since it is most likely the thing that Scala beginners coming from most other languages are most familiar with. You could for example say that there are no primitive types which makes the OOP types integrate better into the code freeing the programmer from bothering with this (or just say "everything is an object" which is more relevant to OOP than FP).

  2. ricky_clarkson – Posted May 20, 2009

    "Of the set of newer JVM languages, Scala is the only one that is statically typed."

    With the exceptions of CAL and JavaFX.

  3. clojure – Posted May 20, 2009

    Can you really trust Scala's speed, for example: http://villane.wordpress.com/2008/02/13/scala-for-avs-while-update/

    I think there is some other issues like reflection based implementation on structural types, boxed primitives are not well optimized (afaik).

    It's unfortunate thing, but you just can't blindly depend that compiler optimizes things to Java-speed; you have to code Java-like.

  4. deanwampler – Posted June 3, 2009

    @Marek. Good point. We cover this later in the book, but I'll add a paragraph about it here.

    @Ricky, I'll clarify to say one of the "few"...

    @Henrik, I'll add a disclaimer that there can be areas where performance is poor.

Add a comment

View 2 comments

  1. jkwatson – Posted March 7, 2010

    How is this a refactoring? More than the design has changed here. The behavior has changed.

  2. jkwatson – Posted March 7, 2010

    How is this refactoring? This is changing the program's entire purpose!

Add a comment

View 3 comments

  1. maddalab – Posted July 26, 2009

    In the example I believe it is good scala convention to omit the '=' sign as the main method finished with a println, i.e. has result type Unit (would be the same if println was omitted as foreach has a result type of Unit)

    The convention is used to indicate "procedural" (relies on side effects, printf) behavior of main

  2. raam – Posted Aug. 11, 2009

    Why doesn't something like the following work?:

    args.foreach(printf("%s ",_.toUpperCase()))

  3. brevius – Posted Oct. 4, 2009

    I like the comparisons to Java, for those who know Java; however, this paragraph doesn't make sense unless one knows Java.

Add a comment

View 1 comment

  1. robcd – Posted June 20, 2009

    Note .. main must be a (possibly inherited) method in an object?

Add a comment

View 1 comment

  1. TimMacEachern – Posted June 23, 2009

    It is difficult to tell that the character before the underscore here is a comma, not a period. Perhaps it should be mentioned explicitly in the text. As well, function parameters are usually separated using a comma and a space, so the curried function here would appear better as:

    printf("%s ", _)
    

    An off-hand reference to the arguments could include the word comma to differentiate this from the _.functionName syntax above: "Here the underscore is given as the second parameter of the function, separated from the print format string by a comma, as usual."

Add a comment

View 2 comments

  1. dreamtangerine – Posted Sept. 10, 2010

    Why don't follow java file names and directories rules ?

  2. swidnikk – Posted March 15, 2011

    I noticed after compiling (version 2.7.7, Mac) that there are several other files created. What are they? Upper$$anonfun$main$1.class
    Upper$$anonfun$main$2.class Upper$.class

Add a comment

View 3 comments

  1. jasonh – Posted May 20, 2009

    Typo above. Should read ... adds the current directory...

  2. deanwampler – Posted June 3, 2009

    Thanks! Will fix

  3. ldeck – Posted Oct. 16, 2009

    The addition of the classpath is unnecessary.

Add a comment

View 1 comment

  1. Viktor Nordling – Posted July 17, 2011

    whet -> wet

Add a comment

View 4 comments

  1. jwolski – Posted July 11, 2009

    Circle and Rectangle extend Shape, but Triangle extends Shape(). If this wasn't intentional, it might confuse readers.

  2. deanwampler – Posted July 12, 2009

    Good catch. Thanks. Will fix.

  3. maddalab – Posted July 26, 2009

    Thought I would add that up until this point in the samples, it is possible to use the Scala REPL, which I find convenient. However with the introduction of packages it would not be possible to use the REPL as the REPL does not support packages. Might be worth noting for readers like me who type packages in the REPL.

  4. brevius – Posted Oct. 4, 2009

    If the Java style syntax is more commonly used, more compact, and more readable, why is the C# style being used in this introductory chapter? I suspect the reader is also assumed to know what the Java style syntax would be.

Add a comment

View 4 comments

  1. steven807 – Posted May 20, 2009

    Typo: "auxiliary constructors in in "

  2. deanwampler – Posted June 3, 2009

    Another production problem that has since been fixed. Sorry.

  3. yingliu97 – Posted March 6, 2011

    The field name and the reader method can not be the same name because all values (fields, methods, packages, and singleton objects) share the same namespace. See Program in Scala book, page 217.

  4. yingliu97 – Posted March 6, 2011

    val implicitly defines a getter accessor.

Add a comment

View 2 comments

  1. maddalab – Posted July 26, 2009

    Not certain about this, however I also omit the () braces around methods with no args along with the {} braces as it enforces the uniform access principle in Scala. Clients of the code do not need to know that they are invoking a function or accessing a member

    override def toString() = "Point(" + x + "," + y + ")"

    would becode

    override def toString = "Point(" + x + "," + y + ")"

    not certain about its applicability to methods defined in the Java API being overridden in Scala.

  2. brevius – Posted Oct. 5, 2009

    Unless you are assuming that the reader knows Java or C#, you may wish to point out that the "+" operator applied to strings concatenates them.

Add a comment

View 1 comment

  1. brevius – Posted Oct. 5, 2009

    Again, keeping with the theme that the reader may not know Java or C#, you may wish to indicate what can be done with abstract classes.

Add a comment

View 2 comments

  1. bfollek – Posted June 19, 2009

    Maybe a quick explanation of "Unit" here?

  2. deanwampler – Posted July 12, 2009

    Thanks. Oversight. Will fix.

Add a comment

View 1 comment

  1. brevius – Posted Oct. 5, 2009

    Again, no need to assume knowledge about other languages. You can say "Although draw will be a method that doesn't return anything that we will be using, because Scala is a typesafe language it must still have a type. Scala calls this type Unit. It is roughly equivalent to void..."

Add a comment

View 1 comment

  1. RogerAlexander – Posted Feb. 23, 2012

    "override" does not need to be specified for Circle.draw() since Shape.draw() is not concrete.

Add a comment

View 1 comment

  1. maddalab – Posted July 26, 2009

    we assume it is not rotated relative to the X and Y axes

    Ehh??? Do not understand what is being said and am not certain it needs to be said.

Add a comment

View 1 comment

  1. generex – Posted Sept. 20, 2009

    "Both draw methods", you're referring to 3 draw methods, so using "Both" sounds wrong.

Add a comment

View 3 comments

  1. TimMacEachern – Posted June 23, 2009

    In "Of course, in a real..." you're talking down to your readers. There's no need for that, certainly at the start of the book. Just drop the "Of course".

  2. deanwampler – Posted July 12, 2009

    Not my intention. Rather I was talking "up" to them, because most experienced devs. would implement this separation of concerns and I want them to know we'll learn techniques for doing that later on.

  3. maddalab – Posted July 26, 2009

    since the implementations would depend on details like the operating system platform, graphics API

    not when running on the JVM. I agree that draw should not be in the domain model classes for the reason in your comment above "separation of concerns" not for the reasons in the Notes section.

    OS is a concern that is abstracted away by the virtual machine

Add a comment

View 10 comments

  1. maddalab – Posted July 26, 2009

    ShapeDrawingActor is also defined as a singleton (object). Assume that is necessary, but why?

  2. maddalab – Posted July 26, 2009

    ShapeDrawingActor is also defined as a singleton (object). Assume that is necessary, but why?

  3. ghexsel – Posted Nov. 4, 2009

    why is the equals sign not needed?

    def act() = { ... }

  4. markvgti – Posted May 3, 2010

    How come the act() method doesn't require an "=" after it in this listing? So far that's how we've been declaring methods.

  5. keccs – Posted Dec. 30, 2010

    Some syntax highlighting would be nice for Scala keywords. It may look as if loop and receive are keywords when in fact they are functions.

  6. keccs – Posted Dec. 31, 2010

    Syntax highlighting would be nice, since it's difficult to tell keywords like object from functions like loop and receive

  7. pavan – Posted March 23, 2011

    if act is overridden, then we have to add override keyword! isnt it?

  8. pavan – Posted March 23, 2011

    override def act() or just def act()

  9. Dave Aronson – Posted Sept. 5, 2011

    @maddalab: My guess would be that it's necessary so that you don't have multiple things each trying to draw a shape on the screen. That might in fact be useful, to have a pool of drawing actors, but unless you KNOW you're going to need it, better not to get complex at this point. YAGNI....

  10. Dave Aronson – Posted Sept. 5, 2011

    @ghexsel and @markvgti: I just started learning Scala a few days ago so I'm not entirely sure, but I think that's because it's not returning a value. On the other claw, neither did Upper.main. Maybe it's just required if you're returning a value, and otherwise optional and won't hurt anything....

Add a comment

View 1 comment

  1. brevius – Posted Oct. 5, 2009

    I'll stop banging on about this point in a moment; the point being that things could be rewritten to not assume familiarity with other languages. Here, for instance, something like "Notice how the underscore, _, is used again in this context as a sort of wildcard indicating that the whole package is to be made available. This is similar to the way the star, *, is used in Java."

Add a comment

View 3 comments

  1. jasonh – Posted May 20, 2009

    Typo last sentence: as we will see in ...

  2. deanwampler – Posted June 3, 2009

    Missing links now fixed.

  3. brevius – Posted Oct. 5, 2009

    I like to know where things come from, so "Here, we will be using blahblah and blah from scala.actors; and our actor will need to extend Actor."

Add a comment

View 1 comment

  1. diathesis – Posted June 22, 2009

    A reference to a section that talks about how this inferrence works would be useful; I'm curious, but I've got no link to click.

Add a comment

View 3 comments

  1. robcd – Posted June 20, 2009

    Don't you mean, 'if we don't want it to silently consume the messages we aren't expecting'?

  2. robcd – Posted June 20, 2009

    Okay, no you don't mean that. But maybe you could emphasize 'at the end' a bit more, and point out that unexpected messages would still be consumed (but silently) if it wasn't included.

  3. ldeck – Posted Oct. 17, 2009

    'case _' will also work in place of 'case x:Any'

Add a comment

View 3 comments

  1. generex – Posted May 21, 2009

    Hopefully we also implemented draw in Triangle!

  2. deanwampler – Posted July 9, 2009

    Thanks. We fixed that one ;)

  3. brevius – Posted Oct. 5, 2009

    The conclusion doesn't follow from the premises. The conclusion about it being a polymorphic operation follows from there being different subtypes of Shape. As draw will be invoked in the case statement, it is, of course necessary that draw be implemented in the subtypes of Shape.

Add a comment

View 3 comments

  1. mellouk – Posted Feb. 8, 2010

    Is there also a built-in thread pool support?

  2. k21 – Posted March 4, 2011

    When I tried this example for the first time, it only printed out the information about the Circle. I tried to add Thread.sleep(1000) at the end of the script and then it worked. It looks like otherwise the program exits before the ShapeDrawingActor processes all the messages.

  3. Jack Viers – Posted Sept. 11, 2011

    If you are running the new Scala code runner version 2.9.1.final -- Copyright 2002-2011, LAMP/EPFL, you need to wrap your loop body in () loop(receive({...body as in example})). I assume this is because loop requires something that returns Unit (the default return type, equivalent to void) and receive requires an anonymous function (the function body from the ShapeDrawingActor example).

    If you then compile and run the shapes-actor-script it will run as expected.

Add a comment

View 3 comments

  1. chifazo – Posted May 30, 2009

    Typo: it says "The four message sends...", it should say "The fourth message sends...".

  2. deanwampler – Posted June 3, 2009

    Thanks!

  3. brevius – Posted Oct. 5, 2009

    Damn, I see that this is already published. I just stumbled across it from Reddit, and happily started making comments; which I now see are completely useless. Thanks for making it available to read. It might be time to turn the comments off, though.

Add a comment

View 1 comment

  1. ldeck – Posted Oct. 17, 2009

    again the addition of a classpath is unnecessary as they're all in scope. So this works fine: scala shapes-actor-script.scala

Add a comment

View 7 comments

  1. tomxtobin – Posted Jan. 26, 2011

    I see the output most of the time that I run scala -cp . shapes-actor-script.scala but perhaps 10% of the time I see no output whatseover. A couple of times I saw only the first line (Circle.draw: Circle(Point(0.0,0.0),1.0)) and nothing else.

  2. luveenw – Posted March 12, 2011

    I don't reliably get this output running Scala 2.7.7. The result varies from no output at all, through some draw methods printing, to all of the expected output. What could be causing this issue? Is there some system dependency underlying the Actors API and concurrency in Scala? FYI, I haven't made any changes to the source provided in the downloadable examples.

  3. luveenw – Posted March 12, 2011

    I don't reliably get this output running Scala 2.7.7. The result varies from no output at all, through some draw methods printing, to all of the expected output. What could be causing this issue? Is there some system dependency underlying the Actors API and concurrency in Scala? FYI, I haven't made any changes to the source provided in the downloadable examples.

  4. virtualonliner – Posted March 22, 2011

    After running the script shapes-actor-script.scala, the output is just empty! I tried it with my own edited files as well as the source from O'Reilly. In both cases, the output is just empty. There is no compile error or runtime error!

  5. hnkang – Posted Aug. 27, 2011

    For those who are getting inconsistent results with this example, you have to compile, then run the compiled code. Read the next section to learn how to do this. http://stackoverflow.com/questions/4333294/scala-actor-in-script-mode

  6. daniel.crowley.wilson – Posted Nov. 11, 2011

    Running Scala 2.8.2, I don't see any output when I run the shapes actor script. Then again, I don't see how it could reliably work, because the script could complete before the actor receives the messages. If I invoke the script's command in the interactive code runner, it works as expected.

  7. karelbilek – Posted March 18, 2012

    Runner 2.9.1.1. I am following the book rigorously and all I am getting here is

    shapes-actor-script.scala:1: error: not found: value shapes import shapes._

    ^

    one error found

    there IS a directory shapes, there ARE the class files inside, and yet I am still getting that.

    edit:nevermind, found it here. Gotta love SO!

    stackoverflow.com/questions/4955055/scala-question-about-examples-in-programming-scala-book

    Edited on March 18, 2012, 9:48 p.m. PDT

Add a comment

View 3 comments

  1. ajasmin – Posted Aug. 23, 2010

    I wasn't seeing any output until I added a Thread.sleep(1000) at the end of the shapes-actor-script.scala script.

    I don't have enough experience with Scala yet to understand if this is a problem with my installation or with the sample itself.

    If that makes any difference I'm using Scala 2.8 and Java 1.6 on a slow Windows XP netbook

  2. rskokan – Posted April 2, 2011

    I've copy-pasted the 3 last shape examples and after compiling the 2 files and when launching the script, sometimes the actor receives only 1 message, sometimes all of them:

    c:devprojscalaProgrammingScalach01>scalac shapes.scala shapes-actor.scala

    c:devprojscalaProgrammingScalach01>scala -cp . shapes-actor-script.scala Circle.draw: Circle(Point(0.0,0.0),1.0) c:devprojscalaProgrammingScalach01>scala -cp . shapes-actor-script.scala Circle.draw: Circle(Point(0.0,0.0),1.0) Rectangle.draw: Rectangle(Point(0.0,0.0),2.0,5.0) Triangle.draw: Triangle(Point(0.0,0.0),Point(1.0,0.0),Point(0.0,1.0)) Error: Unknown message! 3.14159 exiting...

    Is it because, as you wrote, "By default, it runs in its own thread" and the main thread may exit earlier, before the actor's thread finishes?

  3. rskokan – Posted April 2, 2011

    test

Add a comment

View 2 comments

  1. toolbear74 – Posted Dec. 25, 2009

    The benefits of keystroke reduction are overrated. The real value of concision is in savings from repeated readings or editing of existing code. Otherwise clever keyboard macros and autocomplete would be all that was necessary to get a lot of work done with Java. It might be that scala's concision saves on both creation and maintenance, but emphasis should be on the latter.

  2. Jack Viers – Posted Sept. 11, 2011

    Keystroke reduction is of great value, and not overrated. Fewer characters = smaller source code size. Also means that you have less boilerplate to work with and to remember, easing the use of textual editors like vi or emacs or notepad, etc. This lowers the barrier to entry into the language because it broadens the available toolkit for editing and maintaining the language. Since a language lives or dies on user adoption, lowering the barrier to entry is important for a young language like Scala.

    The other benefits you list are of equal value, but being able to write less and do more is really important, especially if you are writing extremely large projects.

Add a comment

View 5 comments

  1. liciobruno – Posted July 15, 2010

    The Scala Version 2.8.0 RC6 gives as output "ArrayBuffer(A, FIRST, SCALA, PROGRAM)" instead of "Array(A, FIRST, SCALA, PROGRAM)"

  2. liciobruno – Posted July 15, 2010

    The Scala Version 2.8.0 RC6, gives as output the followinf result: "ArrayBuffer(A, FIRST, SCALA, PROGRAM)" instead of "Array(A, FIRST, SCALA, PROGRAM)"

  3. jjustice – Posted Nov. 8, 2010

    FYI, in 2.8.0 final, I actually get a trivially different result:

    ArrayBuffer(A, FIRST, SCALA, PROGRAM)

  4. lylejohnson – Posted Jan. 24, 2011

    For Scala 2.8.1, the result is an ArrayBuffer instead of an Array.

  5. Phaneesh Nagaraja – Posted Aug. 6, 2011

    Scala version 2.9.0.1 the result is a ArrayBuffer

Add a comment

View 2 comments

  1. joebowbeer – Posted May 20, 2009

    Typo in blue box above:

    "We discuss these subtleties in in ."

  2. deanwampler – Posted June 3, 2009

    I don't see it, but it might have been a production error where the "Command Line Tools" link disappeared in a prior build of the book. If you are STILL seeing this, could be a browser issue. Let us know with a new comment.

Add a comment

View 2 comments

  1. battisti – Posted May 23, 2009

    Is this paragraph really helpful? Of course you're going to explain the ideas contained in this first program more thoroughly later :-)

  2. deanwampler – Posted June 3, 2009

    Yea, I know... Always a struggle to decide how much really needs to be said...

Add a comment

View 2 comments

  1. brevius – Posted Oct. 4, 2009

    There are no "most curly brackets"; i.e. "outermost" should be one word.

  2. xsolomon – Posted Jan. 5, 2010

    "outermost" is one word.

Add a comment

View 2 comments

  1. piojosnos – Posted Aug. 27, 2009

    Isn't it missing in this paragraph the method name after the "def keyword". I mean: "...second line with the def keyword, followed by the method name, an argument list, ..."

  2. deanwampler – Posted Sept. 1, 2009

    Good point. ;) I'll add that.

Add a comment

View 2 comments

  1. brevius – Posted Oct. 4, 2009

    Unwanted apostrophe: it should be "Strings"

  2. carlolf – Posted Oct. 18, 2009

    if the argument is "actually an Array", so why can't I declare it like this: val sarray = Array("A Upper object", "First", "Scala", "Programmings") and give it as argument? The compiler complains: "required: String" which I do not understand.

Add a comment

View 1 comment

  1. robcd – Posted June 20, 2009
    • Note ... when you omit the colon
    • Note ... than when you omit the colon

Add a comment

View 6 comments

  1. battisti – Posted May 23, 2009

    If you're hinting at the similarity with lambdas/blocks in Ruby, adding "closures" at this point might be helpful for readers not familiar with Ruby.

  2. deanwampler – Posted June 3, 2009

    Will do. Thanks.

  3. maddalab – Posted July 26, 2009

    I understand function literals as syntactic sugar. Function literal syntax can be used to code either anonymous functions (do not capture variables in scope, as in the example here, lambdas) or closures.

    This is the first time I have read function literals being directly referenced as functions (albeit anonymous).

    Nitpicking may be, and I am not certain what is a better approach for someone reading on scala for the first time

  4. cody – Posted Aug. 13, 2009

    Use of the word "closure" here is a mistake, there are no free variables in the example.

    http://en.wikipedia.org/wiki/Closure_%28computer_science%29

  5. emptist – Posted May 10, 2010

    strings.map (s:String)=> s.toUppercase()) //this piece of code is similar to Smalltalk one as follows: // strings collect:[:s| s toUpperCase]

  6. emptist – Posted May 10, 2010

    in smalltalk: strings collect:[:s| s toUppercase]

Add a comment

View 5 comments

  1. battisti – Posted May 23, 2009

    Using the following "Note" to explaining why "return" is rarely used in scala (interfering with type inference, with an appropriate reference to the section explaining type inference) might be informative for readers only accustomed to Java

  2. deanwampler – Posted June 3, 2009

    We cover this topic in the next chapter. I'd rather not go into more details (even a link...) in this cursory introduction.

  3. nolan – Posted June 12, 2009

    I know that you don't want to add any further details into this introduction, so I'm writing this comment with that in mind. For some perspective, I'm fairly new to Scala, coming to this book after a plethora of assorted blog posts and tutorials.

    As someone who is familiar with Ruby, I'm a bit more interested in why => is used rather than =, and not so much in the fact that the last value of a function is the implicit return value. I think both should be mentioned, but even after reading lots of introductory information, the =/=> distinction still confuses me. Maybe a bit less real-estate for return and a bit more to explain => quickly?

  4. derekmahar – Posted July 8, 2009

    "=>" suggests a function mapping. In this case, the function maps from the set of all strings to the set of upper case strings. "=" implies that the set of all strings is equivalent to the set of upper case strings, which obviously is not true. So, I think the choice of "=>" over "=" is appropriate.

  5. carlolf – Posted Oct. 17, 2009

    You should leave a note that this code is not null-safe!

Add a comment

View 3 comments

  1. battisti – Posted May 23, 2009

    This is probably just some nitpicking, but is "declared as an object, which is a singleton class" correct? According to the Scala Reference it: "defines a single object of a new class", while a "singleton class" is a class used to implement the singleton pattern... these two concepts are of course related, but in Scala object definitions are also used as a mechanism for creating modules (which AFAIK is usually not the case when using a Singleton Pattern, which got a bad reputation in the last years).

  2. deanwampler – Posted June 3, 2009

    I'll drop the word "class" from "singleton class" and maybe add some more text.

  3. brevius – Posted Oct. 4, 2009

    The current paragraph still doesn't make the distinction that to create an instance of a class new must be used; the class declaration itself doesn't create an instance. Here, an Upper instance is already available after the declaration.

Add a comment

View 4 comments

  1. brl – Posted May 19, 2009

    It's not clear at all how the example code could possibly not be thread-safe in Scala or any other language since state has not even been introduced yet.

    I think the point you are trying to make is that it is a little bit tricky to implement the Singleton pattern in Java without introducing subtle concurrency problems, while in Scala you can just use an 'object' as a singleton without such concerns.

  2. deanwampler – Posted June 3, 2009

    That's all I'm really saying.

  3. maddalab – Posted July 26, 2009

    Just a comment on the comment. ;)

    I did not understand what was being said, until I read Bruce Leidl's comment about scala singletons not have concurrency considerations that you would have when implementing the same in Java.

  4. danielearwicker – Posted Sept. 25, 2009

    A question raised by this paragraph: when I want my code to be interoperable with Java, can Scala produce a .class file defining a class with static methods? Can Scala code import a class with static methods from a Java .class file and call those methods? Does the Scala compiler "behind the scenes" turn an object-singleton into a class with static members?

Add a comment

View 1 comment

  1. maddalab – Posted July 26, 2009

    The equals sign before the method body tells the compiler, as well as the human reader, where the method body begins.

    Is this redundant, and possibly misleading? You already have a must better reason for the equals sign previously when you say

    "Using an equals sign also reminds us that even functions are values in Scala, which is consistent with Scala’s support of functional programming"

Add a comment

View 2 comments

  1. Leonidas – Posted May 20, 2009

    The chapter reference is missing here (mentioning it in case you have missed it).

  2. abdelazer – Posted May 20, 2009

    @Marek: This was just a bug in the rendering system that was dropping the cross reference text. It's been fixed.

Add a comment

View 1 comment

  1. battisti – Posted May 23, 2009

    Adding a little note explaining that this is also the actual syntax when accessing static methods in Java libraries from Scala code would informative for Java converts or people interested in Scala because of the large number of available (Java) libraries.

Add a comment