diff --git a/_overviews/FAQ/breakout.md b/_overviews/FAQ/breakout.md deleted file mode 100644 index dfb41380ab..0000000000 --- a/_overviews/FAQ/breakout.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -layout: multipage-overview -title: What is breakOut, and how does it work? -overview-name: FAQ -partof: FAQ - -num: 5 -permalink: /tutorials/FAQ/:title.html ---- -You might have encountered some code like the one below, and wonder what is -`breakOut`, and why is it being passed as parameter? - - import scala.collection.breakOut - val map : Map[Int,String] = List("London", "France").map(x => (x.length, x))(breakOut) - - -The answer is found on the definition of `map`: - - def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That - -Note that it has two parameters. The first is your function and the second is -an implicit. If you do not provide that implicit, Scala will choose the most -_specific_ one available. - -### About breakOut - -So, what's the purpose of `breakOut`? Consider the example given at the -beginning , You take a list of strings, transform each string into a tuple -`(Int, String)`, and then produce a `Map` out of it. The most obvious way to do -that would produce an intermediary `List[(Int, String)]` collection, and then -convert it. - -Given that `map` uses a `Builder` to produce the resulting collection, wouldn't -it be possible to skip the intermediary `List` and collect the results directly -into a `Map`? Evidently, yes, it is. To do so, however, we need to pass a -proper `CanBuildFrom` to `map`, and that is exactly what `breakOut` does. - -Let's look, then, at the definition of `breakOut`: - - def breakOut[From, T, To](implicit b : CanBuildFrom[Nothing, T, To]) = - new CanBuildFrom[From, T, To] { - def apply(from: From) = b.apply() ; def apply() = b.apply() - } - -Note that `breakOut` is parameterized, and that it returns an instance of -`CanBuildFrom`. As it happens, the types `From`, `T` and `To` have already been -inferred, because we know that `map` is expecting `CanBuildFrom[List[String], -(Int, String), Map[Int, String]]`. Therefore: - - From = List[String] - T = (Int, String) - To = Map[Int, String] - -To conclude let's examine the implicit received by `breakOut` itself. It is of -type `CanBuildFrom[Nothing,T,To]`. We already know all these types, so we can -determine that we need an implicit of type -`CanBuildFrom[Nothing,(Int,String),Map[Int,String]]`. But is there such a -definition? - -Let's look at `CanBuildFrom`'s definition: - - trait CanBuildFrom[-From, -Elem, +To] - extends AnyRef - -So `CanBuildFrom` is contra-variant on its first type parameter. Because -`Nothing` is a bottom class (ie, it is a subclass of everything), that means -*any* class can be used in place of `Nothing`. - -Since such a builder exists, Scala can use it to produce the desired output. - -### About Builders - -A lot of methods from Scala's collections library consists of taking the -original collection, processing it somehow (in the case of `map`, transforming -each element), and storing the results in a new collection. - -To maximize code reuse, this storing of results is done through a _builder_ -(`scala.collection.mutable.Builder`), which basically supports two operations: -appending elements, and returning the resulting collection. The type of this -resulting collection will depend on the type of the builder. Thus, a `List` -builder will return a `List`, a `Map` builder will return a `Map`, and so on. -The implementation of the `map` method need not concern itself with the type of -the result: the builder takes care of it. - -On the other hand, that means that `map` needs to receive this builder somehow. -The problem faced when designing Scala 2.8 Collections was how to choose the -best builder possible. For example, if I were to write `Map('a' -> -1).map(_.swap)`, I'd like to get a `Map(1 -> 'a')` back. On the other hand, a -`Map('a' -> 1).map(_._1)` can't return a `Map` (it returns an `Iterable`). - -The magic of producing the best possible `Builder` from the known types of the -expression is performed through this `CanBuildFrom` implicit. - -### About CanBuildFrom - -To better explain what's going on, I'll give an example where the collection -being mapped is a `Map` instead of a `List`. I'll go back to `List` later. For -now, consider these two expressions: - - Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length) - Map(1 -> "one", 2 -> "two") map (_._2) - -The first returns a `Map` and the second returns an `Iterable`. The magic of -returning a fitting collection is the work of `CanBuildFrom`. Let's consider -the definition of `map` again to understand it. - -The method `map` is inherited from `TraversableLike`. It is parameterized on -`B` and `That`, and makes use of the type parameters `A` and `Repr`, which -parameterize the class. Let's see both definitions together: - -The class `TraversableLike` is defined as: - - trait TraversableLike[+A, +Repr] - extends HasNewBuilder[A, Repr] with AnyRef - - def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That - - -To understand where `A` and `Repr` come from, let's consider the definition of -`Map` itself: - - trait Map[A, +B] - extends Iterable[(A, B)] with Map[A, B] with MapLike[A, B, Map[A, B]] - -Because `TraversableLike` is inherited by all traits which extend `Map`, `A` -and `Repr` could be inherited from any of them. The last one gets the -preference, though. So, following the definition of the immutable `Map` and all -the traits that connect it to `TraversableLike`, we have: - - trait Map[A, +B] - extends Iterable[(A, B)] with Map[A, B] with MapLike[A, B, Map[A, B]] - - trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] - extends MapLike[A, B, This] - - trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] - extends PartialFunction[A, B] with IterableLike[(A, B), This] with Subtractable[A, This] - - trait IterableLike[+A, +Repr] - extends Equals with TraversableLike[A, Repr] - - trait TraversableLike[+A, +Repr] - extends HasNewBuilder[A, Repr] with AnyRef - -If you pass the type parameters of `Map[Int, String]` all the way down the -chain, we find that the types passed to `TraversableLike`, and, thus, used by -`map`, are: - - A = (Int,String) - Repr = Map[Int, String] - -Going back to the example, the first map is receiving a function of type -`((Int, String)) => (Int, Int)` and the second map is receiving a function of -type `((Int, String)) => String`. I use the double parenthesis to emphasize it is -a tuple being received, as that's the type of `A` as we saw. - -With that information, let's consider the other types. - - map Function.tupled(_ -> _.length): - B = (Int, Int) - - map (_._2): - B = String - -We can see that the type returned by the first `map` is `Map[Int,Int]`, and the -second is `Iterable[String]`. Looking at `map`'s definition, it is easy to see -that these are the values of `That`. But where do they come from? - -If we look inside the companion objects of the classes involved, we see some -implicit declarations providing them. On object `Map`: - - implicit def canBuildFrom [A, B] : CanBuildFrom[Map, (A, B), Map[A, B]] - -And on object `Iterable`, whose class is extended by `Map`: - - implicit def canBuildFrom [A] : CanBuildFrom[Iterable, A, Iterable[A]] - -These definitions provide factories for parameterized `CanBuildFrom`. - -Scala will choose the most specific implicit available. In the first case, it -was the first `CanBuildFrom`. In the second case, as the first did not match, -it chose the second `CanBuildFrom`. - -### Back to the first example - -Let's see the first example, `List`'s and `map`'s definition (again) to -see how the types are inferred: - - val map : Map[Int,String] = List("London", "France").map(x => (x.length, x))(breakOut) - - sealed abstract class List[+A] - extends LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqLike[A, List[A]] - - trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] - extends SeqLike[A, Repr] - - trait SeqLike[+A, +Repr] - extends IterableLike[A, Repr] - - trait IterableLike[+A, +Repr] - extends Equals with TraversableLike[A, Repr] - - trait TraversableLike[+A, +Repr] - extends HasNewBuilder[A, Repr] with AnyRef - - def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That - -The type of `List("London", "France")` is `List[String]`, so the types `A` and -`Repr` defined on `TraversableLike` are: - - A = String - Repr = List[String] - -The type for `(x => (x.length, x))` is `(String) => (Int, String)`, so the type -of `B` is: - - B = (Int, String) - -The last unknown type, `That` is the type of the result of `map`, and we -already have that as well: - - val map : Map[Int,String] = - -So, - - That = Map[Int, String] - -That means `breakOut` must, necessarily, return a type or subtype of -`CanBuildFrom[List[String], (Int, String), Map[Int, String]]`. - -This answer was originally submitted in response to [this question on Stack Overflow][1]. - - [1]: https://stackoverflow.com/q/1715681/53013 diff --git a/_overviews/FAQ/chaining-implicits.md b/_overviews/FAQ/chaining-implicits.md deleted file mode 100644 index cf8f513174..0000000000 --- a/_overviews/FAQ/chaining-implicits.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -layout: multipage-overview -title: How can I chain/nest implicit conversions? -overview-name: FAQ -partof: FAQ - -num: 6 -permalink: /tutorials/FAQ/:title.html ---- - -The enrich-my-library pattern allows one to seemingly add a method to a class by -making available an implicit conversion from that class to one that implements -the method. - -Scala does not allow two such implicit conversions taking place, however, so -one cannot got from `A` to `C` using an implicit `A` to `B` and another -implicit `B` to `C`. Is there a way around this restriction? - -Scala has a restriction on automatic conversions to add a method, which is that -it won't apply more than one conversion in trying to find methods. For example: - - class A(val n: Int) - class B(val m: Int, val n: Int) - class C(val m: Int, val n: Int, val o: Int) { - def total = m + n + o - } - - import scala.language.implicitConversions - - // This demonstrates implicit conversion chaining restrictions - object T1 { // to make it easy to test on REPL - implicit def toA(n: Int): A = new A(n) - implicit def aToB(a: A): B = new B(a.n, a.n) - implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n) - - // won't work - println(5.total) - println(new A(5).total) - - // works - println(new B(5, 5).total) - println(new C(5, 5, 10).total) - } - -However, if an implicit definition requires an implicit parameter itself, Scala -_will_ look for additional implicit values for as long as needed. Continuing from -the last example: - - object T2 { - implicit def toA(n: Int): A = new A(n) - implicit def aToB[A1](a: A1)(implicit f: A1 => A): B = - new B(a.n, a.n) - implicit def bToC[B1](b: B1)(implicit f: B1 => B): C = - new C(b.m, b.n, b.m + b.n) - - // works - println(5.total) - println(new A(5).total) - println(new B(5, 5).total) - println(new C(5, 5, 10).total) - } - -_"Magic!"_, you might say. Not so. Here is how the compiler would translate each -one: - - object T1Translated { - implicit def toA(n: Int): A = new A(n) - implicit def aToB(a: A): B = new B(a.n, a.n) - implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n) - - // Scala won't do this - println(bToC(aToB(toA(5))).total) - println(bToC(aToB(new A(5))).total) - - // Just this - println(bToC(new B(5, 5)).total) - - // No implicits required - println(new C(5, 5, 10).total) - } - - object T2Translated { - implicit def toA(n: Int): A = new A(n) - implicit def aToB[A1](a: A1)(implicit f: A1 => A): B = - new B(a.n, a.n) - implicit def bToC[B1](b: B1)(implicit f: B1 => B): C = - new C(b.m, b.n, b.m + b.n) - - // Scala does this - println(bToC(5)(x => aToB(x)(y => toA(y))).total) - println(bToC(new A(5))(x => aToB(x)(identity)).total) - println(bToC(new B(5, 5))(identity).total) - - // no implicits required - println(new C(5, 5, 10).total) - } - -So, while `bToC` is being used as an implicit conversion, `aToB` and `toA` are -being passed as _implicit parameters_, instead of being chained as implicit -conversions. - -See also: - -* [Context bounds](context-bounds.html) -* [A discussion on types, origin and precedence of implicits](finding-implicits.html) - -This question and answer were originally submitted on [Stack Overflow][1]. - - [1]: https://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala/5332804 diff --git a/_overviews/FAQ/collections.md b/_overviews/FAQ/collections.md deleted file mode 100644 index 6c0ad3355d..0000000000 --- a/_overviews/FAQ/collections.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -layout: multipage-overview -title: How are the collections structured? Which one should I choose? -overview-name: FAQ -partof: FAQ - -num: 8 -permalink: /tutorials/FAQ/:title.html ---- -## Foreword - -There's a [2.8 collection walk-through][1] by Martin Odersky which should -probably be your first reference. It has been supplemented as well with -[architectural notes][2], which will be of particular interest to those who -want to design their own collections. - -The rest of this answer was written way before any such thing existed (in fact, -before 2.8.0 itself was released). - -You can find a paper about it as [Scala SID #3][3]. Other papers in that area -should be interesting as well to people interested in the differences between -Scala 2.7 and 2.8. - -I'll quote from the paper, selectively, and complement with some thoughts of -mine. There are also some images, generated by Matthias at decodified.com, and -the original SVG files can be found [here][4]. - -## The collection classes/traits themselves - -There are actually three hierarchies of traits for the collections: one for -mutable collections, one for immutable collections, and one which doesn't make -any assumptions about the collections. - -There's also a distinction between parallel, serial and maybe-parallel -collections, which was introduced with Scala 2.9. I'll talk about them in the -next section. The hierarchy described in this section refers _exclusively to -non-parallel collections_. - -The following image shows the non-specific hierarchy as of Scala 2.10: - -[![General collection hierarchy][5]][5] - -All elements shown are traits. In the other two hierarchies there are also -classes directly inheriting the traits as well as classes which can be _viewed -as_ belonging in that hierarchy through implicit conversion to wrapper classes. -The legend for these graphs can be found after them. - -Graph for immutable hierarchy: - -[![Immutable collection hierarchy][10]][10] - -Graph for mutable hierarchy: - -[![Mutable collection hierarchy][11]][11] - -Legend: - -[![Graph legend][8]][8] - -Here's an abbreviated ASCII depiction of the collection hierarchy, for those who can't see the images. - - Traversable - | - | - Iterable - | - +------------------+--------------------+ - Map Set Seq - | | | - | | +------+-------+ - SortedMap SortedSet Buffer Vector LinearSeq - | - | - BitSet - -## Parallel Collections - -When Scala 2.9 introduced parallel collections, one of the design goals was to -make their use as seamless as possible. In the simplest terms, one can replace -a non-parallel (serial) collection with a parallel one, and instantly reap the -benefits. - -However, since all collections until then were serial, many algorithms using -them assumed and depended on the fact that they _were_ serial. Parallel -collections fed to the methods with such assumptions would fail. For this -reason, all the hierarchy described in the previous section _mandates serial -processing_. - -Two new hierarchies were created to support the parallel collections. - -The parallel collections hierarchy has the same names for traits, but preceded -with `Par`: `ParIterable`, `ParSeq`, `ParMap` and `ParSet`. Note that there is -no `ParTraversable`, since any collection supporting parallel access is capable -of supporting the stronger `ParIterable` trait. It doesn't have some of the -more specialized traits present in the serial hierarchy either. This whole -hierarchy is found under the directory `scala.collection.parallel`. - -The classes implementing parallel collections also differ, with `ParHashMap` -and `ParHashSet` for both mutable and immutable parallel collections, plus -`ParRange` and `ParVector` implementing `immutable.ParSeq` and `ParArray` -implementing `mutable.ParSeq`. - -Another hierarchy also exists that mirrors the traits of serial and parallel -collections, but with a prefix `Gen`: `GenTraversable`, `GenIterable`, -`GenSeq`, `GenMap` and `GenSet`. These traits are _parents_ to both parallel -and serial collections. This means that a method taking a `Seq` cannot receive -a parallel collection, but a method taking a `GenSeq` is expected to work with -both serial and parallel collections. - -Given the way these hierarchies were structured, code written for Scala 2.8 was -fully compatible with Scala 2.9, and demanded serial behavior. Without being -rewritten, it cannot take advantage of parallel collections, but the changes -required are very small. - -### Using Parallel Collections - -Any collection can be converted into a parallel one by calling the method `par` -on it. Likewise, any collection can be converted into a serial one by calling -the method `seq` on it. - -If the collection was already of the type requested (parallel or serial), no -conversion will take place. If one calls `seq` on a parallel collection or -`par` on a serial collection, however, a new collection with the requested -characteristic will be generated. - -Do not confuse `seq`, which turns a collection into a non-parallel collection, -with `toSeq`, which returns a `Seq` created from the elements of the -collection. Calling `toSeq` on a parallel collection will return a `ParSeq`, -not a serial collection. - -## The Main Traits - -While there are many implementing classes and subtraits, there are some basic -traits in the hierarchy, each of which providing more methods or more specific -guarantees, but reducing the number of classes that could implement them. - -In the following subsections, I'll give a brief description of the main traits -and the idea behind them. - -### Trait TraversableOnce - -This trait is pretty much like trait `Traversable` described below, but with -the limitation that you can only use it _once_. That is, any methods called on -a `TraversableOnce` _may_ render it unusable. - -This limitation makes it possible for the same methods to be shared between the -collections and `Iterator`. This makes it possible for a method that works with -an `Iterator` but not using `Iterator`-specific methods to actually be able to -work with any collection at all, plus iterators, if rewritten to accept -`TraversableOnce`. - -Because `TraversableOnce` unifies collections and iterators, and iterators are -not considered collections, it does not appear in the previous graphs, which -concern themselves only with collections. - -### Trait Traversable - -At the top of the _collection_ hierarchy is trait `Traversable`. Its only -abstract operation is - - def foreach[U](f: Elem => U) - -The operation is meant to traverse all elements of the collection, and apply -the given operation f to each element. The application is done for its side -effect only; in fact any function result of f is discarded by foreach. - -Traversable objects can be finite or infinite. An example of an infinite -traversable object is the stream of natural numbers `Stream.from(0)`. The -method `hasDefiniteSize` indicates whether a collection is possibly infinite. -If `hasDefiniteSize` returns true, the collection is certainly finite. If it -returns false, the collection has not been fully elaborated yet, so it might -be infinite or finite. - -This class defines methods which can be efficiently implemented in terms of -`foreach` (over 40 of them). - -### Trait Iterable - -This trait declares an abstract method `iterator` that returns an iterator that -yields all the collection’s elements one by one. The `foreach` method in -`Iterable` is implemented in terms of `iterator`. Subclasses of `Iterable` -often override foreach with a direct implementation for efficiency. - -Class `Iterable` also adds some less-often used methods to `Traversable`, which -can be implemented efficiently only if an `iterator` is available. They are -summarized below. - - xs.iterator An iterator that yields every element in xs, in the same order as foreach traverses elements. - xs takeRight n A collection consisting of the last n elements of xs (or, some arbitrary n elements, if no order is defined). - xs dropRight n The rest of the collection except xs takeRight n. - xs sameElements ys A test whether xs and ys contain the same elements in the same order - -### Seq, Set and Map - -After `Iterable` there come three base traits which inherit from it: `Seq`, -`Set`, and `Map`. All three have an `apply` method and all three implement the -`PartialFunction` trait, but the meaning of `apply` is different in each case. - -I trust the meaning of `Seq`, `Set` and `Map` is intuitive. After them, the -classes break up in specific implementations that offer particular guarantees -with regards to performance, and the methods it makes available as a result of -it. Also available are some traits with further refinements, such as -`LinearSeq`, `IndexedSeq` and `SortedSet`. - -## Complete Overview - -### Base Classes and Traits - -* `TraversableOnce` -- All methods and behavior common to collections and iterators. - - * `Traversable` -- Basic collection class. Can be implemented just with `foreach`. - - * `TraversableProxy` -- Proxy for a `Traversable`. Just point `self` to the real collection. - * `TraversableView` -- A Traversable with some non-strict methods. - * `TraversableForwarder` -- Forwards most methods to `underlying`, except `toString`, `hashCode`, `equals`, `stringPrefix`, `newBuilder`, `view` and all calls creating a new iterable object of the same kind. - * `mutable.Traversable` and `immutable.Traversable` -- same thing as `Traversable`, but restricting the collection type. - * Other special-cases `Iterable` classes, such as `MetaData`, exists. - * `Iterable` -- A collection for which an `Iterator` can be created (through `iterator`). - * `IterableProxy`, `IterableView`, `mutable` and `immutable.Iterable`. - - * `Iterator` -- A trait which is not descendant of `Traversable`. Define `next` and `hasNext`. - * `CountedIterator` -- An `Iterator` defining `count`, which returns the elements seen so far. - * `BufferedIterator` -- Defines `head`, which returns the next element without consuming it. - * Other special-cases `Iterator` classes, such as `Source`, exists. - -### The Sequences - -* `Seq` -- A sequence of elements. One assumes a well-defined size and element repetition. Extends `PartialFunction` as well. - - * `IndexedSeq` -- Sequences that support O(1) element access and O(1) length computation. - * `IndexedSeqView` - * `immutable.PagedSeq` -- An implementation of `IndexedSeq` where the elements are produced on-demand by a function passed through the constructor. - * `immutable.IndexedSeq` - - * `immutable.Range` -- A delimited sequence of integers, closed on the lower end, open on the high end, and with a step. - * `immutable.Range.Inclusive` -- A `Range` closed on the high end as well. - * `immutable.NumericRange` -- A more generic version of `Range` which works with any `Integral`. - * `immutable.NumericRange.Inclusive`, `immutable.NumericRange.Exclusive`. - * `immutable.WrappedString`, `immutable.RichString` -- Wrappers which enables seeing a `String` as a `Seq[Char]`, while still preserving the `String` methods. I'm not sure what the difference between them is. - - * `mutable.IndexedSeq` - * `mutable.GenericArray` -- An `Seq`-based array-like structure. Note that the "class" `Array` is Java's `Array`, which is more of a memory storage method than a class. - * `mutable.ResizableArray` -- Internal class used by classes based on resizable arrays. - * `mutable.PriorityQueue`, `mutable.SynchronizedPriorityQueue` -- Classes implementing prioritized queues -- queues where the elements are dequeued according to an `Ordering` first, and order of queueing last. - * `mutable.PriorityQueueProxy` -- an abstract `Proxy` for a `PriorityQueue`. - - * `LinearSeq` -- A trait for linear sequences, with efficient time for `isEmpty`, `head` and `tail`. - - * `immutable.LinearSeq` - * `immutable.List` -- An immutable, singly-linked, list implementation. - * `immutable.Stream` -- A lazy-list. Its elements are only computed on-demand, but memoized (kept in memory) afterwards. It can be theoretically infinite. - * `mutable.LinearSeq` - * `mutable.DoublyLinkedList` -- A list with mutable `prev`, `head` (`elem`) and `tail` (`next`). - * `mutable.LinkedList` -- A list with mutable `head` (`elem`) and `tail` (`next`). - * `mutable.MutableList` -- A class used internally to implement classes based on mutable lists. - * `mutable.Queue`, `mutable.QueueProxy` -- A data structure optimized for FIFO (First-In, First-Out) operations. - * `mutable.QueueProxy` -- A `Proxy` for a `mutable.Queue`. - - * `SeqProxy`, `SeqView`, `SeqForwarder` - - * `immutable.Seq` - - * `immutable.Queue` -- A class implementing a FIFO-optimized (First-In, First-Out) data structure. There is no common superclass of both `mutable` and `immutable` queues. - * `immutable.Stack` -- A class implementing a LIFO-optimized (Last-In, First-Out) data structure. There is no common superclass of both `mutable` `immutable` stacks. - * `immutable.Vector` -- ? - * `scala.xml.NodeSeq` -- A specialized XML class which extends `immutable.Seq`. - * `immutable.IndexedSeq` -- As seen above. - * `immutable.LinearSeq` -- As seen above. - - * `mutable.ArrayStack` -- A class implementing a LIFO-optimized data structure using arrays. Supposedly significantly faster than a normal stack. - * `mutable.Stack`, `mutable.SynchronizedStack` -- Classes implementing a LIFO-optimized data structure. - * `mutable.StackProxy` -- A `Proxy` for a `mutable.Stack`.. - * `mutable.Seq` - - * `mutable.Buffer` -- Sequence of elements which can be changed by appending, prepending or inserting new members. - * `mutable.ArrayBuffer` -- An implementation of the `mutable.Buffer` class, with constant amortized time for the append, update and random access operations. It has some specialized subclasses, such as `NodeBuffer`. - * `mutable.BufferProxy`, `mutable.SynchronizedBuffer`. - * `mutable.ListBuffer` -- A buffer backed by a list. It provides constant time append and prepend, with most other operations being linear. - * `mutable.ObservableBuffer` -- A *mixin* trait which, when mixed to a `Buffer`, provides notification events through a `Publisher` interfaces. - * `mutable.IndexedSeq` -- As seen above. - * `mutable.LinearSeq` -- As seen above. - -### The Sets - -* `Set` -- A set is a collection that includes at most one of any object. - - * `SortedSet` -- A set whose elements are ordered. - * `immutable.SortedSet` - * `immutable.BitSet` -- A set of integers stored as a bitset. - * `immutable.TreeSet` -- An implementation of a `SortedSet` based on a tree. - * `mutable.SortedSet` - * `mutable.BitSet` -- A set of integers stored as a bitset. - - * `SetProxy` -- A `Proxy` for a `Set`. - - * `immutable.Set` - * `immutable.HashSet` -- An implementation of `Set` based on element hashing. - * `immutable.ListSet` -- An implementation of `Set` based on lists. - * Additional set classes exists to provide optimized implementations for sets from 0 to 4 elements. - * `immutable.SetProxy` -- A `Proxy` for an immutable `Set`. - - * `mutable.Set` - * `mutable.HashSet` -- An implementation of `Set` based on element hashing. - * `mutable.ImmutableSetAdaptor` -- A class implementing a mutable `Set` from an immutable `Set`. - * `LinkedHashSet` -- An implementation of `Set` based on lists. - * `ObservableSet` -- A *mixin* trait which, when mixed with a `Set`, provides notification events through a `Publisher` interface. - * `SetProxy` -- A `Proxy` for a `Set`. - * `SynchronizedSet` -- A *mixin* trait which, when mixed with a `Set`, provides notification events through a `Publisher` interface. - -### The Maps - -* `Map` -- An `Iterable` of `Tuple2`, which also provides methods for retrieving a value (the second element of the tuple) given a key (the first element of the tuple). Extends `PartialFunction` as well. - * `MapProxy` -- A `Proxy` for a `Map`. - * `DefaultMap` -- A trait implementing some of `Map`'s abstract methods. - * `SortedMap` -- A `Map` whose keys are sorted. - * `immutable.SortMap` - * `immutable.TreeMap` -- A class implementing `immutable.SortedMap`. - * `immutable.Map` - * `immutable.MapProxy` - * `immutable.HashMap` -- A class implementing `immutable.Map` through key hashing. - * `immutable.IntMap` -- A class implementing `immutable.Map` specialized for `Int` keys. Uses a tree based on the binary digits of the keys. - * `immutable.ListMap` -- A class implementing `immutable.Map` through lists. - * `immutable.LongMap` -- A class implementing `immutable.Map` specialized for `Long` keys. See `IntMap`. - * There are additional classes optimized for an specific number of elements. - * `mutable.Map` - * `mutable.HashMap` -- A class implementing `mutable.Map` through key hashing. - * `mutable.ImmutableMapAdaptor` -- A class implementing a `mutable.Map` from an existing `immutable.Map`. - * `mutable.LinkedHashMap` -- ? - * `mutable.ListMap` -- A class implementing `mutable.Map` through lists. - * `mutable.MultiMap` -- A class accepting more than one distinct value for each key. - * `mutable.ObservableMap` -- A *mixin* which, when mixed with a `Map`, publishes events to observers through a `Publisher` interface. - * `mutable.OpenHashMap` -- A class based on an open hashing algorithm. - * `mutable.SynchronizedMap` -- A *mixin* which should be mixed with a `Map` to provide a version of it with synchronized methods. - * `mutable.MapProxy`. - -## Bonus Questions - -* Why the Like classes exist (e.g. TraversableLike)? - -This was done to achieve maximum code reuse. The concrete *generic* -implementation for classes with a certain structure (a traversable, a map, etc) -is done in the Like classes. The classes intended for general consumption, -then, override selected methods that can be optimized. - -* What the companion methods are for (e.g. List.companion)? - -The builder for the classes, ie, the object which knows how to create instances -of that class in a way that can be used by methods like `map`, is created by a -method in the companion object. So, in order to build an object of type X, I -need to get that builder from the companion object of X. Unfortunately, there -is no way, in Scala, to get from class X to object X. Because of that, there is -a method defined in each instance of X, `companion`, which returns the -companion object of class X. - -While there might be some use for such method in normal programs, its target is -enabling code reuse in the collection library. - -* How I know what implicit objects are in scope at a given point? - -You aren't supposed to care about that. They are implicit precisely so that you -don't need to figure out how to make it work. - -These implicits exists to enable the methods on the collections to be defined -on parent classes but still return a collection of the same type. For example, -the `map` method is defined on `TraversableLike`, but if you used on a `List` -you'll get a `List` back. - -This answer was originally submitted in response to [this question][9] on Stack -Overflow. - - - [1]: https://docs.scala-lang.org/overviews/collections/introduction.html - [2]: https://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html - [3]: https://www.scala-lang.org/sid/3 - [4]: https://github.com/sirthias/scala-collections-charts/downloads - [5]: /resources/images/tour/collections-diagram.svg - [6]: https://i.stack.imgur.com/2fjoA.png - [7]: https://i.stack.imgur.com/Dsptl.png - [8]: /resources/images/tour/collections-legend-diagram.svg - [9]: https://stackoverflow.com/q/1722137/53013 - [10]: /resources/images/tour/collections-immutable-diagram.svg - [11]: /resources/images/tour/collections-mutable-diagram.svg diff --git a/_overviews/FAQ/context-bounds.md b/_overviews/FAQ/context-bounds.md deleted file mode 100644 index 16c3732be4..0000000000 --- a/_overviews/FAQ/context-bounds.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -layout: multipage-overview -title: What are Scala context bounds? -overview-name: FAQ -partof: FAQ - -num: 3 -permalink: /tutorials/FAQ/:title.html ---- - -What is a Context Bound? ------------------------- - -Context bounds were introduced in Scala 2.8.0, and are typically used with the -so-called _type class pattern_, a pattern of code that emulates the -functionality provided by Haskell type classes, though in a more verbose -manner. - -A context bound requires a _parameterized type_, such as `Ordered[A]`. - -A context bound describes an implicit _value_. It is used to declare that for -some type `A`, there is an -implicit value of type `B[A]` available. The syntax goes like this: - - def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A] - -The common example of usage in Scala is this: - - def f[A : ClassTag](n: Int) = new Array[A](n) - -An `Array` initialization on a parameterized type requires a `ClassTag` to -be available, for arcane reasons related to type erasure and the non-erasure -nature of arrays. - -Another very common example in the library is a bit more complex: - - def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b) - -Here, `implicitly` is used to retrieve the implicit value we want, one of type -`Ordering[A]`, which class defines the method `compare(a: A, b: A): Int`. - -We'll see another way of doing this below. - -How are Context Bounds implemented? ---------------------------------------------------- - -It shouldn't be surprising that context bounds are -implemented with implicit parameters, given their definition. Actually, the -syntax I showed are syntactic sugars for what really happens. See below how -they de-sugar: - - def g[A : B](a: A) = h(a) - def g[A](a: A)(implicit ev: B[A]) = h(a) - -So, naturally, one can write them in their full syntax, which is specially -useful for context bounds: - - def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b) - -What are Context Bounds used for? ---------------------------------- - -Context bounds are mainly used in what has become known as _typeclass pattern_, -as a reference to Haskell's type classes. Basically, this pattern implements an -alternative to inheritance by making functionality available through a sort of -implicit adapter pattern. - -The classic example is Scala 2.8's `Ordering`. The usage is: - - def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b - -Though you'll usually see that written like this: - - def f[A](a: A, b: A)(implicit ord: Ordering[A]) = { - import ord._ - if (a < b) a else b - } - -Which take advantage of some implicit conversions inside `Ordering` that enable -the traditional operator style. Another example in Scala 2.8 is the `Numeric`: - - def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b) - -A more complex example is the new collection usage of `CanBuildFrom`, but -there's already a very long answer about that, so I'll avoid it here. And, as -mentioned before, there's the `ClassTag` usage, which is required to -initialize new arrays without concrete types. - -Though it has been possible for a long time, the use of context bounds has -really taken off in 2010, and is now found to some degree in most of Scala's -most important libraries and frameworks. The most extreme example of its usage, -though, is the Scalaz library, which brings a lot of the power of Haskell to -Scala. I recommend reading up on typeclass patterns to get more acquainted it -all the ways in which it can be used. - -Related questions of interest: - -* [A discussion on types, origin and precedence of implicits](finding-implicits.html) -* [Chaining implicits](chaining-implicits.html) - -This answer was originally submitted in response to [this question on Stack Overflow][1]. - - [1]: https://stackoverflow.com/q/4465948/53013 diff --git a/_overviews/FAQ/finding-implicits.md b/_overviews/FAQ/finding-implicits.md deleted file mode 100644 index 5be593d931..0000000000 --- a/_overviews/FAQ/finding-implicits.md +++ /dev/null @@ -1,415 +0,0 @@ ---- -layout: multipage-overview -title: Where does Scala look for implicits? -overview-name: FAQ -partof: FAQ - -num: 7 -permalink: /tutorials/FAQ/:title.html ---- - -Newcomers to Scala often ask: Where does the compiler look for implicits? - -For example, where do the values for `integral` below come from? - - scala> import scala.math._ - import scala.math._ - - scala> def foo[T](t: T)(implicit integral: Integral[T]): Unit = { - println(integral) - } - foo: [T](t: T)(implicit integral: scala.math.Integral[T])Unit - - scala> foo(0) - scala.math.Numeric$IntIsIntegral$@3dbea611 - - scala> foo(0L) - scala.math.Numeric$LongIsIntegral$@48c610af - -The natural continuation of this line of inquiry leads to a second question: How -does the compiler choose which implicit to use, in certain situations of apparent -ambiguity (but that compile anyway)? - -For instance, `scala.Predef` defines two conversions from `String`: one to -`WrappedString` and another to `StringOps`. Both classes, however, share a lot -of methods, so why doesn't Scala complain about ambiguity when, say, calling -`map`? - -**Note:** this question was inspired by [this other question on Stack -Overflow][4], but states the problem in more general terms. The example was -copied from there, because it is referred to in the answer. - -## Types of Implicits - -Implicits in Scala refers to either a value that can be passed "automatically", -so to speak, or a conversion from one type to another that is made -automatically. - -### Implicit Conversion - -Speaking very briefly about the latter type, if one calls a method `m` on an -object `o` of a class `C`, and that class does not support method `m`, then -Scala will look for an implicit conversion from `C` to something that _does_ -support `m`. A simple example would be the method `map` on `String`: - - "abc".map(_.toInt) - -`String` does not support the method `map`, but `StringOps` does, and there's -an implicit conversion from `String` to `StringOps` available (see `implicit -def augmentString` on `Predef`). - -### Implicit Parameters - -The other kind of implicit is the implicit _parameter_. These are passed to -method calls like any other parameter, but the compiler tries to fill them in -automatically. If it can't, it will complain. One _can_ pass these parameters -explicitly, which is how one uses `breakOut`, for example (see question about -`breakOut`, on a day you are feeling up for a challenge). - -In this case, one has to declare the need for an implicit, such as the `foo` -method declaration: - - def foo[T](t: T)(implicit integral: Integral[T]): Unit = { - println(integral) - } - -### Implicit conversions as implicit parameters - -There's one situation where an implicit is both an implicit conversion and an -implicit parameter. For example: - - def getIndex[T, CC](seq: CC, value: T)(implicit conv: CC => Seq[T]) = seq.indexOf(value) - - getIndex("abc", 'a') - -The method `getIndex` can receive any object, as long as there is an implicit -conversion available from its class to `Seq[T]`. Because of that, a `String` can be -passed to `getIndex`, and it will work. - -Behind the scenes, the compiler changes `seq.IndexOf(value)` to -`conv(seq).indexOf(value)`. - -### Context Bounds - -Another common pattern in implicit parameters is the _type class pattern_. This -pattern enables the provision of common interfaces to classes which did not -declare them. It can both serve as a bridge pattern -- gaining separation of -concerns -- and as an adapter pattern. - -The `Integral` class mentioned above is a classic example of type class pattern. -Another example on Scala's standard library is `Ordering`. Scalaz is a library -that makes heavy use of this pattern. - -This is an example of its use: - - def sum[T](list: List[T])(implicit integral: Integral[T]): T = { - import integral._ // get the implicits in question into scope - list.foldLeft(integral.zero)(_ + _) - } - -There is also a syntactic sugar for it, called a _context bound_, which is made -less useful by the need to refer to the implicit. A straight conversion of that -method looks like this: - - def sum[T : Integral](list: List[T]): T = { - val integral = implicitly[Integral[T]] - import integral._ // get the implicits in question into scope - list.foldLeft(integral.zero)(_ + _) - } - -Context bounds are more useful when you just need to _pass_ them to other -methods that use them. For example, the method `sorted` on `Seq` needs an -implicit `Ordering`. To create a method `reverseSort`, one could write: - - def reverseSort[T : Ordering](seq: Seq[T]) = seq.sorted.reverse - -Because `Ordering[T]` was implicitly passed to `reverseSort`, it can then pass -it implicitly to `sorted`. - -## Where do Implicits Come From? - -As described above, there are several contexts in which an implicit value may be required -for an expression to typecheck. The required implicit type is what determines -which value is selected. That value is found either in lexical scope or, -failing that, in what is called implicit scope. - -### Implicits Defined in Lexical Scope - -When a value of a certain name is required, lexical scope is searched for -a value with that name. Similarly, when an implicit value of a certain type is required, -lexical scope is searched for a value with that type. - -Any such value which can be referenced with its "simple" name, without -selecting from another value using dotted syntax, is an eligible implicit value. - -For example, here is a function that takes an implicit scaling factor. -The function requires a parameter of type `Int`, and there is a value -of that type in scope. The variable name `n` does not matter in this -case. - - implicit val n: Int = 5 - def scale(x: Int)(implicit y: Int) = x * y - scale(5) // takes n from the current scope, with the result 25 - -The invocation can be rewritten `scale(5)(n)`. If `n` can be referenced -using its simple name, as shown here, it is eligible as an implicit value. - -An implicit value can be introduced into scope by an import statement: - - import scala.collection.JavaConverters._ - def env = System.getenv().asScala // extension method enabled by imported implicit - val term = env("TERM") // it's a Scala Map - -There may be more than one such value because they have different names. - -In that case, overload resolution is used to pick one of them. The algorithm -for overload resolution is the same used to choose the reference for a -given name, when more than one term in scope has that name. For example, -`println` is overloaded, and each overload takes a different parameter type. -An invocation of `println` requires selecting the correct overloaded method. - -In implicit search, overload resolution chooses a value among more than one -that have the same required type. Usually this entails selecting a narrower -type or a value defined in a subclass relative to other eligible values. - -The rule that the value must be accessible using its simple name means -that the normal rules for name binding apply. - -In summary, a definition for `x` shadows a definition in -an enclosing scope. But a binding for `x` can also be introduced by -local imports. Imported symbols can't override definitions of the same -name in an enclosing scope. Similarly, wildcard imports can't override -an import of a specific name, and names in the current package that are -visible from other source files can't override imports or local definitions. - -These are the normal rules for deciding what `x` means in a given context, -and also determine which value `x` is accessible by its simple name and -is eligible as an implicit. - -This means that an implicit in scope can be disabled by shadowing it with -a term of the same name. - -For example, here, `X.f` is supplied the imported `X.s`: `X.f(s)`. -The body of `f` uses an implicit `Int`, from the immediate scope, -which shadows the `n` from `Y`, which is therefore not an eligible -implicit value. The parameter `s` shadows the member `s`. - -The method `g` does not compile because the implicit `t` is shadowed -by a `t` that is not implicit, so no implicit `T` is in scope. - - object Y { - implicit val n: Int = 17 - trait T { - implicit val i: Int = 17 - implicit def t: T = ??? - } - object X extends T { - implicit val n: Int = 42 - implicit val s: String = "hello, world\n" - def f(implicit s: String) = implicitly[String] * implicitly[Int] - override def t: T = ??? - def g = implicitly[T] - } - } - import Y.X._ - f - -The invocation of `f` was enabled by importing from `Y.X.`. But it is -not convenient to require an import to access implicit values -provided by a package. - -If an implicit value is not found in lexical scope, implicit search -continues in implicit scope. - -### Implicits Defined in Implicit Scope - -Implicit syntax can avoid the [import tax][1], which of course is a "sin tax," -by leveraging "implicit scope", which depends on the type of the implicit -instead of imports in lexical scope. - -When an implicit of type `T` is required, implicit scope includes -the companion object `T`: - - trait T - object T { implicit val t: T = new T { } } - -When an `F[T]` is required, implicit scope includes both the companion -of `F` and the companion of the type argument, e.g., `object C` for `F[C]`. - -In addition, implicit scope includes the companions of the base classes -of `F` and `C`, including package objects, such as `p` for `p.F`. - -### Companion Objects of a Type - -There are two object companions of note here. First, the object companion of -the "source" type is looked into. For instance, inside the object `Option` -there is an implicit conversion to `Iterable`, so one can call `Iterable` -methods on `Option`, or pass `Option` to something expecting an `Iterable`. For -example: - - for { - x <- List(1, 2, 3) - y <- Some('x') - } yield (x, y) - -That expression is translated by the compiler into - - List(1, 2, 3).flatMap(x => Some('x').map(y => (x, y))) - -However, `List.flatMap` expects a `TraversableOnce`, which `Option` is not. The -compiler then looks inside `Option`'s object companion and finds the conversion -to `Iterable`, which is a `TraversableOnce`, making this expression correct. - -Second, the companion object of the expected type: - - List(1, 2, 3).sorted - -The method `sorted` takes an implicit `Ordering`. In this case, it looks inside -the object `Ordering`, companion to the class `Ordering`, and finds an implicit -`Ordering[Int]` there. - -Note that companion objects of super classes are also looked into. For example: - - class A(val n: Int) - object A { - implicit def str(a: A) = "A: %d" format a.n - } - class B(val x: Int, y: Int) extends A(y) - val b = new B(5, 2) - val s: String = b // s == "A: 2" - -This is how Scala found the implicit `Numeric[Int]` and `Numeric[Long]` in the -opening example, by the way, as they are found inside `Numeric`, not `Integral`. - -### Implicit scope of an argument's type - -If you have a method with an argument type `A`, then the implicit scope of type -`A` will also be considered. Here "implicit scope" means all these rules -will be applied recursively -- for example, the companion object of `A` will be -searched for implicits, as per the rule above. - -Note that this does not mean the implicit scope of `A` will be searched for -conversions of that parameter alone, but of the whole expression. For example: - - class A(val n: Int) { - def +(other: A) = new A(n + other.n) - } - object A { - implicit def fromInt(n: Int) = new A(n) - } - - // This becomes possible: - 1 + new A(1) - // because it is converted into this: - A.fromInt(1) + new A(1) - -### Implicit scope of type arguments - -This is required to make the type class pattern really work. Consider -`Ordering`, for instance... it comes with some implicits in its companion -object, but you can't add stuff to it. So how can you make an `Ordering` for -your own class that is automatically found? - -Let's start with the implementation: - - class A(val n: Int) - object A { - implicit val ord = new Ordering[A] { - def compare(x: A, y: A) = implicitly[Ordering[Int]].compare(x.n, y.n) - } - } - -So, consider what happens when you call - - List(new A(5), new A(2)).sorted - -As we saw, the method `sorted` expects an `Ordering[A]` (actually, it expects -an `Ordering[B]`, where `B >: A`). There isn't any such thing inside -`Ordering`, and there is no "source" type on which to look. Obviously, it is -finding it inside `A`, which is a _type argument_ of `Ordering`. - -This is also how various collection methods expecting `CanBuildFrom` work: the -implicits are found inside companion objects to the type parameters of -`CanBuildFrom`. - -**Note**: `Ordering` is defined as `trait Ordering[T]`, where `T` is a type -parameter. The implicit looked for above is `Ordering[A]`, where -`A` is an actual type, not type parameter: it is a _type argument_ to -`Ordering`. See section 7.2 of the [Scala Specification][6]. - -### Outer Objects for Nested Types - -The principle is simple: - - class A(val n: Int) { - class B(val m: Int) { require(m < n) } - } - object A { - implicit def bToString(b: A#B) = "B: %d" format b.m - } - val a = new A(5) - val b = new a.B(3) - val s: String = b // s == "B: 3" - -A real world example of this would be welcome. Please share your example! - -### Package Objects Can Contribute Implicit Values - -An implicit value in a package object can be made available either -in lexical scope or in implicit scope. - -To be available in lexical scope, the packages must be declared as nested packages: - - package object p { implicit val s: String = "hello, world" } - package p { - package q { - object X { def f = implicitly[String] } - } - } - -This is sensitive to name binding rules. The following example compiles -only if the package object is in a separate file, in which case the import is used: - - package object p { implicit val s: String = "hello, world" } - package p { - package q { - object Y { - implicit val s: String = "bye" - } - object X { - import Y._ - def f = implicitly[String] - } - } - } - -A package object can also offer implicit values of types in subpackages: - - package object p { implicit val c: q.C = new q.C } - package p.q { - class C - object X { def f = implicitly[C] } - } - -Here, the implicit is supplied in implicit scope of `C`. - -### Call To Action - -Avoid taking this question as being the final arbiter of what is happening. -If you do notice it has become out-of-date, do [open a ticket about it][7], or, if -you know how to correct it, please fix it. - -Related questions of interest: - -* [Context bounds](context-bounds.html) -* [Chaining implicits](chaining-implicits.html) - -This question and answer were originally submitted on [Stack Overflow][3]. - - [1]: https://jsuereth.com/scala/2011/02/18/2011-implicits-without-tax.html - [2]: https://issues.scala-lang.org/browse/SI-4427 - [3]: https://stackoverflow.com/q/5598085/53013 - [4]: https://stackoverflow.com/questions/5512397/passing-scala-math-integral-as-implicit-parameter - [5]: https://scala-lang.org/files/archive/spec/2.11/06-expressions.html - [6]: https://scala-lang.org/files/archive/spec/2.11/07-implicits.html - [7]: https://github.com/scala/docs.scala-lang/issues diff --git a/_overviews/FAQ/finding-symbols.md b/_overviews/FAQ/finding-symbols.md deleted file mode 100644 index c9737400c0..0000000000 --- a/_overviews/FAQ/finding-symbols.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -layout: multipage-overview -title: How do I find what some symbol means or does? -overview-name: FAQ -partof: FAQ - -num: 1 - -permalink: /tutorials/FAQ/:title.html ---- -We can divide the operators in Scala, for the purpose of teaching, into four categories: - -* Keywords/reserved symbols -* Normal methods or values -* Methods provided by implicit conversion -* Syntactic sugars/composition - -And let's see some arbitrary examples: - - <- // Keyword - -> // Method provided by implicit conversion - <= // Common method - ++= // Can be a common method or syntactic sugar involving ++ method - :: // Common method or object - _+_ // Not really a single operator; it's parsed as _ + _ - -The exact meaning of most of these methods depends on the class they are defined -on. For example, `<=` on `Int` means _"less than or equal to"_, but it might -mean something else in another class. `::` in an expression is probably the method of the class -`List` but it can also refer to the object of the same name (and in a pattern it -definitely does). - -So, let's discuss these categories. - -Keywords/reserved symbols -------------------------- - -There are a few symbols in Scala that are special and cannot be defined or used as method names. -Two of them are considered proper keywords, while others are just "reserved". They are: - - // Keywords - <- // Used on for-comprehensions, to separate pattern from generator - => // Used for function types, function literals and import renaming - - // Reserved - ( ) // Delimit expressions and parameters - [ ] // Delimit type parameters - { } // Delimit blocks - . // Method call and path separator - // /* */ // Comments - # // Used in type notations - : // Type ascription or context bounds - <: >: // Upper and lower bounds - <% // View bounds (deprecated) - " """ // Strings - ' // Indicate symbols and characters - @ // Annotations and variable binding on pattern matching - ` // Denote constant or enable arbitrary identifiers - , // Parameter separator - ; // Statement separator - _* // vararg expansion - _ // Many different meanings - -These are all _part of the language_, and, as such, can be found in any text -that properly describe the language, such as [Scala Specification][1](PDF) -itself. - -The last one, the underscore, deserve a special description, because it is -widely used, and has different meanings depending on the context. Here's a sample: - - import scala._ // Wild card -- all of Scala is imported - import scala.{ Predef => _, _ } // Exclusion, everything except Predef - def f[M[_]] // Higher kinded type parameter - def f(m: M[_]) // Existential type - _ + _ // Anonymous function placeholder parameter - m _ // Eta expansion of method into method value - m(_) // Partial function application - _ => 5 // Discarded parameter - case _ => // Wild card pattern -- matches anything - f(xs: _*) // Sequence xs is passed as multiple parameters to f(ys: T*) - case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence - -Common methods --------------- - -Many symbols are simply methods of a class, a trait, or an object. For instance, if you do - - List(1, 2) ++ List(3, 4) - -You'll find the method `++` right on the Scaladoc for [List][5]. However, -there's one convention that you must be aware when searching for methods. -Methods ending in colon (`:`) bind _to the right_ instead of the left. In other -words, while the above method call is equivalent to: - - List(1, 2).++(List(3, 4)) - -If I had, instead `1 :: List(2, 3)`, that would be equivalent to: - - List(2, 3).::(1) - -So you need to look at the type found _on the right_ when looking for methods -ending in colon. Consider, for instance: - - 1 +: List(2, 3) :+ 4 - -The first method (`+:`) binds to the right, and is found on `List`. The second -method (`:+`) is just a normal method, and binds to the left -- again, on -`List`. - -If the name ends in `=`, look for the method called the same without `=` and -read the last section. - -If you aren't sure what the type of the receiver is, you can look up the symbol -on the Scaladoc [index page for identifiers not starting with letters][2] (for -standard Scala library; of course, third-party libraries can add their own -symbolic methods, for which you should look at the corresponding page of _their_ -Scaladoc). - -Types and objects can also have symbolic names; in particular, it should be mentioned -that for types with two type parameters the name can be written _between_ parameters, -so that e.g. `Int <:< Any` is the same as `<:<[Int, Any]`. - -Methods provided by implicit conversion ---------------------------------------- - -If you did not find the symbol you are looking for in the list of reserved symbols, then -it must be a method, or part of one. But, often, you'll see some symbol and the -documentation for the class will not have that method. When this happens, -either you are looking at a composition of one or more methods with something -else, or the method has been imported into scope, or is available through an -imported implicit conversion. - -These can also be found in Scaladoc's [index][2], as mentioned above. - -All Scala code has three automatic imports: - - // Not necessarily in this order - import java.lang._ - import scala._ - import scala.Predef._ - -The first two only make classes and singleton objects available, none of which -look like operators. [`Predef`][3] is the only interesting one for this post. - -Looking inside `Predef` shows some symbolic names: - - class <:< - class =:= - object =:= - object <%< // removed in Scala 2.10 - def ??? - -There is also `::`, which doesn't appear in the Scaladoc, but is mentioned in the comments. -In addition, `Predef` makes some methods available through _implicit conversions_. Just -look at the methods and classes with `implicit` modifier that receive, as parameter, an -object of type that is receiving the method. For example, consider `"a" -> 1`. We need -to look for an implicit which works on `"a"`, and so it can take `String`, one of its -supertypes (`AnyRef` or `Any`) or a type parameter. In this case, we find -`implicit final class ArrowAssoc[A](private val self: A)` which makes this implicit -available on all types. - -Other implicit conversions may be visible in your scope depending on imports, extended types or -self-type annotations. See [Finding implicits](finding-implicits.html) for details. - -Syntactic sugars/composition ------------------------------ - -So, here's a few syntactic sugars that may hide a method: - - class Example(arr: Array[Int] = Array.fill(5)(0)) { - def apply(n: Int) = arr(n) - def update(n: Int, v: Int) = arr(n) = v - def a = arr(0); def a_=(v: Int) = arr(0) = v - def b = arr(1); def b_=(v: Int) = arr(1) = v - def c = arr(2); def c_=(v: Int) = arr(2) = v - def d = arr(3); def d_=(v: Int) = arr(3) = v - def e = arr(4); def e_=(v: Int) = arr(4) = v - def +(v: Int) = new Example(arr map (_ + v)) - def unapply(n: Int) = if (arr.indices contains n) Some(arr(n)) else None - } - - val ex = new Example - println(ex(0)) // means ex.apply(0) - ex(0) = 2 // means ex.update(0, 2) - ex.b = 3 // means ex.b_=(3) - val ex(c) = 2 // calls ex.unapply(2) and assigns result to c, if it's Some; throws MatchError if it's None - ex += 1 // means ex = ex + 1; if Example had a += method, it would be used instead - -The last one is interesting, because *any* symbolic method can be combined with `=` in that way. - -And, of course, all of the above can be combined in various combinations, e.g. - - (_+_) // An expression, or parameter, that is an anonymous function with - // two parameters, used exactly where the underscores appear, and - // which calls the "+" method on the first parameter passing the - // second parameter as argument. - -This answer was originally submitted in response to [this question on Stack Overflow][6]. - - [1]: https://scala-lang.org/files/archive/spec/2.11/ - [2]: https://www.scala-lang.org/api/current/index.html#index.index-_ - [3]: https://www.scala-lang.org/api/current/scala/Predef$.html - [4]: https://www.scala-lang.org/api/current/scala/Predef$$ArrowAssoc.html - [5]: https://www.scala-lang.org/api/current/scala/collection/immutable/List.html - [6]: https://stackoverflow.com/q/7888944/53013 diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index 91ab76367b..450a1f3ebb 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -4,10 +4,95 @@ title: Scala FAQs permalink: /tutorials/FAQ/index.html --- -A collection of frequently asked questions and their answers! Graciously -provided by Daniel Sobral, adapted from his StackOverflow posts. +Frequently asked questions, with _brief_ answers and/or links to +longer answers. -## FAQs +This list only includes questions that _actually_ come up over and +over again in Scala chat rooms and forums. + +## General questions + +### Where can I ask Scala questions? + +see our [Community page](https://scala-lang.org/community/) + +### Should I learn Scala 2, or Scala 3? + +The default choice remains Scala 2 for now. Most Scala jobs are Scala +2 jobs; most Scala books and online learning materials cover Scala 2; +tooling and library support is strongest in Scala 2; and so on. + +Scala 3.0 is planned for release in early 2021, and a number of +Scala 3 books will come out in 2021 as well. In time, there will +be more and more Scala 3 jobs as well. + +### What's a good book about Scala? + +Our [Books page](https://docs.scala-lang.org/books.html) lists a few +especially popular, well-known books. + +We don't have a list of all the Scala books that +are out there; there are many. + +You can go on the [Scala room on +Gitter](https://gitter.im/scala/scala) or another community forum and +ask for book recommendations, but note that you'll get more helpful +answers if you provide some information about your background and your +reasons for wanting to learn Scala. + +### How do I find what some symbol means or does? + +A [Stack Overflow answer](https://stackoverflow.com/a/7890032) lays +out what the different kinds of symbol in Scala are and explains the +most commonly used symbols. + +Scala allows symbolic method names. So if you see a random-looking +operator like `>=@=>` in Scala code, it might simply be a method in +some library, rather than having any special meaning in the language +itself. + +You can search for symbols on Google. For example, if you want to +know what `<:<` means, searching for `scala <:<` works fine. If you +get poor results, try surrounding the symbol with double quotes. + +## Specific technical questions + +### Which type of collection should I choose? + +see the [Scala 2.13 Collections Guide](https://docs.scala-lang.org/overviews/collections-2.13/introduction.html) + +### What are Scala context bounds (`[T : Foo]`)? + +[answer on Stack Overflow](https://stackoverflow.com/a/4467012) + +### How does `yield` work? + +[answer on Stack Overflow](https://stackoverflow.com/a/1059501) + +### What is the difference between view, stream and iterator? + +[answer on Stack Overflow](https://stackoverflow.com/a/5159356) + +### How can I chain/nest implicit conversions? + +[answer on Stack Overflow](https://stackoverflow.com/a/5332804) + +### Where does Scala look for implicits? + +[answer on Stack Overflow](https://stackoverflow.com/a/5598107) + +### Why do primitive type parameters erase to `Object`? + +So for example, a `List[Int]` in Scala code will appear to Java as a +`List[Object]`. The Java type system doesn't allow primitive types to +appear as type parameters, but couldn't they appear as their boxed +equivalents, such as `List[java.lang.Integer]`? + +One would hope so, but doing it that way was tried and it proved +impossible. [This SO question](https://stackoverflow.com/questions/11167430/why-are-primitive-types-such-as-int-erased-to-object-in-scala) +sadly lacks a concise explanation, but it does link to past discussions. + +## More questions {% assign overviews = site.overviews | sort: 'num' %}