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.

3 comments

  1. Jungho Kim Posted 2 months, 18 days and 22 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 13 hours ago

    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. Arbi Sookazian Posted 1 month, 3 days and 6 hours ago

    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

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.

4 comments

  1. Bruce Leidl Posted 2 months, 23 days and 2 hours ago

    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. Eder Andres Avila Posted 2 months, 13 days and 13 hours ago

    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. Eder Andres Avila Posted 2 months, 13 days and 13 hours ago

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

  4. Dean Wampler Posted 2 months, 8 days and 13 hours ago

    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

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.

3 comments

  1. Marek Kubica Posted 2 months, 22 days and 19 hours ago

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

  2. Dean Wampler Posted 2 months, 8 days and 13 hours ago

    Will make this statement more 'inclusive".

  3. Arbi Sookazian Posted 1 month, 3 days and 6 hours ago

    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

Add a comment

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.

3 comments

  1. Henrik Huttunen Posted 2 months, 22 days and 8 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 13 hours ago

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

  3. Bhaskar Maddala Posted 16 days and 16 hours ago

    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

Add a comment

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.

2 comments

  1. Ricky Clarkson Posted 2 months, 22 days and 8 hours ago

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

  2. Ged Byrne Posted 1 month, 3 days and 14 hours ago

    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.

Add a comment

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.

1 comment

  1. Bhaskar Maddala Posted 16 days and 16 hours ago

    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.

Add a comment

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.

1 comment

  1. Henrik Huttunen Posted 2 months, 22 days and 8 hours ago

    This paragraph could be made much concise without losing meaning.

Add a comment

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.

2 comments

  1. Derek Mahar Posted 1 month, 5 days and 5 hours ago

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

  2. Bhaskar Maddala Posted 16 days and 15 hours ago

    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

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.

1 comment

  1. Geoffrey Wiseman Posted 1 month, 22 days and 1 hour ago

    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.

Add a comment

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.

4 comments

  1. Marek Kubica Posted 2 months, 22 days and 19 hours ago

    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 2 months, 22 days and 8 hours ago

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

    With the exceptions of CAL and JavaFX.

  3. Henrik Huttunen Posted 2 months, 22 days and 8 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 13 hours ago

    @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

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.

2 comments

  1. Peter Rawsthorne Posted 2 months, 16 days and 11 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 13 hours ago

    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.

Add a comment

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.

1 comment

  1. Derek Mahar Posted 1 month, 4 days and 10 hours ago

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

Add a comment

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.

2 comments

  1. Henrik Huttunen Posted 2 months, 22 days and 8 hours ago

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

  2. Derek Mahar Posted 1 month, 4 days and 10 hours ago

    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?

Add a comment

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.

4 comments

  1. Henrik Huttunen Posted 2 months, 22 days and 8 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    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. Posted 2 months, 4 days and 23 hours ago

    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. Derek Mahar Posted 1 month, 4 days and 9 hours ago

    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.

Add a comment

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.

1 comment

  1. Posted 2 months, 4 days and 23 hours ago

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

Add a comment

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.

1 comment

  1. Arbi Sookazian Posted 1 month, 3 days and 6 hours ago

    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

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.

1 comment

  1. Ze'ev Posted 2 months, 21 days and 12 hours ago

    Test

Add a comment

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.

4 comments

  1. JoshG Posted 2 months, 19 days and 12 hours ago

    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. JoshG Posted 2 months, 19 days and 12 hours ago

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

  3. Geoffrey Wiseman Posted 1 month, 20 days and 23 hours ago

    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. Dean Wampler Posted 1 month, 2 days and 5 hours ago

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

Add a comment

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.

2 comments

  1. Joe Bowbeer Posted 2 months, 22 days and 6 hours ago

    Typo in blue box above:

    "We discuss these subtleties in in ."

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    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

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.

2 comments

  1. Alexander Battisti Posted 2 months, 19 days and 5 hours ago

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

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

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

Add a comment

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 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 <…>.

1 comment

  1. Rob Dickens Posted 1 month, 21 days and 17 hours ago
    • Note ... when you omit the colon
    • Note ... than when you omit the colon

Add a comment

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.

3 comments

  1. Alexander Battisti Posted 2 months, 19 days and 4 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Will do. Thanks.

  3. Bhaskar Maddala Posted 16 days and 15 hours ago

    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

Add a comment

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).

4 comments

  1. Alexander Battisti Posted 2 months, 19 days and 4 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    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 1 month, 29 days and 1 hour ago

    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. Derek Mahar Posted 1 month, 3 days and 6 hours ago

    "=>" 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.

