Saturday, December 26, 2009
Product
As a response to a comment on a previous post about about Tuples this topic is about Products and the most common subclasses of Tuples.
I should preface this post by saying that I am not going to attempt any scholastic style discussions, instead I am going to try to explain Product in practical terms and stay away from theory. That said on can think of Products as (potentially) heterogenous collections (non-resizable collections). There are several Product classes (Product, Product1, Product2...). All Product classes extend Product, which contains the common methods. Product has the methods for accessing the Product members and the subclass adds type information about the Members.
A good way to think about Product is to look at Tuple which is a Product. There is a good stack overflow question that is worth looking at.
To give more context consider other well known subclasses of Product:
I should preface this post by saying that I am not going to attempt any scholastic style discussions, instead I am going to try to explain Product in practical terms and stay away from theory. That said on can think of Products as (potentially) heterogenous collections (non-resizable collections). There are several Product classes (Product, Product1, Product2...). All Product classes extend Product, which contains the common methods. Product has the methods for accessing the Product members and the subclass adds type information about the Members.
A good way to think about Product is to look at Tuple which is a Product. There is a good stack overflow question that is worth looking at.
To give more context consider other well known subclasses of Product:
- All case classes
- List
- Option
- scala> val product : Product = (1,'2',3)
- product: Product = (1,2,3)
- scala> product.productIterator.foreach {println _}
- 1
- 2
- 3
- scala> product.productArity
- res1: Int = 3
- scala> product.productElement(2)
- res2: Any = 3
- scala> product.productPrefix
- res3: java.lang.String = Tuple3
- scala> product.toString
- res4: java.lang.String = (1,2,3)
- scala> val product3 = product.asInstanceOf[Product3[Int,Char,Int]]
- product3: Product3[Int,Char,Int] = (1,2,3)
- scala> product3._2
- res5: Char = 2
- scala> product3._3
- res6: Int = 3
- scala> case class Test(name:String, passed:Boolean, error:String)
- defined class Test
- scala> Test("Chicken Little", false, "the sky is falling")
- res7: Test = Test(Chicken Little,false,the sky is falling)
- scala> res7.productArity
- res8: Int = 3
- scala> res7.productIterator mkString ", "
- res9: String = Chicken Little, false, the sky is falling
Friday, December 18, 2009
Tuples are (not?) Collections
Tuples are quite handy but a potential annoyance is that at a glance they seem list-like but appearances can be deceiving. The normal collection methods are not supported by Tuples. For example suppose you like the simple syntax:
Word of warning. Unlike collections Tuples are very often not homogeneous. IE you do not have
Note: this was done with Scala 2.8 so results may be slightly different with 2.7. But I believe the syntax is valid.
(1,2,3)
better than List(1,2,3)
. With the Tuple you cannot do the maps, filters, etc... (with good reason) but there is a use-case for being able to convert a Tuple to a Traversable. Word of warning. Unlike collections Tuples are very often not homogeneous. IE you do not have
Tuple2[Int]
you have Tuple2[A,B]
. So the best you can do is to map a tuple to an Iterator[Any]. Note: this was done with Scala 2.8 so results may be slightly different with 2.7. But I believe the syntax is valid.
- // the productIterator method gives access to an iterator over the elements
- scala> (1,2,3).productIterator.map {_.toString} mkString (",")
- res1: String = 1,2,3
- scala> (1,2,3).productIterator foreach {println _}
- 1
- 2
- 3
- // if you know the tuple is heterogeneous then you can use partial functions
- // for casting the elements to a particular type.
- scala> (1,2,3).productIterator map {case i:Int => i + 2} foreach {println _}
- 3
- 4
- 5
- // To get a full Traversable out of the deal you use one of the many
- // to* methods to convert to Seq, List, Array, etc...
- scala> (1,2,3).productIterator.toList map {case i:Int => i + 2}
- res15: List[Int] = List(3, 4, 5)
- // and if you want you can use an implicit to clean up the syntax a bit
- // Problem with this is you need an implicit for each Tuple length
- scala> implicit def tupleToTraversable[T](t:(T,T,T)) = t.productIterator.toList map { case e:T => e}
- warning: there were unchecked warnings; re-run with -unchecked for details
- tupleToTraversable: [T](t: (T, T, T))List[T]
- scala> (1,2,3) foreach {println _}
- 1
- 2
- 3
- /*
- EDIT: Dan pointed out that the methods I am using are inherited from the
- Product super class of Tuple. So you can do something similar as follows.
- Note: I am using the same name as the previous method so that they don't interfer
- with one another
- */
- scala> implicit def tupleToTraversable[T](t:Product) = t.productIterator.toList map { case e:T => e}
- warning: there were unchecked warnings; re-run with -unchecked for details
- tupleToTraversable: [T](t: Product)List[T]
- scala> (1,2,3) foreach {println _}
- 1
- 2
- 3
- // this is interesting... it does cast to int unless required
- scala> (1,2,'t') foreach {println _}
- 1
- 2
- t
- // lets verify we are getting correct conversion
- scala> def inc(l:List[Int]) = l map {_ + 1}
- inc: (l: List[Int])List[Int]
- scala> inc ( (1,2,3))
- res4: List[Int] = List(2, 3, 4)
- // yep this I expected
- scala> inc ( (1,2,'t'))
- java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Integer
- at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
- at $anonfun$inc1ドル.apply(< console>:7)
- at scala.collection.TraversableLike$$anonfun$map1ドル.apply(TraversableLike.scala:238)
- at .< clinit>(< console>)
- scala> def inc(l:List[Int]) = l foreach {println _}
- inc: (l: List[Int])Unit
- scala> def p(l:List[Int]) = l foreach {println _}
- p: (l: List[Int])Unit
- scala> p ( (1,2,'t'))
- 1
- 2
- t
Labels:
collections,
Scala,
tuple
Wednesday, December 16, 2009
Specs BDD Testing framework
This is the second Scala test framework topic and focuses on the excellent Specs framework. The other topic was on ScalaTest, another excellent testing framework for Scala.
Specs is focussed on BDD testing (Behaviour Driven Design) and is the inspiration for ScalaTests WordSpec. From what I understand Specs was in-turn inspired by RSpec the Ruby BDD testing framework.
Specs has some truly unique features to it which we will encounter in future topics. But for now just the basics. The following example tests a couple of Scala's XML support in order to demonstract the general pattern followed when writing Specs' tests.
Specs is focussed on BDD testing (Behaviour Driven Design) and is the inspiration for ScalaTests WordSpec. From what I understand Specs was in-turn inspired by RSpec the Ruby BDD testing framework.
Specs has some truly unique features to it which we will encounter in future topics. But for now just the basics. The following example tests a couple of Scala's XML support in order to demonstract the general pattern followed when writing Specs' tests.
- # scala -classpath ~/.m2/repository/org/scala-tools/testing/specs/1.6.1/specs-1.6.1.jar
- scala> import org.specs._
- import org.specs._
- scala> object XmlSpec extends Specification {
- | val sample = <library>
- | <videos>
- | <video type="dvd">Seven</video>
- | <video type="blue-ray">The fifth element</video>
- | <video type="hardcover">Gardens of the moon</video>
- | </videos>
- | <books>
- | <book type="softcover">Memories of Ice</book>
- | </books>
- | </library>
- | "Scala XML" should {
- | "allow xpath-like selection" in {
- | (sample \\ "video").size must be (3)
- | }
- | "select child nodes" in {
- | // This test fails because child is a sequence not a string
- | // See the results of the tests
- | sample.child must contain (<videos/>)
- | }
- | }
- | }
- defined module XmlSpec
- scala> XmlSpec.main(Array[String]())
- Specification "XmlSpec"
- Scala XML should
- + allow xpath-like selection
- x select child nodes <-- x indicates failure.
- 'ArrayBuffer(
- , <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
- <video type="hardcover">Gardens of the moon</video>
- </videos>,
- , <books>
- <book type="softcover">Memories of Ice</book>
- </books>,
- )' doesn't contain '<videos></videos>' (< console>:24)
- Total for specification "XmlSpec":
- Finished in 0 second, 52 ms
- 2 examples, 2 expectations, 1 failure, 0 error
By-name-parameter to Function
Today's topic is related to Defining Custom Control Structures. By name parameters are not function objects in the same way as other functions. Normally you need to invoke a function:
Compare that to a by-name-parameter function:
So the issue is how can you pass a by-name-parameter to a method that takes a function as a parameter without having to do:
the alternative syntax is:
- scala> def exec(func: () => Int) = func()
- exec: (() => Int)Int
- // exec invokes the function so 10 is the result
- scala> exec (() => 10)
- res1: Int = 10
- scala> def exec(func: () => Int) = func
- exec: (() => Int)() => Int
- // here exec returns the function:
- scala> exec (() => 10)
- res2: () => Int = <function>
Compare that to a by-name-parameter function:
- scala> def exec(func: => Int) = func
- exec: (=> Int)Int
- // by-name-parameters are executed when they are referenced
- // so the result is 10
- scala> exec {10}
- res3: Int = 10
- // This is not legal because by-name-parameters
- // are not normal functions
- scala> def exec(func: => Int) = func()
- <console>:4: error: func of type Int does not take parameters
- def exec(func: => Int) = func()
So the issue is how can you pass a by-name-parameter to a method that takes a function as a parameter without having to do:
- scala> def takesFunc(func: () => Int) = println(func())
- takesFunc: (() => Int)Unit
- scala> def send(x: => Int) = takesFunc(() => x)
- send: (=> Int)Unit
- scala> send{2}
- 2
the alternative syntax is:
- scala> def send(x: => Int) = takesFunc (x _)
- send: (=> Int)Unit
- scala> send {2}
- 2
Labels:
by-name-parameter,
control structure,
function,
Scala
Sunday, December 13, 2009
Danger: Shadowed member values
It is possible (although not recommended) to declare a public property in a super class and have a private value or variable in a subclass:
This begs the question: how can the subclass access the superclass instance of i? Let me re-iterate. Just because it is possible this is a bad idea. This pattern seems like it is begging to create bugs. But who knows there is probably some reason out there where this is required.
The way to access the X.i value from Y is to declare which value you want using the syntax this:X :
Repeat: Watch out! Because I learned this danger while writing this topic:
It seems that the syntax (this:X).i accesses the public accessor for i. The public access is a method call I think so it always obtains the value for the property. Shocking!
- scala> class X (val i:Int)
- defined class X
- scala> class Y(i:Int) extends X(19) {
- | println(i)
- | }
- defined class Y
- scala> val y = new Y(100)
- 100
- y: Y = Y@3e55a58f
- scala> y.i
- res7: Int = 19
This begs the question: how can the subclass access the superclass instance of i? Let me re-iterate. Just because it is possible this is a bad idea. This pattern seems like it is begging to create bugs. But who knows there is probably some reason out there where this is required.
The way to access the X.i value from Y is to declare which value you want using the syntax this:X :
- scala> class Y(i:Int) extends X(19) {
- | println("Y.i"+i)
- | println("X.i"+(this:X).i)
- | }
- defined class Y
- scala> new Y(39)
- Y.i39
- X.i19
- res8: Y = Y@451dfada
Repeat: Watch out! Because I learned this danger while writing this topic:
- scala> class Y(i:Int) extends X(19) {
- | println("1. "+i)
- | println("2. "+this.i)
- | println("3. "+(this:Y).i)
- | println("4. "+(this:X).i)
- | }
- defined class Y
- scala> new Y(44)
- 1. 44
- 2. 44
- 3. 19 // this is created via (this:Y).i !
- 4. 19
- res0: Y = Y@338bd37a
It seems that the syntax (this:X).i accesses the public accessor for i. The public access is a method call I think so it always obtains the value for the property. Shocking!
Thursday, December 10, 2009
XML transformations 2
This topic is a continuation of XML Transformations. The previous topic showed a method of creating transformation rules then combining the rules to create a transformation that could be applied to an XML datastructure. This topic takes a different approach of
using a match statement an a recursive method to iterate through the tree.
using a match statement an a recursive method to iterate through the tree.
- scala> val xml = <library>
- | <videos>
- | <video type="dvd">Seven</video>
- | <video type="blue-ray">The fifth element</video>
- | <video type="hardcover">Gardens of the moon</video>
- | </videos>
- | <books>
- | <book type="softcover">Memories of Ice</book>
- | </books>
- | </library>
- xml: scala.xml.Elem =
- <library>
- <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
- <video type="hardcover">Gardens of the moon</video>
- </videos>
- <books>
- <book type="softcover">Memories of Ice</book>
- </books>
- </library>
- scala> import scala.xml._
- import scala.xml._
- scala> def moveElements (node:Node) : Node = node match {
- | case n:Elem if (n.label == "videos") =>
- | n.copy( child = n.child diff mislabelledBooks)
- | case n:Elem if (n.label == "books") =>
- | val newBooks = mislabelledBooks map { e => e.asInstanceOf[Elem].copy(label="book") }
- | n.copy( child = n.child ++ newBooks)
- | case n:Elem =>
- | val children = n.child map {moveElements _}
- | n.copy(child = children)
- | case n => n
- | }
- moveElements: (node: scala.xml.Node)scala.xml.Node
- scala> moveElements(xml)
- res1: scala.xml.Node =
- <library>
- <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
-
- </videos>
- <books>
- <book type="softcover">Memories of Ice</book>
- <book type="hardcover">Gardens of the moon</book></books>
- </library>
Labels:
intermediate,
Scala,
transformation,
xml
Xml Transformation 1
Unlike most Java Xml Apis the Scala Object model consists of immutable object. This has two major consequences:
Both point cause non-functional programmers to feel a little uneasy but in practice only the first restriction causes any real discomfort.
Two methods for XML transformation will be demonstrated in this and the next topic.
- There is no reference to the parent node because that would cause the XML to be very expensive during transformations
- Transforming the XML requires creating new nodes rather than changing the existing nodes
Both point cause non-functional programmers to feel a little uneasy but in practice only the first restriction causes any real discomfort.
Two methods for XML transformation will be demonstrated in this and the next topic.
- scala> val xml = <library>
- | <videos>
- | <video type="dvd">Seven</video>
- | <video type="blue-ray">The fifth element</video>
- | <video type="hardcover">Gardens of the moon</video>
- | </videos>
- | <books>
- | <book type="softcover">Memories of Ice</book>
- | </books>
- | </library>
- xml: scala.xml.Elem =
- <library>
- <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
- <video type="hardcover">Gardens of the moon</video>
- </videos>
- <books>
- <book type="softcover">Memories of Ice</book>
- </books>
- </library>
- scala> import scala.xml._
- import scala.xml._
- scala> import scala.xml.transform._
- import scala.xml.transform._
- // Some of the books are labelled as videos
- // not books so lets select those elements
- scala> val mislabelledBooks = xml \\ "video" filter {e => (e \\ "@type").text == "hardcover"}
- mislabelledBooks: scala.xml.NodeSeq = <video type="hardcover">Gardens of the moon</video>
- // we can create a rule that will remove all the
- // selected elements
- scala> object RemoveMislabelledBooks extends RewriteRule {
- | override def transform(n: Node): Seq[Node] ={
- | if (mislabelledBooks contains n) Array[Node]()
- | else n
- | }
- | }
- defined module RemoveMislabelledBooks
- // a quick test to make sure the elements are removed
- scala> new RuleTransformer(RemoveMislabelledBooks)(xml)
- res1: scala.xml.Node =
- <library>
- <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
-
- </videos>
- <books>
- <book type="softcover">Memories of Ice</book>
- </books>
- </library>
- // Now another rule to add them back
- scala> object AddToBooks extends RewriteRule {
- | override def transform(n: Node): Seq[Node] = n match {
- | case e:Elem if(e.label == "books") =>
- | val newBooks = mislabelledBooks map { case e:Elem => e.copy(label="book") }
- | e.copy(child = e.child ++ newBooks)
- | case _ => n
- | }
- | }
- defined module AddToBooks
- // voila done
- scala> new RuleTransformer(RemoveMislabelledBooks, AddToBooks)(xml)
- res4: scala.xml.Node =
- <library>
- <videos>
- <video type="dvd">Seven</video>
- <video type="blue-ray">The fifth element</video>
- </videos>
- <books>
- <book type="softcover">Memories of Ice</book>
- <book type="hardcover">Gardens of the moon</book></books>
- </library>
Labels:
intermediate,
rule,
Scala,
transformation,
xml
Wednesday, December 9, 2009
Futures
Futures are mainly tokens returned by an actor that promises a result sometime in the future. The typical place one encounters a future is from an actor. The !! method of an actor returns a future. However in addition the Futures object provides several methods for doing parallel processing without having to write actors (or threads for that matter.)
Note: My use of scala.util.Random requires Scala 2.8 but I think the rest is 2.7.7.
Note: My use of scala.util.Random requires Scala 2.8 but I think the rest is 2.7.7.
- scala> import scala.actors.Futures._
- import scala.actors.Futures._
- /*
- The most basic future example.
- Just runs the function in a seperate thread and returns a Future object
- for the result
- */
- scala> future {Thread.sleep(10000);println("hi");10}
- res2: scala.actors.Future[Int] = < function0>
- /*
- Use one of the future methods for obtaining the actual result
- this one blocks tile ready, but other can check if result is ready and so on
- */
- scala> res2()
- hi
- res3: Int = 10
- /*
- This is more interesting.
- The method creates several futures and the using the awaitAll method
- waits for all the futures to complete before continuing
- */
- scala> def bubbles = {
- | val bubbles = for( i <- 1 to 20) yield {
- | future {
- | Thread.sleep(scala.util.Random.nextInt(20)*500)
- | println("pop "+i)
- | "pop "+i
- | }
- | }
- | awaitAll(30000, bubbles:_*) foreach println _
- | }
- bubbles: Unit
- scala> bubbles
- pop 9
- pop 12
- pop 11
- pop 5
- pop 3
- pop 14
- pop 20
- pop 10
- pop 1
- pop 4
- pop 16
- pop 6
- pop 7
- pop 2
- pop 8
- pop 18
- pop 15
- pop 19
- pop 17
- pop 13
- Some(pop 1)
- Some(pop 2)
- Some(pop 3)
- Some(pop 4)
- Some(pop 5)
- Some(pop 6)
- Some(pop 7)
- Some(pop 8)
- Some(pop 9)
- Some(pop 10)
- Some(pop 11)
- Some(pop 12)
- Some(pop 13)
- Some(pop 14)
- Some(pop 15)
- Some(pop 16)
- Some(pop 17)
- Some(pop 18)
- Some(pop 19)
- Some(pop 20)
- scala> import java.net._
- import java.net._
- scala> import scala.io._
- import scala.io._
- /*
- A kind of funny example. We set off two futures to download the google page
- and print the first that finishes
- */
- scala> def load = {
- | val com = future {
- | val comStream = new URL("http://www.google.com").openStream()
- | Source.fromInputStream(comStream).getLines().mkString("\n")
- | }
- | val ch = future {
- | val chStream = new URL("http://www.google.ch").openStream()
- | Source.fromInputStream(chStream).getLines().mkString("\n")
- | }
- | awaitEither(ch,com)
- | }
- load: Any
- scala> load
- res0: Any =
- & !doctype html...
Labels:
actor,
future,
intermediate,
Scala
Tuesday, December 8, 2009
Labelled Multiple Returns
A cool idea I found at http://stackoverflow.com/questions/1827672/is-there-a-way-to-have-tuples-with-named-fields-in-scala-similar-to-anonymous-cl. A very simple idea but very useful.
To summarize, you want to return multiple values but want to assign names to the values rather than use a tuple which more or less assigns indices to the different values. Here are a couple of solutions:
Using structured types. Simplest solution with the least extra code.
Using case classes. Returns a product which has properties that may be useful.
To summarize, you want to return multiple values but want to assign names to the values rather than use a tuple which more or less assigns indices to the different values. Here are a couple of solutions:
Using structured types. Simplest solution with the least extra code.
- scala> def multipleReturns1 = {
- | new { val first = 1; val second = 2 }
- | }
- multipleReturns1: java.lang.Object{def first: Int; def second: Int}
- scala> multipleReturns1
- res0: java.lang.Object{def first: Int; def second: Int} = $anon1ドル@549b6976
- scala> res0.first
- res1: Int = 1
- scala> res0.second
- res2: Int = 2
- scala> import res0._
- import res0._
- scala> first
- res3: Int = 1
- scala> second
- res4: Int = 2
Using case classes. Returns a product which has properties that may be useful.
- scala> def moreReturns = {
- | case class Returns (one:Int, two:Int)
- | Returns(1,2)
- | }
- moreReturns: java.lang.Object with ScalaObject with Product{def one: Int; def two: Int}
- scala> moreReturns
- res5: java.lang.Object with ScalaObject with Product{def one: Int; def two: Int} = Returns(1,2)
- scala> res5.one
- res6: Int = 1
- scala> res5.two
- res7: Int = 2
- scala> import res5._
- import res5._
- scala> one
- res8: Int = 1
- scala> two
- res9: Int = 2
- scala> res5.productIterator foreach println _
- 1
- 2
- scala> res5.productPrefix
- res15: java.lang.String = Returns
Labels:
case-classes,
intermediate,
Scala,
structural types
Monday, December 7, 2009
Scala cheat sheet
One can never go wrong with a Cheat sheet. It is not all there but it is a nice start and well worth looking through.
http://anyall.org/scalacheat/
http://anyall.org/scalacheat/
Labels:
Scala
Scala 2.8 Traversable and IndexedSequence
This topic is really just a collection of examples using the Scala 2.8 API. The examples are mostly based on Strings. But because Strings are in fact an IndexedSeq all of these examples also work with Lists arrays and the first several work with all collections.
These examples are all based on first Traversable. The basis of all collections and therefore will work with all collections. And the next set of examples work with IndexedSeq and most will work with Seq as well. Sets, Maps and others still need to be examined.
This is not an exhaustive set of examples and not all are even that interesting (sorry :-) ). But I let out the most trivial unless theay are being compared to others.
Traversable:
IndexedSequense additions to Traversable:
These examples are all based on first Traversable. The basis of all collections and therefore will work with all collections. And the next set of examples work with IndexedSeq and most will work with Seq as well. Sets, Maps and others still need to be examined.
This is not an exhaustive set of examples and not all are even that interesting (sorry :-) ). But I let out the most trivial unless theay are being compared to others.
Traversable:
- scala> val license = """Subject of Agreement. ?Product?, as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation."""
- res0: RandomAccessSeq[Char] =
- license: java.lang.String = ...
- scala> license count (_ == 'u')
- res1: Int = 37
- scala> license split ' ' count {_ == "and"}
- res3: Int = 6
- scala> license ++ " this is silly!"
- res0: RandomAccessSeq[Char] = ...
- scala> license dropWhile { _ != 'y'} drop 1 takeWhile { _ != 'y'}
- res6: Seq[Char] = RandomAccessSeqTW( , s, o, ...
- scala> license forall {_ != 'z'}
- res8: Boolean = true
- scala> (1 until 5).init
- res0: scala.collection.immutable.Range = Range(1, 2, 3)
- scala> (1 until 5).head
- res1: Int = 1
- scala> (1 until 5).tail
- res2: scala.collection.immutable.IndexedSeq[Int] = Range(2, 3, 4)
- scala> (1 until 5).last
- res3: Int = 4
- scala> (1 until 5).headOption
- res4: Option[Int] = Some(1)
- scala> (1 until 5).lastOption
- res6: Option[Int] = Some(4)
- scala> license max
- res8: Char = y
- scala> license min
- res9: Char =
- scala> List() nonEmpty
- res10: Boolean = false
- scala> List() isEmpty
- res11: Boolean = true
- scala> license partialMap {case c if ('a' to 'z' contains c) => c}
- res13: scala.collection.immutable.IndexedSeq[Any] = IndexedSeq(u, b, j, e, c ...)
- scala> 1 to 10000 by 2 product
- res19: Int = 481029393
- scala> 1 to 10000 by 2 sum
- res23: Int = 25000000
- scala> license partition {"aeiou" contains _}
- res20: (String, String) = (ueoeeeouaeeeoiieeeaeeia ....
- scala> license span {_ != 'a'}
- res22: (String, String) = (Subject of Agreement. ?Product?, ,as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with differ ...
- scala> val consonants = license withFilter {c => !("aeiuo" contains c)}
- consonants: scala.collection.immutable.StringOps#WithFilter = scala.collection.TraversableLike$WithFilter@78e8a591
- scala> consonants foreach print _
- Sbjct f Agrmnt. ?Prdct?, s rfrrd t n ths Agrmnt, shll b th bnry sftwr pckg ?Sn VrtlBx,? whch Prdct llws fr crtng mltpl vrtl cmptrs, ch wth dffrnt prtng systms (?Gst Cmptrs?), n physcl cmptr wth spcfc prtng systm (?Hst Cmptr?), t llw fr nstllng nd xctng ths Gst Cmptrs smltnsly. Th Prdct cnssts f xctbl fls n mchn cd fr th Slrs, Wndws, Lnx, nd Mc?OS?X prtng systms s wll s thr dt fls s rqrd by th xctbl fls t rn-tm nd dcmnttn n lctrnc frm. Th Prdct nclds ll dcmnttn nd pdts prvdd t Y by Sn ndr ths Agrmnt nd th trms f ths Agrmnt wll pply t ll sch dcmnttn nd pdts nlss dffrnt lcns s prvdd wth n pdt r dcmnttn.
IndexedSequense additions to Traversable:
- scala> '!' +: license
- res33: String = !Subject of Agreement
- scala> "hello" +: license
- res32: scala.collection.immutable.IndexedSeq[Any] = IndexedSeq(hello, S, u, b, j, e, c, t, , o, f, , A, g, r, e, e, m, e, n, t, ., , ?, P, r, o, d, u, c, t, ?, ,, , a, s, , r, e, f, e, r, r, e, d, , t, o, , i, n, , t, h, i, s, , A, g, r, e, e, m, e, n, t, ,, , s, h, a, l, l, , b, e, , t, h, e, , b, i, n, a, r, y, , s, o, f, t, w, a, r, e, , p, a, c, k, a, g, e, , ?, S, u, n, , V, i, r, t, u, a, l, B, o, x, ,, ?, , w, h, i, c, h, , P, r, o, d, u, c, t, , a, l, l
- scala> license(11)
- res35: Char = A
- scala> license diff ("aeiou")
- res47: String = Sbjct f Agreement. ?Product?, s referred to n this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation.
- scala> license dropRight(30)
- res48: String = Subject of Agreement. ?Product?, as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided wi
- scala> license takeRight(10)
- res49: String = mentation.
- scala> license indexWhere { "aeiou" contains _}
- res4: Int = 1
- scala> license lastIndexWhere { "aeiou" contains _}
- res6: Int = 873
- scala> List(1,2,3) flatten {0 to _}
- res7: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3)
- scala> ' ' +: license zip license indexWhere {case (last, c) => "" + last + c == "an"}
- res14: Int = 343
- scala> license indexOfSlice ("and")
- res17: Int = 342
- scala> ('a' to 'z') ++ ('A' to 'Z')
- res25: scala.collection.IndexedSeqView[Char,IndexedSeq[_]] = IndexedSeqViewA(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)
- scala> license intersect res25
- res26: String = SubjectofAgrmnPdasihlywpkVBxvGCHTWLMOXqY
- scala> license diff res25
- res27: String = eeet. ?rouct?, referred to n tis Agreement, shal be the binar softare acage ?Sun irtualo,? which Product allows for creating multiple irtual computers, each with different operating systems (?uest omputers?), on a physical computer with a specific operating system (?ost Computer?), to allow for installing and executing these Guest Computers simultaneously. he Product consists of executable files in machine code for the Solaris, indows, inux, and ac?S? operating systems as well as other data files as reuired by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to ou by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation.
- scala> license filter res25
- < console>:7: error: type mismatch;
- found : scala.collection.IndexedSeqView[Char,IndexedSeq[_]]
- required: (Char) => Boolean
- license filter res25
- ^
- scala> license filter {res25 contains _}
- res29: String = SubjectofAgreementProductasreferredtointhisAgreementshallbethebinarysoftwarepackageSunVirtualBoxwhichProductallowsforcreatingmultiplevirtualcomputerseachwithdifferentoperatingsystemsGuestComputersonaphysicalcomputerwithaspecificoperatingsystemHostComputertoallowforinstallingandexecutingtheseGuestComputerssimultaneouslyTheProductconsistsofexecutablefilesinmachinecodefortheSolarisWindowsLinuxandMacOSXoperatingsystemsaswellasotherdatafilesasrequiredbytheexecutablefilesatruntimeanddocumentationinelectronicformTheProductincludesalldocumentationandupdatesprovidedtoYoubySununderthisAgreementandthetermsofthisAgreementwillapplytoallsuchdocumentationandupdatesunlessadifferentlicenseisprovidedwithanupdateordocumentation
- scala> license filterNot {res25 contains _}
- res30: String = . ??, , ? ,? , (? ?), (? ?), . , , , ?? - . .
- scala> license removeDuplicates
- res31: String = Subject ofAgrmn.?Pd,asihlywpkVBxv(GC)HTWLMOXq-Y
- scala> license segmentLength ({_ > 'A'},2)
- res37: Int = 5
- scala> license drop 2 span {_ > 'A'} _1
- res41: String = bject
- scala> license sortWith Ordering.Char
- res45: String = (()),,,,,,,,,-....??????????AAAABCCCGGHLMOPPPPSSSSSTTVWXYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefffffffffffffffffggggggggggghhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiijkllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooooooooooooooooooooooooooooooooooooooooopppppppppppppppppppqrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrsssssssssssssssssssssssssssssssssssssssssssssssttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvwwwwwwwwwwxxxxxyyyyyyyyy
- scala> 'a' to 'z' union ('A' to 'Z')
- scala> "hello world" patch (6, "goof", 5)
- res51: String = hello goof
- scala> "hello world" updated(0,'H')
- res54: String = Hello world
Labels:
collections,
intermediate,
Scala,
seq,
traversable
Friday, December 4, 2009
Yet more instances of '_'
A few more placeholder instances that I have remembered or was reminded of.
- scala> class MyClass {
- | var a:Int = _ // 1
- | def countDown = 10 to 5 by -1
- | }
- defined class MyClass
- scala> val obj = new MyClass()
- obj: MyClass = MyClass@6ff0239
- scala> val countDownMethod = obj.countDown _ // 2
- countDownMethod: () => Range = < function>
- scala> def multiple(a:Int)(b:Int) = a*b
- multiple: (Int)(Int)Int
- scala> val triple = multiple(3) _ // 3
- triple: (Int) => Int = < function>
- scala> List(1,2,3) foreach { _ => Console.println("Hello") } // 4
- Hello
- Hello
- Hello
- initialize a variable to its default value. If the = _ is left out then the definition will be an abstract declaration and will have to be defined in subclasses
- create a reference to the method (rather than invoking the method and having a reference to the resulting value) (Thanks Daniel)
- This is an example of currying; a new function is created with a single parameter.
- where the underscore is used as an ignored and unnamed parameter (Thanks Alex)
Labels:
intermediate,
Scala,
underscore
Wednesday, December 2, 2009
What the @*!% is with the '_'
- scala> import java.io._ // 1
- import java.io._
- scala> import java.io.{ File => _ } // 2
- import java.io.{File=>_}
- scala> object MyObj{ def count=(1 to 10) }
- defined module MyObj
- scala> import MyObj._ // 3
- import MyObj._
- scala> class MyClass { def countDown= 10 to 5 by -1}
- defined class MyClass
- scala> val instance = new MyClass()
- instance: MyClass = MyClass@69ebcd0
- scala> import instance._ // 4
- import instance._
- scala> def multiply(by:Int,x:Int)=2*x
- multiply: (Int,Int)Int
- scala> val double=multiply(2, _:Int) // 5
- double: (Int) => Int
- scala> count foreach {i => double(i)}
- scala> val double2:Int=>Int = multiply(2,_)
- double2: (Int) => Int = & function>
- scala> count foreach {i => double2(i)}
- scala> count reduceLeft {_+_} // 6
- res3: Int = 55
- class Generic[T](val t:T)
- val generic:Generic[_] = new Generic(2) // 7
While at a glance the underscores do not seem related, in fact the general rule is fill in the blank. Sca_la what goes in the blank?
Going through the examples:
- import anything/everything in package
- this seems to be an exception. Assign File to oblivion. (It is no longer imported)
- import all methods in object
- same thing. Import all methods in instance object
- creat a new method where the first parameter is defined but all others will be defined later. In this case a special syntax is required so the compiler knows that a new method is desired and the missing parameters was not simply a mistake. There is another syntax for defining methods that do not require the _ for currying
- reduceLeft takes method with 2 parameters.
_ + _
creates a function of 2 parameters: the first '_' represents the first parameter and the second '_' represents the second parameter. - the '_' represents any value. This syntax is frowned upon since Scala has such a rich type system but can be useful when interoperating with Java. Perhaps a better declaration would be
Generic[Any]
Labels:
import,
Scala,
underscore
Subscribe to:
Posts (Atom)