Add a comment

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.

2 comments

  1. Alexander Battisti Posted 2 months, 19 days and 4 hours ago

    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. Dean Wampler Posted 2 months, 8 days and 12 hours ago

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

Add a comment

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.

3 comments

  1. Bruce Leidl Posted 2 months, 23 days and 1 hour ago

    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. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    That's all I'm really saying.

  3. Bhaskar Maddala Posted 16 days and 15 hours ago

    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.

Add a comment

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.

1 comment

  1. Bhaskar Maddala Posted 16 days and 15 hours ago

    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

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.

2 comments

  1. Marek Kubica Posted 2 months, 22 days and 19 hours ago

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

  2. Keith Fahlgren Posted 2 months, 22 days and 1 hour ago

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

Add a comment

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).

1 comment

  1. Alexander Battisti Posted 2 months, 19 days and 4 hours ago

    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

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.

1 comment

  1. Bhaskar Maddala Posted 16 days and 14 hours ago

    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

Add a comment

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.

1 comment

  1. Rob Dickens Posted 1 month, 21 days and 16 hours ago

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

Add a comment

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.

1 comment

  1. Tim MacEachern Posted 1 month, 18 days and 12 hours ago

    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

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.

2 comments

  1. Jason Harris Posted 2 months, 22 days and 14 hours ago

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

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Thanks! Will fix

Add a comment

 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.

3 comments

  1. Steven Grady Posted 2 months, 22 days and 3 hours ago

    In Erlang, there is no "Actors" library -- the concurrency in Erlang is part of the language.

  2. Alexander Battisti Posted 2 months, 19 days and 4 hours ago

    "built-in Actors library" reads a bit like as if Actors were part of the Scala Language definition; a stronger hint, that Actors in Scala are "just" a library would IMHO be good. Together with Steven's comment above, maybe: "One reason is Scala's Actors library, a concurrency API based on the Erlang's Actors concurrency model." ... removed "robust" due to the "New Lift Actor code" Mail by David Pollak in the Lift Google Group ... which might make a nice side note showing off Scala's flexibility :-)

  3. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Good points. Will fix.

Add a comment

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.

3 comments

  1. Jeff Posted 1 month and 13 hours ago

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

  2. Dean Wampler Posted 30 days and 2 hours ago

    Good catch. Thanks. Will fix.

  3. Bhaskar Maddala Posted 16 days and 13 hours ago

    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.

Add a comment

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.

2 comments

  1. Steven Grady Posted 2 months, 22 days and 3 hours ago

    Typo: "auxiliary constructors in in "

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Another production problem that has since been fixed. Sorry.

Add a comment

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.

1 comment

  1. Bhaskar Maddala Posted 16 days and 13 hours ago

    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.

Add a comment

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.)

2 comments

  1. Bob Follek Posted 1 month, 22 days and 14 hours ago

    Maybe a quick explanation of "Unit" here?

  2. Dean Wampler Posted 30 days and 2 hours ago

    Thanks. Oversight. Will fix.

Add a comment

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.

1 comment

  1. Bhaskar Maddala Posted 16 days and 13 hours ago

    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

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.

3 comments

  1. Tim MacEachern Posted 1 month, 18 days and 13 hours ago

    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. Dean Wampler Posted 30 days and 2 hours ago

    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. Bhaskar Maddala Posted 16 days and 13 hours ago

    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

// 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.

2 comments

  1. Bhaskar Maddala Posted 16 days and 12 hours ago

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

  2. Bhaskar Maddala Posted 16 days and 12 hours ago

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

Add a comment

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.

2 comments

  1. Jason Harris Posted 2 months, 22 days and 13 hours ago

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

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Missing links now fixed.

Add a comment

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.

1 comment

  1. Geoffrey Wiseman Posted 1 month, 19 days and 6 hours ago

    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

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!

2 comments

  1. Rob Dickens Posted 1 month, 21 days and 15 hours ago

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

  2. Rob Dickens Posted 1 month, 21 days and 10 hours ago

    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.

Add a comment

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.

2 comments

  1. Joshua Posted 2 months, 21 days and 11 hours ago

    Hopefully we also implemented draw in Triangle!

  2. Dean Wampler Posted 1 month, 2 days and 5 hours ago

    Thanks. We fixed that one ;)

Add a comment

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.

2 comments

  1. Ariel Ortiz Posted 2 months, 12 days and 8 hours ago

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

  2. Dean Wampler Posted 2 months, 8 days and 12 hours ago

    Thanks!

Add a comment

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.

You must sign in or register before commenting