tag:blogger.com,1999:blog-50897733524049816352024-03-12T18:30:32.434-07:00Daily scalaA short daily dose of scala examples and occasionally explanations.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.comBlogger163125tag:blogger.com,1999:blog-5089773352404981635.post-41283937385252710722012-10-05T11:17:00.000-07:002012-10-05T11:17:15.346-07:00Scala-IO Core: Unmanaged ResourcesThe main design of Scala-IO is around automatic closing of resources each time a resource is accessed in order to ensure that a programmer cannot unintentionally leave resources open in the face of exceptions or other unexpected situations. However, there are cases where the Scala-IO API is desired but the resource management is undesired. The classic case is of reading or writing to System.in and out. Thus Unmanaged resources exist to satisfy this use-case.
<br />
<br />
Since unmanaged resources is a less common use-case there is not a factory object like there is for normal <i>managed</i> Resources. Instead certain objects can be converted to unmanaged resources using the JavaConverters implicit methods as follows:<br />
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
// JavaConverters implicit methods are required to create the
// unmanaged resources
scala> import scalax.io.JavaConverters._
import scalax.io.JavaConverters._
// now that JavaConverters are in scope we can convert
// System.out to a Output object and use it as any normal
// output object except that the stream will not be closed
// WriteableByteChannels can also be converted
scala> System.out.asUnmanagedOutput.write("Not closing right?")
Not closing right?
// See, still not closed
scala> System.out.asUnmanagedOutput.write("Still not closed?")
Still not closed?
scala> import java.io._
import java.io._
// another demonstration of converting an output stream to a
// unmanaged Output object. This is frowned upon unless
// unavoidable.
scala> val fout = new FileOutputStream("somefile.txt")
fout: java.io.FileOutputStream = java.io.FileOutputStream@23987721
scala> val foutOutput = fout.asUnmanagedOutput
foutOutput: scalax.io.Output = scalax.io.unmanaged.WritableByteChannelResource@36b54a77
scala> foutOutput.write("Hello ")
scala> foutOutput.write("World!")
scala> fout.close
// see the output object is broken now because the stream is closed
scala> foutOutput.write("boom")
No Main Exception
---
class java.nio.channels.ClosedChannelException(null)
...
// The mirror image is converting an input stream to an Input object
scala> val fin = new FileInputStream("somefile.txt")
fin: java.io.FileInputStream = java.io.FileInputStream@4fcbc4de
scala> val chars = fin.asUnmanagedInput.chars
chars: scalax.io.LongTraversable[Char] = LongTraversable(...)
// normally a LongTraversable will close the resource
// but this LongTraversable is obtained from a unmanagedInput
// so can be used multiple times without closing the resource
scala> chars.head
res19: Char = H
scala> chars.head
res20: Char = e
scala> chars.head
res21: Char = l
scala> chars.head
res22: Char = l
// don't forget to close
scala> fin.close
// quick demo of using channels
// the following is a major anti-pattern and is
// here mainly for completeness
scala> val fchannel = new RandomAccessFile("somefile.txt", "rw").getChannel
fchannel: java.nio.channels.FileChannel = sun.nio.ch.FileChannelImpl@1e10cb60
scala> val fInput2 = fchannel.asUnmanagedInput
fInput2: scalax.io.Input = scalax.io.unmanaged.ReadableByteChannelResource@679a339e
scala> println(fInput2.string)
Hello World!
scala> fchannel.isOpen
res13: Boolean = true
scala> val fOutput = fchannel.asUnmanagedOutput
fOutput: scalax.io.Output = scalax.io.unmanaged.WritableByteChannelResource@9cc8b91
scala> fOutput.write("hi there")
scala> println(fInput2.string)
hi thererld!
// don't forget to close
scala> fchannel.close
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com4tag:blogger.com,1999:blog-5089773352404981635.post-74140635295600039362012-09-26T22:35:00.000-07:002012-09-26T22:35:17.724-07:00Scala-IO Core: To Resource ConvertersIn order to simplify integration with existing libraries, most commonly Java libraries, Scala-IO provides a JavaConverters object with implicit methods that add as*** methods (asInput, asOutput, asSeekable, etc...) to several types of objects. It is the same pattern as in the scala.collection.JavaConverters object.<br />
<br />
These methods can be used instead of the Resource.from*** methods to provide a slightly nicer appearing code.<br />
<br />
There is one warning. When using JavaConverters, instead of Resource.from*** for creating Input/Output/Seekable/etc... objects, the chances of falling into the trap of creating non-reusable resources or causing a resource leak is increased. See: <a href="http://daily-scala.blogspot.ch/2012/09/scala-io-core-reusable-resources.html">scala-io-core-reusable-resources</a> for more details on this.<br />
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
// JavaConverters object contains the implicit methods
// which add the as*** methods to the applicable _normal_ objects
import scalax.io.JavaConverters._
// Several objects can be converted to input objects using
// asInput. URLs, File, RandomAccessFile, InputStream, Traversable[Byte]
// Array[Byte], ReadableByteChannel
val input = new URL("http://www.camptocamp.com").asInput
// simple demonstation using the newly created input object
println(input.bytes.size)
// asSeekable can only be applied to a few objects at the
// moment. Including RandomAccessFile, SeekableByteChannel,
// File and perhaps in future mutable Sequences
val file = new java.io.File("somefile.txt").asSeekable
// demonstrate a seekable method. This method
// ensures the file is empty
file.truncate(0)
// write hi using the Output API
file.write("hi :)")
// output the file to the console to see the results
println(file.string)
// asUnmanaged*** created Unmanaged resources for
// operations. The Unmanaged Resource post will
// discuss this in more detail but essentially the
// resource is not closed and thus is useful when
// dealing with underlying objects that should not
// be closed like System.out
val unmanagedOutput = System.out.asUnmanagedOutput
// prints to standard out: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
unmanagedOutput.writeStrings(1 to 10 map (_.toString), ", ")
// prints: Hello World
// This demonstrates how a simple Array or Traversable can be easily used
// as an Input object. The array is Hello world encoded as normal latin1
println(Array(72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100).asInput.string)
// prints: Hll Wrld
// Raw Strings and Reader objects cannot currently be converted to an Input object
// but can be converted to ReadChars object (Essentially the character API of Input)
println("Hello World".asReadChars.chars.filterNot(c => "aeiou" contains c) mkString)
// Similarly Writer objects cannot be Output objects since they can't write
// bytes so asWriteChars is used to be able to have the string writing
// capabilities of Scala-IO
new java.io.FileWriter("somefile.txt").asWriteChars write "Hi"
// prints: Hi
println(new java.io.FileReader("somefile.txt").asReadChars.string)
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-56421118796510835982012-09-19T22:39:00.002-07:002012-09-19T22:39:32.995-07:00Scala-IO Core: Reusable Resources<br />
One aspect of resources in Scala-IO that can cause problems is the construction of resource objects. The factory methods that are provided in the Resource object each have a lazy parameter for opening the underlying resource. However a common error developers can make is to pass in the already open resource to the method which has multiple problems. <br />
<br />
Consider:<br />
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
val stream = new java.io.FileOutputStream("somefile.txt")
val output = Resource.fromOutputStream(stream)
output write "hey "
// boom, stream was closed last write
// and the stream cannot be reopened.
output write "how's it going?"
]]></script>
In the example above the stream is created and opened at the definition of stream (it is a val). This has two effects:<br />
<br />
<ol>
<li>the stream is open and if the resource object is not closed you will have a resource leak</li>
<li>since the stream is opened the resource can only be used once since it will be closed after each use.</li>
</ol>
<div>
The correct way to create the resource would be to change <b>val</b> to <b>def</b> so that the stream is only created on demand and therefore there will be no chance of a resource leak. The following is the correct example:</div>
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
def stream = new java.io.FileOutputStream("somefile.txt")
val output = Resource.fromOutputStream(stream)
output write "hey "
// the second write will now work. However since
// the underlying resource is a FileOutputStream
// the file will contain just "how's it going"
output write "how's it going?"
println(Resource.fromFile("somefile.txt").string)
]]></script>
<br />
This anti-pattern is also a risk when using the converter methods in the JavaConverters object. (A future post will look into this in more detail.) The following example shows the anti-pattern in effect:
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import JavaConverters._
val output = new java.io.FileOutputStream("somefile.txt").asOutput
output write "hey "
// Next line will cause exception because
// stream is closed.
output write "how's it going?"
]]></script>
The asOutput method can only be applied to an object (at time of this writing) and therefore the resulting object has all of the negative characteristics mentioned above. Therefore it is recommended that asOutput/asInput/etc... only be used on 1 time use resources (like InputStream) within a scope and not passed out to an external method so that it is easy to view the entirety of the operation.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com0tag:blogger.com,1999:blog-5089773352404981635.post-40599108049812737142012-09-13T11:44:00.003-07:002012-09-13T11:44:53.008-07:00Scala-IO Core: ReadChars and WriteCharsThe Input and Output objects of Scala-IO assume that the underlying data is composed of bytes. However, another common pattern is to have the underlying data be composed of characters instead of bytes, for example java.io.Reader and java.io.Writer. While it is possible to decompose the output into Bytes and construct an Input object from the decorated object, ReadChars and WriteChars can be used in this situation to reduce the work needed to interact with such resources.<br />
<div>
<br /></div>
<div>
ReadChars and WriteChars are traits that contain the character and string methods of Input and Output. The primary difference is that the Charset is defined by the underlying resource rather than supplied at the method invocation site. </div>
<div>
<br /></div>
<div>
Compare two methods:</div>
<div>
<br /></div>
<div>Input:</div>
<pre class="brush: scala">def chars(implicit codec: Codec = Codec.default): LongTraversable[Char]</pre>
ReadChars:<div>
<pre class="brush: scala">def chars: LongTraversable[Char]</pre>
</div>
You will notice that the ReadChars method does not have the codec parameter because there translation is not required, unlike in Input which requires the characters to be created from raw bytes.<br />
<div><br />
Not many examples are needed to explain these concepts but here are a few examples on how to create ReadChar and WriteChar objects:</div>
<div>
<br /></div>
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import JavaConverters._
// JavaConverters has asReadChars and asWriteChars
// for converting some objects to ReadChars and WriteChars
// (The JavaConverters post will explain
// more about the JavaConverters object)
"Hello World".asReadChars.chars.size
val writer = new java.io.StringWriter()
// Resource object can be used to create a ReadChars and WriteChars
val writeChars = Resource.fromWriter(writer).write("Yeee Hawww!")
println(Resource.fromReader(new java.io.StringReader(writer.toString)).lines().size)
// ReadChars and WriteChars can be obtained from
// InputResource and OutputResource object respectively
// SeekableByteChannelResource[SeekableByteChannel]
// (returned by fromFile) implements both traits and
// therefore has both methods
val fileResource = Resource.fromFile("somefile.txt")
implicit val codec = Codec.UTF8
// clear any old data in file
fileResource.truncate(0)
// Codec used is declared when calling writer or reader
// methods
fileResource.writer.write("hi")
println(fileResource.reader.chars.size)
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-86710590938681496722012-08-30T12:03:00.001-07:002012-08-30T12:03:33.486-07:00On VacationI am getting a lot of emails about Scala-IO and my posts. Just want to let everyone know I am on vacation until September 10th or so. I have some posts in the works but they won't be done here where I have virtually no internet.<br />
<br />
Back soon.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com0tag:blogger.com,1999:blog-5089773352404981635.post-30953848924838853632012-08-19T23:11:00.000-07:002012-08-19T23:11:18.987-07:00Scala-IO Core: SeekableAt the same level of abstraction as Input and Output is the fine trait called Seekable. As the name implies it provides random access style methods for interacting with a resource. The example that comes immediately to mind is a random access file. <br />
<br />
The design of Seekable largely mimics the scala.collection.Seq patch and insert methods. Not much more to say beyond getting into some examples:<br />
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import java.io.File
// For this example lets explicitly specify a codec
implicit val codec = scalax.io.Codec.UTF8
val file: Seekable = Resource.fromFile(new File("scala-io.out"))
// delete all data from the file
// or more specifically only keep the data from the beginning of the
// file up to (but not including) the first byte
file truncate 0
val seedData = "Entering some seed data into the file"
file write seedData
// verify seed data was correctly written (in REPL)
file.string
// write "first" after character 9
// if the file is < 9 characters an underflow exception is thrown
// if the patch extends past the end of the file then the file is extended
// Note: The offset is always dependent on type of data being written
// for example if the data written is a string it will be 9 characters
// if the data is bytes it will be 9 bytes
file patch (9, "first",OverwriteAll)
// dumping to REPL will show: Entering firstseed data into the file
file.string
// patch at position 0 and replace 100 bytes with new data
file.patch(0,seedData, OverwriteSome(100))
// dumping to REPL will show the unchanged seedData once again
file.string
// Overwrite only 4 bytes starting at bytes 9.
// the extra bytes will be inserted
// In other words the "some" word of seed data will
// be replaced with second
// Warning: This is an overwrite and an insert
// inserts are expensive since it requires copying the data from
// the index to end of file. If small enough it is done in
// memory but a temporary file is required for big files.
file.patch(9,"second".getBytes(), OverwriteSome(4))
// dumping to REPL will show: Entering second seed data into the file
file.string
// reset file
file.patch(0,seedData, OverwriteSome(100))
// Replace 9 bytes with the 5 bytes that are provided
// In other words: replace "some seed" with "third"
file.patch(9,"third".getBytes(), OverwriteSome(9))
// dumping to REPL will show: Entering third data into the file
file.string
// reset file
file.patch(0,seedData, OverwriteSome(100))
// Insert a string at start of file
file.insert(0, "newInsertedData ")
// dumping to REPL will show: newInsertedData Entering some seed data into the file
file.string
// reset file
file.patch(0,seedData, OverwriteSome(100))
//add !! to end of file
file.append("!!")
// dumping to REPL will show: Entering some seed data into the file!!
file.string
]]></script>
<em>IMPORTANT:</em> Each time truncate() or patch or insert is called a new connection to the file is opened and closed. The Processor API is to be used to perform multiple operations within one connection.<br />
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import java.io.File
val file: Seekable = Resource.fromFile(new File("scala-io.out"))
for {
p <- file.seekableProcessor
seekable = p.asSeekable
} {
seekable truncate 0
seekable write "hi"
seekable append " world"
// one can do patch, insert etc...
// or move the cursor to the correct position and write
// this is essentially a patch(0, "Hi", OverwriteAll)
seekable.position = 0
seekable write "Hi"
seekable patch (3, "W", OverwriteAll)
// dumping to REPL will show: Hi World
println (seekable.string)
}
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com0tag:blogger.com,1999:blog-5089773352404981635.post-24740347263126318712012-08-14T23:21:00.000-07:002012-08-15T20:56:12.192-07:00Scala-IO Core: Output - OutputConverterAs mentioned in the last post on Output, it is possible to write arbitrary objects to an output object and have it serialized to disk. <br />
<br />
The way this is handled in Scala-IO is via OutputConverters. If you are familiar with the type-class pattern then this should be very clear to you how this works. For a very quick introduction you can read: <a href="http://www.sidewayscoding.com/2011/01/introduction-to-type-classes-in-scala.html">http://www.sidewayscoding.com/2011/01/introduction-to-type-classes-in-scala.html</a>.<br />
<br />
The clue is in the signature of write:<br />
<pre class="brush: scala">
def write[T](data: T)(implicit writer: OutputConverter[T]): Unit
</pre>
<br />
<div class="p1">
the last parameter is the object that defines how the object is serialized. The OutputConverter trait essentially converts and object into bytes and has a few built-in implementations in its companion object for objects like Int, Float, Byte, Char, etc... </div>
<div class="p1">
<br /></div>
<div class="p1">
Since the parameter is implicit the compiler will search for an implementation that satisfies the requirements (that the OutputConverter has the type parameter T). This allows:</div>
<pre class="brush: scala">
import scalax.io._
val output:Output = Resource.fromFile("scala-io.out")
output write 3
// and
output write Seq(1,2,3)
// one can be more explicit and declare the OutputConverter
output.write(3)(OutputConverter.IntConverter)
</pre>
The last line in the example shows the explicit declaration of the OutputConverter to use when writing the data. This indicates how one can provide their own converter. <br />
<br />
Since the parameter is implicit there are two ways that custom OutputConverters can be used.
<ul>
<li>defining an implicit object for the object to be written. In this case all the possible ways implicits can be defined can be used. For example as an implicit value or in the companion object of the object to be written (serialized)</li>
<li>Explicitly declare the converter to use at the method call site</li>
</ul>
<br />
First let's examine the use-case where the object is from a different library and therefore we cannot create a companion object for the object.
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import java.util.Date
import scalax.io._
import Resource._
import OutputConverter._
val file = fromFile("scala-io.out")
// Simplest design pattern is to create a new implicit object in scope
implicit object DateConverter extends OutputConverter[Date] {
def sizeInBytes = 8
def toBytes(data: Date) = LongConverter.toBytes(data.getTime)
}
file.write(java.util.Calendar.getInstance().getTime())
// display result in REPL
file.byteArray
// naturally the write method can have the converter
// explicitly declared if you don't want to make the
// object implicit
file.write(java.util.Calendar.getInstance().getTime())(DateConverter)
]]></script>
The second case is where you are implementing the class and therefore can add a companion object:
<br />
For this next bit to work you need to paste it into a file and run that or use the paste mechanism of the REPL (type :paste into repl and press enter)
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import Resource._
import OutputConverter._
class MyData(val name:String)
object MyData {
implicit object Converter extends OutputConverter[MyData] {
def sizeInBytes = 1
def toBytes(data: MyData) = data.name.getBytes("UTF8")
}
}
val file = fromFile("scala-io.out")
// lets quickly delete file to make sure we are dealing with
// and empty file (this is a method on Seekable)
file.truncate(0)
file write (new MyData("jesse"))
// display result in REPL
file.string
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com6tag:blogger.com,1999:blog-5089773352404981635.post-79683880973101391492012-08-08T11:26:00.000-07:002012-08-08T11:26:04.533-07:00Scala-IO Core: OutputThe Output object is the primary trait for writing data to a resource. The basic usage is very simple but can get more complex when one wishes to serialize objects. <br />
<br />
Lets start with the basic usage:
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
import scalax.io.Resource
val out:Output = Resource.fromOutputStream(new java.io.FileOutputStream("daily-scala.out"))
val in:Input = Resource.fromFile("daily-scala.out")
// Write some bytes to the output object
// each write will typically overwrite
//the previous data the processing API
// can be used is you do not want this behaviour
out write "data".getBytes()
out write Array[Byte](1,2,3)
// print out file in REPL
in.byteArray
// Writing strings need a Codec
// for encoding the strings. The default is UTF8
// but the default is easily overridden.
out write "howdy"
// printout file in REPL
in.string
out.write("howdy")(Codec.UTF8)
// printout file in REPL
in.string
implicit val defaultCodec: Codec = Codec.UTF8
// The implicit code will be used instead of the
// default codec
out write "hi there"
// printout file in REPL
in.string
// write all strings in a collection with default separator ("")
out writeStrings Seq("it","was","a","dark","and","stormy","night")
// printout file in REPL
in.string
// write all strings in sequence with a space as the separator
out.writeStrings(Seq("it","was","a","dark","and","stormy","night"), " ")
]]></script>
A common need is to write several times to a single Output without overwriting the data. To do this one can use the processing API. A future post(s) will look at the processing API in more detail but for now a simple example:
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
import scalax.io._
val output:Output = Resource.fromOutputStream(new java.io.FileOutputStream("daily-scala.out"))
val in:Input = Resource.fromFile("daily-scala.out")
// Output processor are used when one
// needs to perform batch writes on an
// output object When a processor object
// is used a "processing" pipeline is
// created and the operations are performed
// in batch form.
// The following example will write 2 lines
// to the output object (a file in this case)
// there are a few ways to use outputProcessors.
// This example is the pattern most developers will
// likely be most comfortable with:
for{
// create a processor (signalling the start of a batch process)
processor <- output.outputProcessor
// create an output object from it
out = processor.asOutput
}{
// all writes to out will be on the same open output stream/channel
out.write("first write\n")
out.write("second write")
}
// show data in REPL
in.string
// As will be shown in the future, a processor is typically lazy
// if created with map and flatmap calls.
// The next example is another way to do the multiple writes.
// first create processor
val processor = for{
// create the processor
out <- output.outputProcessor
// perform write calls
_ <- out.write("second time first write\n")
_ <- out.write("second time second write")
} yield {}
// at this point the writes have not occurred because
// processor contains the processing pipeline
// show data in REPL
in.string
processor.execute // execute processor
// show data in REPL
in.string
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com5tag:blogger.com,1999:blog-5089773352404981635.post-43844373963388808842012-08-06T00:25:00.000-07:002012-08-30T12:14:24.762-07:00Scala-IO Core: Long TraversableThe LongTraversable trait is one of the most important objects in Scala IO. Input provides a uniform way of creating views on the data (as a string or byte array or LongTraversable of something like bytes.)<br />
<br />
LongTraversable is a scala.collection.Traversable with some extra capabilities. A few of the salient points of LongTraversable are:<br />
<ul>
<li>It is a lazy/non-strict collection similar to Stream. In other words, you can perform operations like map, flatmap, filter, collect, etc... without accessing the resource</li>
<li>Methods like slice and drop will (if possible for the resource) skip the dropped bytes without reading them</li>
<li>Each usage of the LongTraversable will typically open and close the underlying resource.</li>
<li>Has methods that one typically finds in Seq. For example: zip, apply, containsSlice</li>
<li>Has methods that take or return Longs instead of Ints like ldrop, lslice, ltake, lsize</li>
<li>Has limitFold method that allows fold like behaviour with extra features like skip and early termination</li>
<li>Can be converted to an AsyncLongTraversable which has methods that return Futures instead and won't block the program</li>
<li>Can be converted to a Process object for advanced data processing pipelines</li>
</ul>
<div>
Example usage:</div>
<script class="brush: scala" type="syntaxhighlighter"><![CDATA[
import scalax.io._
import java.net.URL
val file1 = Resource.fromURL(new URL("http://www.scala-lang.org"))
val file2 = Resource.fromURL(new URL("http://www.camptocamp.com"))
// scala-io versions > 0.4.1 will have method
// Resource.fromURLString("http://xyz.com")
// but earlier versions use an overloaded method:
// Resource.fromURL("http://www.scala-lang.org")
// A simple example of comparing all bytes in
// one file with those of another.
// combining zip with sliding is a good way to perform operations
// on sections of two (or more) files
val zipped = file1.bytes.zip(file2.bytes) map {
case (file1Byte, file2Byte) =>
file2Byte < file1Byte
}
// take the first 5 results and load them into memory
val fiveBytes = zipped.take(5).force
// for debug in REPL lets print them out
fiveBytes mkString ","
// Add a line number to each line in a file
//
// Note: Since methods in a Input object return LongTraversableView objects
// all zip examples do not open the file. To do that you must call
// force or some other method that forces a read to take place.
val addedLineNumbers = file1.lines().zipWithIndex.map {
case (line,idx) => idx+" "+line
}
// print out second group of 5 lines
addedLineNumbers.drop(5).take(5) foreach println
// check if file 1 startsWith file 2
file1.bytes.startsWith(file2.bytes)
// The number of consecutive lines starting at 0 containing <
file1.lines().segmentLength(_ contains "<",0)
// check if all lines in file1 are the same as in file2 ignoring case
file1.lines().corresponds(file2.lines())(_ equalsIgnoreCase _)
// Check if file1has the same bytes as file2
file1.bytes.sameElements(file2.bytes)
// silly example but shows that value
// being compared can be any traversable
file1.bytes.sameElements(1 to 30)
// use sliding to visit each 1008 bytes.
// map splits the window into two parts, block and checksum
val blocks = file1.bytes.sliding(1008,1008).map{_ splitAt 1000}
// grouped is sliding(size,size) so the following is equivalent
val blocks2 = file1.bytes.grouped(1008).map{_ splitAt 1000}
blocks2 foreach {
case (block,checksum) =>
// verify checksum and process
println(block take 5)
}
]]></script>
<div>
<br /></div>
The limitFold method can be quite useful to process only a portion of the file if you don't know ahead of time what the indices of the portion are:
<script class="brush: scala" type="syntaxhighlighter"><![CDATA[
import scalax.io._
import java.net.URL
val in:Input = Resource.fromURL(new URL("http://www.camptocamp.com"))
/**
* Skip first 10 bytes and sum a random number of bytes up
* to 20 bytes
*/
in.bytes.drop(10).take(20).limitFold(10) {
case (acc, next) if util.Random.nextBoolean => End(acc + next)
case (acc, next) => Continue(acc + next)
}
]]></script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-41349852367376272192012-08-02T10:59:00.001-07:002012-08-02T10:59:19.116-07:00Scala-IO Core: Resource, InputJust a note: all these examples have been tested in REPL so go ahead and fire up the sbt console in the example project and try these out.
<h1>
Resource</h1>
<br />
Resource is the fundamental component of Scala-IO. A Resource is essentially anything that has a simple open/close lifecycle. The Resource trait handles the lifecycle for the developer allowing him to focus on the IO logic.<br />
<br />
In the typical use-case one of the Resource subclasses will be used. They are more useful in general because they will have one of higher level traits mixed in like Input or Output.<br />
<br />
The most typical way to create a Resource is with the Resource object which is a factory method for creating Resource objects from various types of Java objects.<br />
<br />
While Resource is the foundation Trait, Input and Output are the Traits most commonly used, The user-facing traits if you will. <br />
<br />
Here are a few examples of creating Resources:
<script class="brush: scala" type="syntaxhighlighter">
<![CDATA[
import scalax.io.Resource
Resource.fromURL("http://www.camptocamp.com")
Resource.fromURL(new java.net.URL("http://www.camptocamp.com"))
Resource.fromFile("file")
Resource.fromFile(new java.io.File("file"))
Resource.fromRandomAccessFile(new java.io.RandomAccessFile("file", "rw"))
Resource.fromByteChannel(new java.io.FileInputStream("file").getChannel)
Resource.fromReadableByteChannel(new java.io.FileInputStream("file").getChannel)
Resource.fromWritableByteChannel(new java.io.FileInputStream("file").getChannel)
Resource.fromInputStream(new java.io.FileInputStream("file"))
Resource.fromOutputStream(new java.io.FileOutputStream("file"))
Resource.fromReader(new java.io.FileReader("file"))
Resource.fromWriter(new java.io.FileWriter("file"))
Resource.fromClasspath("scalax/io/Resource.class")
Resource.fromClasspath("scalax/io/Resource.class", classOf[Resource[_]])
]]>
</script>
There are advanced usages of Resource that we will get into in later posts. At the moment I want to focus on Input, Output and Seekable Traits. In later posts we will look at how to integrate with legacy Java APIs and how to access the underlying resource using the loan pattern.
<h1>
Input</h1>
<br />
The Input Trait provides methods for accessing the data of the underlying resource in various different way. As bytes, strings, lines, etc...<br />
<br />
There are two basic types of methods. Methods that return LongTraversable objects and methods that load the entire Resource into memory. For example: <code>string</code> and <code>byteArray</code> load the entire resource into memory while <code>bytes</code> and <code>chars</code> return a LongTraversable.<br />
<br />
What is a LongTraversable? That will be the next post :-). Summarized, it is a specialized Lazy/non-strict Traversable.
<script class="brush: scala" type="syntaxhighlighter">
<![CDATA[
import scalax.io._
val input:Input = Resource.fromURL("http://www.scala-lang.org")
// The simplest way to read data is to get the bytes from an Input object
val bytes: LongTraversable[Byte] = input.bytes
// you can also get the characters and strings from an Input object but you need a codec for decoding the bytes
val chars: LongTraversable[Char] = input.chars(Codec.UTF8)
// The default encoding is UTF-8 so one can leave of the codec if desired
val defaultChars = input.chars
// Notice that the () are left off input.chars. That is because the codec
// parameter is implicit. This allows the codec to be defined once
// and be used by all chars calls
implicit val codec = Codec.ISO8859
val iso8859chars = input.chars
// The read method in the java InputStream API returns the bytes
// as an integer. For the similar behaviour you can call bytesAsInts
val bytesAsInts = input.bytesAsInts
// There are two useful methods for loading all data into memory
val string = input.string
val array = input.byteArray
// We will revisit it in more detail later but there is an efficient copy method
// for copying the data from the Input object to any Output
// The copy method detects type of the Input Object and the Output
// object and intelligently chooses a method for copying that is
// as efficient as possible.
// For example if the Input is based on a FileInputStream and
// Output is based on a FileOutputStream the FileChannel copyTo
// method is used so that the OS will perform the copy
// efficiently
input copyDataTo Resource.fromFile("file")
// Lines Example 1
// Another useful method is the lines() method which more or less
// does what it implies. The default behaviour will be to Auto
// detect the line ending. For efficiency it finds the end of the first
// line and then assumes the rest of the file has the same ending.
// The terminator is removed by default.
input.lines()
// Lines Example 2
// This example explicitly declares the EOL terminator and
// requests that the terminator is not stripped from the line
import Line.Terminators._
input.lines(terminator=NewLine, includeTerminator=true)
// Lines Example 3
// Lastly lines is not limited to just the standard line endings
// arbitrary separators can be used. This last example
// demonstrates parsing the input into lines using %% as the
// EOL terminator. Additionally it shows the explicit use
// of the Codec to override the in scope implicit Codec
input.lines(terminator=Custom("%%"))(Codec.UTF8)
]]>
</script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-61821104598490589612012-07-27T12:57:00.000-07:002012-08-15T08:18:31.482-07:00Scala-IO Getting StartedFor the next several posts you will need to have Scala-IO installed and probably should have a sbt project as well.<br />
<br />
There are currently 2 Scala-IO 0.4 releases.<br />
<br />
<ul>
<li>Scala-io 0.4-seq - A version of Scala 0.4 without the Akka dependency and therefore no ASync support</li>
<li>Scala-io 0.4 - The full version that contains an Akka dependency</li>
</ul>
<div>
The Scala 2.10 versions will have no Akka dependency but can optionally use Akka.</div>
<div>
<br /></div>
<div>
So getting started:</div>
<div>
<br /></div>
<div>
Download the example project on the docs website (<a href="http://jesseeichar.github.com/scala-io-doc/latest">http://jesseeichar.github.com/scala-io-doc/latest</a>):</div>
<div>
<ul>
<li>Go to <b>Getting Started</b> and follow instructions for downloading and running the example project. The following goes through the steps for the 0.4.1 instructions.</li>
</ul>
<script type="syntaxhighlighter" class="brush: plain"><![CDATA[
curl -L http://jesseeichar.github.com/scala-io-doc/0.4.1/example_projects/example-sbt-project.zip > tmp.zip && unzip tmp.zip && rm tmp.zip
cd example-sbt-project
sbt run
]]></script>
<div>
<br /></div>
</div>
<div>
<br /></div>
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
sbt console
scala> import scalax.io._
import scalax.io._
scala> import java.net.URL
import java.net.URL
scala> Resource.fromURL(new URL("http://www.scala-lang.com")).
| lines().async.size.onComplete(println)
res3: akka.dispatch.Future[Int] = akka.dispatch.DefaultPromise@363adfb4
scala> Right(770)
]]></script>
<br/>
The last line (Right(770)) is not a command to enter; it is the result of the asynchonous call.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-44772478166350038942012-07-26T07:00:00.001-07:002012-08-02T10:50:22.780-07:00Introducing Scala-IO<br />
This is the start of a series of posts on Scala-IO. Scala-IO is as the name implies a library for performing input and output operations with Scala. There are 4 main facets to the library<br />
<br />
<br />
<ul>
<li>Basic IO - Reading and writing to some underlying resource. The current implementation is Java based and thus allows reading and writing to resources like java.io.Readers, Writers, Channels, Streams, etc...</li>
<li>File API - A library loosely designed after java 7 nio.file API with an additional simple unix like DSL for traversing and searching the filesystem. It is a pluggable architecture which allows plugins for systems like WebDav or Zip filesystems to be addressed in a similar manner as the local filesystem. The included implementation is for the local file system and is implemented on the java.io APIs</li>
<li>Asynchronous Access - Throughout the APIs are both synchronous and asynchronous options allowing both models of programming to be easily used. </li>
<ul>
<li>In the 2.10.x + versions the future implementations are pluggable but require no additional libraries if so that is the desire</li>
<li>In 2.9.x versions there are two different dependencies one with asynchronous APIs implemented on Akka and one without any asynchronous APIs</li>
</ul>
<li>Processor API - An API for defining complex IO processes declaratively.</li>
</ul>
<div>
This series will look at normally a small and simple IO operation each day (or so) rather than only a few in-depth articles. This is required because of my limited available time.<br />
<br />
With the introduction done lets look at two small examples:</div>
<div>
<br /></div>
<div>
Read File with Core API (not File API):</div>
<script class="brush: scala" type="syntaxhighlighter">
<![CDATA[
import scalax.io._
// Create a resource from a file. This is a convenience method and the string can be
// a relative path or a absolute path. While this is convenient it is not portable
// so it is recommened to use the File API to create a Path object and read from that
val input:Input = Resource.fromFile("someFile")
// read all bytes into an in memory array
input.byteArray
// skip first 5 bytes and take the next 5
// force the operation to take place.
// The bytes is a ResourceView which is a LongTraversableView,
// meaning it will evaluate lazily until the data is forced
// or requested
input.bytes.drop(5).take(5).force
// read all bytes into a string
// note: codec can be passed implicitely as well
input.string(Codec.UTF8)
]]>
</script>
<div>Same thing but with File API:</div>
<script class="brush: scala" type="syntaxhighlighter">
<![CDATA[
import scalax.file.Path
val path = Path("file")
// read all bytes into an in memory array
path.byteArray
// skip first 5 bytes and take the next 5
// force the operation to take place.
// The bytes is a ResourceView which is a LongTraversableView,
// meaning it will evaluate lazily until the data is forced
// or requested
path.bytes.drop(5).take(5).force
// read all bytes into a string
// note: codec can be passed implicitly as well
path.string(Codec.UTF8)
]]>
</script>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com12tag:blogger.com,1999:blog-5089773352404981635.post-91106659342530581182010-05-27T23:28:00.000-07:002010-05-27T23:28:16.347-07:00zipWithIndexA common desire is to have access to the index of an element when using collection methods like foreach, filter, foldLeft/Right, etc... Fortunately there is a simple way. <br />
<br />
<code>List(<span class="char">'a'</span>,<span class="char">'b'</span>,<span class="char">'c'</span>,<span class="char">'d'</span>).zipWithIndex</code>. <br />
<br />
But wait! <br />
<br />
Does that not trigger an extra iteration through the collection?. Indeed it does and that is where <a href="http://daily-scala.blogspot.com/search/label/view">Views</a> help. <br />
<br />
<code>List(<span class="char">'a'</span>,<span class="char">'b'</span>,<span class="char">'c'</span>,<span class="char">'d'</span>).view.zipWithIndex</code> <br />
<br />
When using a <a href="http://daily-scala.blogspot.com/search/label/view">view</a> the collection is only traversed when required so there is no performance loss.<br />
<br />
Here are some examples of zipWithIndex:<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">val</span> list = List(<span class="char">'a'</span>,<span class="char">'b'</span>,<span class="char">'c'</span>,<span class="char">'d'</span>)</li><li class="codelist ">list: List<span class="type-param">[Char]</span> = List(a, b, c, d)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">/*</span></li><li class="codelist alt"><span class="comment">I like to use functions constructed with case statements</span></li><li class="codelist "><span class="comment">in order to clearly label the index.  The alternative is </span></li><li class="codelist alt"><span class="comment">to use x._2 for the index and x._1 for the value</span></li><li class="codelist "><span class="comment">*/</span></li><li class="codelist alt"><span class="repl">scala></span> list.view.zipWithIndex foreach {<span class="key">case</span> (value,index) => println(value,index)}</li><li class="codelist ">(a,0)</li><li class="codelist alt">(b,1)</li><li class="codelist ">(c,2)</li><li class="codelist alt">(d,3)</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// alternative syntax without case statement</span></li><li class="codelist "><span class="repl">scala></span> list.view.zipWithIndex foreach {e => println(e._1,e._2)}</li><li class="codelist alt">(a,0)</li><li class="codelist ">(b,1)</li><li class="codelist alt">(c,2)</li><li class="codelist ">(d,3)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">/*</span></li><li class="codelist alt"><span class="comment">Fold left and right functions have 2 parameters (accumulator, nextValue) </span></li><li class="codelist "><span class="comment">using a case statement allows you to expand that but watch the brackets!</span></li><li class="codelist alt"><span class="comment">*/</span></li><li class="codelist "><span class="repl">scala></span> (list.view.zipWithIndex foldLeft 0) {<span class="key">case</span> (acc,(value,index)) => acc + value.toInt + index} </li><li class="codelist alt">res14: <span class="basicType">Int</span> = 400</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// alternative syntax without case statement</span></li><li class="codelist "><span class="repl">scala></span> (list.view.zipWithIndex foldLeft 0) {(acc,e) => acc + e._1.toInt + e._2} </li><li class="codelist alt">res23: <span class="basicType">Int</span> = 400</li><li class="codelist "></li><li class="codelist alt"><span class="comment">/*</span></li><li class="codelist "><span class="comment">alternative foldLeft operator.  The thing I like about this</span></li><li class="codelist alt"><span class="comment">syntax is that it has the initial accumulator value on the left </span></li><li class="codelist "><span class="comment">in the same position as the accumulator parameter in the function.</span></li><li class="codelist alt"><span class="comment"></span></li><li class="codelist "><span class="comment">The other thing I like about it is that visually you can see that it starts with</span></li><li class="codelist alt"><span class="comment">"" and the folds left</span></li><li class="codelist "><span class="comment">*/</span></li><li class="codelist alt"><span class="repl">scala></span> (<span class="string">""</span> /: list.view.zipWithIndex) {                          </li><li class="codelist ">     | <span class="key">case</span> (acc, (value, index)) <span class="key">if</span> index % 2 == 0 => acc + value</li><li class="codelist alt">     | <span class="key">case</span> (acc, _) => acc                                       </li><li class="codelist ">     | }</li><li class="codelist alt">res15: java.lang.<span class="basicType">String</span> = ac</li><li class="codelist "></li><li class="codelist alt"><span class="comment">/*</span></li><li class="codelist "><span class="comment">This example filters based on the index then uses map to remove the index</span></li><li class="codelist alt"><span class="comment">force simply forces the view to be processed.  (I love these collections!)</span></li><li class="codelist "><span class="comment">*/</span></li><li class="codelist alt"><span class="repl">scala></span> list.view.zipWithIndex.filter { _._2 % 2 == 0 }.map { _._1}.force</li><li class="codelist ">res29: Seq<span class="type-param">[Char]</span> = List(a, c)</li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com8tag:blogger.com,1999:blog-5089773352404981635.post-71559418794324054082010-05-26T23:41:00.000-07:002010-05-26T23:41:07.546-07:00Return value of a blockA common misunderstanding is that a code block (without parameters) is a function. That is not the case. A code block is a sequence of statements that are executed and result the last statement is returned. That sounds like a Function0, however, if the block is passed to a method/function only the last statement will be returned to the function/method. If that method/function expects a function as the parameter the last statement maybe returned as a function not a value, this means that the block itself is not a function.<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">var</span> count = 0                                                                                                                         </li><li class="codelist ">count: <span class="basicType">Int</span> = 0</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// the last statement is returned as a function so count</span></li><li class="codelist alt"><span class="comment">// is incremented only one during the creation of the function</span></li><li class="codelist "><span class="repl">scala></span> List(1,2,3,4).map{count += 1;_ + 1}</li><li class="codelist alt">res9: List<span class="type-param">[Int]</span> = List(2, 3, 4, 5)</li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> count</li><li class="codelist ">res10: <span class="basicType">Int</span> = 1</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// now the count increment is within the function</span></li><li class="codelist alt"><span class="repl">scala></span> List(1,2,3,4).map{i => count += 1;i + 1}</li><li class="codelist ">res11: List<span class="type-param">[Int]</span> = List(2, 3, 4, 5)</li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> count</li><li class="codelist alt">res12: <span class="basicType">Int</span> = 5</li></ol></div></code> <br />
The previous example demonstrates a Gotcha if I ever saw one. Map expects a function so the block essentially constructs a function. The last statement being the function. The first line <code>count += 1</code> executed only once because it is part of creating the function not part of the resulting function. This is equivalent to:<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">val</span> x = {count += 1 ; i:<span class="basicType">Int</span> => i +1}</li><li class="codelist ">x: (<span class="basicType">Int</span>) => <span class="basicType">Int</span> = < function1></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> List(1,2,3,4).map(x)</li><li class="codelist alt">res15: List<span class="type-param">[Int]</span> = List(2, 3, 4, 5)</li></ol></div></code> <br />
Beginning a block with the parameter list signals that the entire block is a function.<br />
<br />
Rule of thumb: Functions with placeholder parameters should be a single statement.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com6tag:blogger.com,1999:blog-5089773352404981635.post-51695022041052362152010-05-20T00:04:00.001-07:002010-05-20T00:05:31.660-07:00Type Inference with Abstract TypesA second "gotcha" that one might get tripped up when dealing with abstract types is the signature of the concrete class contains type information about the abstract type. So if you are not explicit when assigning a variable or defining a function you can get unexpected compiler errors.<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">trait</span> S {</li>
<li class="codelist ">     |   <span class="key">type</span> x</li>
<li class="codelist alt">     |   <span class="key">def</span> get : x</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">defined <span class="key">trait</span> S</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="repl">scala></span> <span class="key">var</span> sample = <span class="key">new</span> S{ </li>
<li class="codelist ">     |   <span class="key">type</span> x = <span class="basicType">Int</span></li>
<li class="codelist alt">     |   <span class="key">def</span> get = 3</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">sample: java.lang.Object <span class="key">with</span> S{<span class="key">type</span> x = <span class="basicType">Int</span>} = $anon$1<span class="annotation">@</span>397af435</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="repl">scala></span> sample = <span class="key">new</span> S {</li>
<li class="codelist ">     |   <span class="key">type</span> x = <span class="basicType">Double</span></li>
<li class="codelist alt">     |   <span class="key">def</span> get = 3.0</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">< console>:7: error: <span class="key">type</span> mismatch;</li>
<li class="codelist "> found   : java.lang.Object <span class="key">with</span> S</li>
<li class="codelist alt"> required: java.lang.Object <span class="key">with</span> S{<span class="key">type</span> x = <span class="basicType">Int</span>}</li>
<li class="codelist ">       sample = <span class="key">new</span> S {</li>
</ol></div></code> <br />
In this example <em>sample</em> uses type inference so the actual type is <em>S with underlying type Int</em>. The consequence is that <em>sample</em> can only be assigned with instances of S with <em>type x = Int</em>. The fix is to explicitly declare the variable type:<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">var</span> sample2 : S = <span class="key">new</span> S{ </li>
<li class="codelist ">     |   <span class="key">type</span> x = <span class="basicType">Int</span></li>
<li class="codelist alt">     |   <span class="key">def</span> get = 3</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">sample2: S = $anon$1<span class="annotation">@</span>31602bbc</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="repl">scala></span> sample2 = <span class="key">new</span> S {</li>
<li class="codelist ">     |   <span class="key">type</span> x = <span class="basicType">Double</span></li>
<li class="codelist alt">     |   <span class="key">def</span> get = 3.0</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">sample2: S = $anon$1<span class="annotation">@</span>4de5ed7b</li>
</ol></div></code> <br />
The same thing happens when declaring functions and allows type inference for function definition<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">class</span> Fac {</li>
<li class="codelist ">     |   <span class="key">def</span> newS = <span class="key">new</span> S {</li>
<li class="codelist alt">     |     <span class="key">type</span> x = <span class="basicType">Int</span></li>
<li class="codelist ">     |     <span class="key">def</span> get = 3</li>
<li class="codelist alt">     |   }</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">defined <span class="key">class</span> Fac</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="repl">scala></span> <span class="key">class</span> SubFac <span class="key">extends</span> Fac{</li>
<li class="codelist ">     |   <span class="key">override</span> <span class="key">def</span> newS = <span class="key">new</span> S {</li>
<li class="codelist alt">     |     <span class="key">type</span> x = <span class="basicType">Double</span></li>
<li class="codelist ">     |     <span class="key">def</span> get = 3.0</li>
<li class="codelist alt">     |   }</li>
<li class="codelist ">     | }</li>
<li class="codelist alt">< console>:8: error: <span class="key">type</span> mismatch;</li>
<li class="codelist "> found   : java.lang.Object <span class="key">with</span> S</li>
<li class="codelist alt"> required: java.lang.Object <span class="key">with</span> S{<span class="key">type</span> x = <span class="basicType">Int</span>}</li>
<li class="codelist ">         <span class="key">override</span> <span class="key">def</span> newS = <span class="key">new</span> S {</li>
</ol></div></code> <br />
The fix for this example is to be explicit in the definition of the function in the superclassAnonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com2tag:blogger.com,1999:blog-5089773352404981635.post-77034411295597220542010-05-17T02:24:00.000-07:002010-05-17T02:24:30.019-07:00Instance Type (Abstract type gotcha 1)In a previous post about abstract types I showed one of the benefits of using abstract types over parameterized types. <a href="http://daily-scala.blogspot.com/2010/05/abstract-types-vs-parameter.html">Abstract Types vs Parameter</a>. The next several posts will feature potential problems you may encounter when using Abstract Types.<br />
<br />
I should point out that abstract types are not inherently difficult to understand but they are rather different from anything you will see when you come from the Java world so if you are new to them I would use them with caution at first.<br />
<br />
In the <a href="http://daily-scala.blogspot.com/2010/05/abstract-types-vs-parameter.html#full_example">abstract types example</a> you will notice that the abstract type 'I' in Foreach is not within the trait Source rather it is outside in the Foreach trait. At first one might consider putting the type in Source rather than Foreach. The naive change can get you in trouble (but there is a couple easy fixes)<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">trait</span> Foreach<span class="type-param">[A]</span> {</li><li class="codelist ">  <span class="key">trait</span> Source {</li><li class="codelist alt">    <span class="key">type</span> I <: java.io.Closeable  <span class="comment">// moved this line into Source</span></li><li class="codelist ">    <span class="key">def</span> in : I</li><li class="codelist alt">    <span class="key">def</span> next(in : I) : Option<span class="type-param">[A]</span></li><li class="codelist ">  }</li><li class="codelist alt">  <span class="key">def</span> source : Source</li><li class="codelist ">  </li><li class="codelist alt">  <span class="key">def</span> foreach<span class="type-param">[U]</span>(f : A => U) : <span class="singleton">Unit</span> = {</li><li class="codelist ">    <span class="key">val</span> s = source.in</li><li class="codelist alt">    <span class="key">try</span> {</li><li class="codelist ">      <span class="key">def</span> processNext : <span class="singleton">Unit</span> = source.next(s) <span class="key">match</span> {</li><li class="codelist alt">        <span class="key">case</span> None => </li><li class="codelist ">          ()</li><li class="codelist alt">        <span class="key">case</span> Some(value) => </li><li class="codelist ">          f(value)</li><li class="codelist alt">          processNext</li><li class="codelist ">      }</li><li class="codelist alt">      </li><li class="codelist ">      processNext</li><li class="codelist alt">    } <span class="key">finally</span> {</li><li class="codelist ">      <span class="comment">// correctly handle exceptions</span></li><li class="codelist alt">      s.close</li><li class="codelist ">    }</li><li class="codelist alt">  }</li><li class="codelist ">}</li></ol></div></code> <br />
Compiling the class results in a compilation error:<br />
<quot> <br />
jeichar: tmp$ scalac XX.scala <br />
XX.scala:12: error: type mismatch;<br />
found : s.type (with underlying type Foreach.this.Source#I)<br />
required: _2.I where val _2: Foreach.this.Source<br />
def processNext : Unit = source.next(s) match {<br />
^<br />
XX.scala:16: error: type mismatch;<br />
found : value.type (with underlying type Any)<br />
required: A<br />
f(value)<br />
^<br />
two errors found<br />
</quot> <br />
So what is the problem? The problem is simple but subtle. Notice that source is defined as a <em>def</em>. So calling source 2 times may return 2 different instances of Source. A simple change can fix this. Either change def source : Source to val source : Source. Or change the method foreach to assign the result from source to a val.<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">trait</span> Foreach {</li><li class="codelist ">  <span class="key">trait</span> Source {</li><li class="codelist alt">    <span class="key">type</span> I <: java.io.Closeable  <span class="comment">// moved this line into Source</span></li><li class="codelist ">    <span class="key">def</span> in : I</li><li class="codelist alt">    <span class="key">def</span> next(in : I) : Option<span class="type-param">[Int]</span></li><li class="codelist ">  }</li><li class="codelist alt">  <span class="key">def</span> source : Source</li><li class="codelist ">  </li><li class="codelist alt">  <span class="key">def</span> foreach<span class="type-param">[U]</span>(f : <span class="basicType">Int</span> => U) : <span class="singleton">Unit</span> = {</li><li class="codelist ">    <span class="comment">// this assignment allows this example to compile</span></li><li class="codelist alt">    <span class="key">val</span> sameSource = source</li><li class="codelist ">    <span class="key">val</span> s = sameSource.in</li><li class="codelist alt">    <span class="key">try</span> {</li><li class="codelist ">      <span class="key">def</span> processNext : <span class="singleton">Unit</span> = sameSource.next(s) <span class="key">match</span> {</li><li class="codelist alt">        <span class="key">case</span> None => </li><li class="codelist ">          ()</li><li class="codelist alt">        <span class="key">case</span> Some(value) => </li><li class="codelist ">          f(value)</li><li class="codelist alt">          processNext</li><li class="codelist ">      }</li><li class="codelist alt">      </li><li class="codelist ">      processNext</li><li class="codelist alt">    } <span class="key">finally</span> {</li><li class="codelist ">      <span class="comment">// correctly handle exceptions</span></li><li class="codelist alt">      s.close</li><li class="codelist ">    }</li><li class="codelist alt">  }</li><li class="codelist ">}</li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com0tag:blogger.com,1999:blog-5089773352404981635.post-14108216733056306162010-05-03T01:15:00.000-07:002010-05-17T01:09:14.303-07:00Abstract Types vs ParameterThis topic (and the next) are intended to discuss abstract types. A class/trait with an abstract type is quite similar to a class/trait type parameter. For example:<br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">trait</span> C<span class="type-param">[A]</span> {</li>
<li class="codelist "> <span class="key">def</span> get : A</li>
<li class="codelist alt"> <span class="key">def</span> doit(a:A):A</li>
<li class="codelist ">}</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="key">trait</span> C2 {</li>
<li class="codelist alt"> <span class="key">type</span> A</li>
<li class="codelist "> <span class="key">def</span> get : A</li>
<li class="codelist alt"> <span class="key">def</span> doit(a:A):A</li>
<li class="codelist ">}</li>
</ol></div></code><br />
Both implementations have similar properties. However they are <em>NOT</em> the same. At first I thought that I could used them inter-changeably. However, consider the following examples:<br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="comment">//compiles</span></li>
<li class="codelist "><span class="key">def</span> p(c:C<span class="type-param">[Int]</span>) = c.doit(c.get)</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="comment">// doesn't compile</span></li>
<li class="codelist alt"><span class="key">def</span> p2(c:C2) = c.doit(c.get)</li>
</ol></div></code><br />
So why doesn't p2 compile? Because it returns A. From the signature of p2 it is impossible to know what p2 returns. There are several ways to fix this problem. One make the method return Unit:<br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="comment">// compiles because the internals of C2 does not leak out</span></li>
<li class="codelist "><span class="key">def</span> p(c:C2):<span class="singleton">Unit</span> = c.doit(c.get)</li>
</ol></div></code><br />
Another fix would be to change doit to return Unit or an explicit return value like Int<br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">trait</span> C2 {</li>
<li class="codelist "> <span class="key">type</span> A</li>
<li class="codelist alt"> <span class="key">def</span> get : A</li>
<li class="codelist "> <span class="key">def</span> doit(a:A):<span class="basicType">Int</span></li>
<li class="codelist alt">}</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="comment">// compiles correctly</span></li>
<li class="codelist "><span class="key">def</span> p(c:C2) = c.doit(c.get)</li>
</ol></div></code><br />
A second difference between parameterized types and types with abstract type values is illustrated below:<br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">trait</span> C2 {</li>
<li class="codelist "> <span class="key">type</span> A</li>
<li class="codelist alt"> <span class="key">def</span> get : A</li>
<li class="codelist ">}</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="repl">scala></span> <span class="key">var</span> c : C2 = <span class="key">new</span> C2 { </li>
<li class="codelist alt"> | <span class="key">type</span> A = <span class="basicType">Int</span></li>
<li class="codelist "> | <span class="key">def</span> get = 3</li>
<li class="codelist alt"> | }</li>
<li class="codelist ">c: C2 = $anon$1<span class="annotation">@</span>11a40fff</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="comment">// what is the type of result if at compile time the</span></li>
<li class="codelist alt"><span class="comment">// value of c is not known</span></li>
<li class="codelist "><span class="repl">scala></span> <span class="key">var</span> result = c.get</li>
<li class="codelist alt">result: C2#A = 3</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="repl">scala></span> c = <span class="key">new</span> C2 { </li>
<li class="codelist "> | <span class="key">type</span> A = <span class="basicType">String</span></li>
<li class="codelist alt"> | <span class="key">def</span> get = <span class="string">"hi"</span></li>
<li class="codelist "> | }</li>
<li class="codelist alt">c: C2 = $anon$1<span class="annotation">@</span>5f154718</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="comment">// crazy eh :) the variable can be anything but does not</span></li>
<li class="codelist "><span class="comment">// have type Any so you cannot assign arbitrary values</span></li>
<li class="codelist alt"><span class="repl">scala></span> result = c.get</li>
<li class="codelist ">result: C2#A = hi</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="repl">scala></span> result.isInstanceOf<span class="type-param">[String]</span></li>
<li class="codelist alt">res0: <span class="basicType">Boolean</span> = <span class="basicType">true</span></li>
<li class="codelist "></li>
<li class="codelist alt"><span class="comment">// while the dynamic type of result is a string the</span></li>
<li class="codelist "><span class="comment">// static type is not so you cannot assign a string to result</span></li>
<li class="codelist alt"><span class="repl">scala></span> result = <span class="string">"4"</span></li>
<li class="codelist ">< console> :8: error: <span class="key">type</span> mismatch;</li>
<li class="codelist alt"> found : java.lang.<span class="basicType">String</span>(<span class="string">"4"</span>)</li>
<li class="codelist "> required: C2#A</li>
<li class="codelist alt"> result = <span class="string">"4"</span></li>
<li class="codelist "> ^</li>
</ol></div></code><br />
The obvious question is what use are abstract types. I don't claim to know them all but the main point is that they do not expose the internal implementation details to the world. The famous cake pattern is one such example usage of abstract types.<br />
<br />
I read the following as well (wish I could remember where):<br />
<br />
Abstract types are good when extending and there will be concrete subclasses. Param type good for when a type is useful without extension but can handle several types.<br />
<br />
A simpler example is examined here. It is loosely based on a real world usecase. <br />
The example below is contrived so that it is smaller than the actual usecase, so consider the design and not the fact that the example could be easier done with other examples. In the real scenario this design reduced the lines of duplicated code from around 500 to 10.<br />
<br />
The example below shows how a Traversable like object can be created from InputStreams and Readers. The important aspect is that the type signature of Foreach does not leak information about the implementation. Users of a Foreach object don't care whether it is backed onto an InputStream or Reader. They just care about the type of object contained. <br />
<br />
I am leaving this already long post here. The next post will investigate different ways you can get in trouble trying to implement using abstract types.<br />
<br />
<a name="full_example"></a><br />
<code></code><br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">import</span> java.io.{InputStream, Reader, ByteArrayInputStream, StringReader}</li>
<li class="codelist "><span class="key">import</span> java.net.URL</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="key">object</span> Foreach {</li>
<li class="codelist alt"> <span class="key">def</span> fromStream(s: => InputStream) = <span class="key">new</span> Foreach<span class="type-param">[Int]</span> {</li>
<li class="codelist "> <span class="key">type</span> I = InputStream</li>
<li class="codelist alt"> <span class="key">def</span> source = <span class="key">new</span> Source {</li>
<li class="codelist "> <span class="key">def</span> in = s</li>
<li class="codelist alt"> <span class="key">def</span> next(_in : InputStream) = _in.read <span class="key">match</span> {</li>
<li class="codelist "> <span class="key">case</span> -1 => None</li>
<li class="codelist alt"> <span class="key">case</span> i => Some(i)</li>
<li class="codelist "> }</li>
<li class="codelist alt"> }</li>
<li class="codelist "> }</li>
<li class="codelist alt"> </li>
<li class="codelist "> <span class="key">def</span> fromReader(s: => Reader) = <span class="key">new</span> Foreach<span class="type-param">[Char]</span> {</li>
<li class="codelist alt"> <span class="key">type</span> I = Reader</li>
<li class="codelist "> <span class="key">def</span> source = <span class="key">new</span> Source {</li>
<li class="codelist alt"> <span class="key">def</span> in = s</li>
<li class="codelist "> <span class="key">def</span> next(_in : Reader) = _in.read <span class="key">match</span> {</li>
<li class="codelist alt"> <span class="key">case</span> -1 => None</li>
<li class="codelist "> <span class="key">case</span> i => Some(i.toChar)</li>
<li class="codelist alt"> }</li>
<li class="codelist "> }</li>
<li class="codelist alt"> }</li>
<li class="codelist "> </li>
<li class="codelist alt"> </li>
<li class="codelist "> <span class="key">def</span> fromInputAndFunction<span class="type-param">[A]</span>(s: => InputStream, f: <span class="basicType">Int</span> => A) = <span class="key">new</span> Foreach<span class="type-param">[A]</span> {</li>
<li class="codelist alt"> <span class="key">type</span> I = InputStream</li>
<li class="codelist "> <span class="key">def</span> source = <span class="key">new</span> Source {</li>
<li class="codelist alt"> <span class="key">def</span> in = s</li>
<li class="codelist "> <span class="key">def</span> next(_in : InputStream) = _in.read <span class="key">match</span> {</li>
<li class="codelist alt"> <span class="key">case</span> -1 => None</li>
<li class="codelist "> <span class="key">case</span> i => Some(f(i))</li>
<li class="codelist alt"> }</li>
<li class="codelist "> }</li>
<li class="codelist alt"> }</li>
<li class="codelist "> </li>
<li class="codelist alt"> </li>
<li class="codelist ">}</li>
<li class="codelist alt"></li>
<li class="codelist "><span class="key">trait</span> Foreach<span class="type-param">[A]</span> {</li>
<li class="codelist alt"> <span class="key">type</span> I <: java.io.Closeable</li>
<li class="codelist "> <span class="key">trait</span> Source {</li>
<li class="codelist alt"> <span class="key">def</span> in : I</li>
<li class="codelist "> <span class="key">def</span> next(in : I) : Option<span class="type-param">[A]</span></li>
<li class="codelist alt"> }</li>
<li class="codelist "> <span class="key">def</span> source : Source</li>
<li class="codelist alt"> </li>
<li class="codelist "> <span class="key">def</span> foreach<span class="type-param">[U]</span>(f : A => U) : <span class="singleton">Unit</span> = {</li>
<li class="codelist alt"> <span class="key">val</span> s = source.in</li>
<li class="codelist "> <span class="key">try</span> {</li>
<li class="codelist alt"> <span class="key">def</span> processNext : <span class="singleton">Unit</span> = source.next(s) <span class="key">match</span> {</li>
<li class="codelist "> <span class="key">case</span> None => </li>
<li class="codelist alt"> ()</li>
<li class="codelist "> <span class="key">case</span> Some(value) => </li>
<li class="codelist alt"> f(value)</li>
<li class="codelist "> processNext</li>
<li class="codelist alt"> }</li>
<li class="codelist "> </li>
<li class="codelist alt"> processNext</li>
<li class="codelist "> } <span class="key">finally</span> {</li>
<li class="codelist alt"> <span class="comment">// correctly handle exceptions</span></li>
<li class="codelist "> s.close</li>
<li class="codelist alt"> }</li>
<li class="codelist "> }</li>
<li class="codelist alt">}</li>
<li class="codelist "></li>
<li class="codelist alt"><span class="key">object</span> Test {</li>
<li class="codelist "> <span class="key">def</span> main(args : Array<span class="type-param">[String]</span>) = {</li>
<li class="codelist alt"> <span class="key">val</span> data = <span class="string">"Hello World"</span></li>
<li class="codelist "> <span class="key">val</span> bytes = data.toArray.map { _.toByte }</li>
<li class="codelist alt"> <span class="key">import</span> Foreach._</li>
<li class="codelist "> fromStream(<span class="key">new</span> ByteArrayInputStream(bytes)).foreach {a => print(a.toChar)}</li>
<li class="codelist alt"> </li>
<li class="codelist "> println</li>
<li class="codelist alt"></li>
<li class="codelist "> fromReader(<span class="key">new</span> StringReader(data)) foreach print</li>
<li class="codelist alt"> </li>
<li class="codelist "> println</li>
<li class="codelist alt"> </li>
<li class="codelist "> fromInputAndFunction(<span class="key">new</span> ByteArrayInputStream(bytes), i => i.toChar) foreach print</li>
<li class="codelist alt"> </li>
<li class="codelist "> println</li>
<li class="codelist alt"> }</li>
<li class="codelist ">}</li>
</ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com7tag:blogger.com,1999:blog-5089773352404981635.post-50814034431095800652010-04-29T00:44:00.001-07:002010-04-29T00:44:43.159-07:00Filter with FlatMap (or collect)I picked up this tip from one of Daniel Spiewak's tweets. He tweeted a pro tip that uses flatMap to create a filtered list: <br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt">list flatMap {</li><li class="codelist ">  <span class="key">case</span> st: <span class="basicType">String</span> => Some(st)</li><li class="codelist alt">  <span class="key">case</span> _ => None</li><li class="codelist ">}</li></ol></div></code><br />At a glance one might wonder why not simply use list.filter{_.isInstanceOf[String]}. The difference is that the flatMap will return a List[String].<br /><br />However Scala 2.8 offers the collect method for doing a similar thing.<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">def</span> strings(list: List<span class="type-param">[Any]</span>) = list flatMap {</li><li class="codelist ">  <span class="key">case</span> st: <span class="basicType">String</span> => Some(st)</li><li class="codelist alt">  <span class="key">case</span> _ => None</li><li class="codelist ">}</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// returned list is a List[String]</span></li><li class="codelist alt"><span class="repl">scala></span> strings(<span class="string">"hi"</span> :: 1 :: <span class="string">"world"</span> :: 4 :: <span class="singleton">Nil</span>)</li><li class="codelist ">res11: List<span class="type-param">[String]</span> = List(hi, world)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// returned list is a List[Any] (not as useful)</span></li><li class="codelist alt"><span class="repl">scala></span> <span class="string">"hi"</span> :: 1 :: <span class="string">"world"</span> :: 4 :: <span class="singleton">Nil</span> filter {_.isInstanceOf<span class="type-param">[String]</span>}</li><li class="codelist ">res12: List<span class="type-param">[Any]</span> = List(hi, world)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// collect returns List[String]</span></li><li class="codelist alt"><span class="repl">scala></span> <span class="string">"hi"</span> :: 1 :: <span class="string">"world"</span> :: 4 :: <span class="singleton">Nil</span> collect {<span class="key">case</span> s:<span class="basicType">String</span> => s}           </li><li class="codelist ">res13: List<span class="type-param">[String]</span> = List(hi, world)</li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com4tag:blogger.com,1999:blog-5089773352404981635.post-16373931189435730052010-04-27T23:38:00.001-07:002010-04-29T11:44:41.044-07:00Implicit Parameter ResolutionThis topic is a continuation of the previous implicit parameter topics:<br />
<ul><li><a href="http://daily-scala.blogspot.com/2010/04/implicit-parameters.html">Implicit Parameters</a></li><li><a href="http://daily-scala.blogspot.com/2010/04/companion-object-implicits.html">Companion Object Implicits</a></li></ul><br />
This topic provides some explanation about how implicit parameters are resulted. There are very strict rules for which implicit value is to be applied to a implicit parameter. A simple way to think about it is that the "closest" definition will be used. Local scope, enclosing class, parent class, companion object of the desired type.<br />
<code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">class</span> X(<span class="key">val</span> i:<span class="basicType">Int</span>)</li><li class="codelist "><span class="key">class</span> Y(<span class="key">val</span> i:<span class="basicType">Int</span>)</li><li class="codelist alt"></li><li class="codelist "><span class="key">object</span> X {</li><li class="codelist alt">  implicit <span class="key">def</span> xx = <span class="key">new</span> X(1)</li><li class="codelist ">}</li><li class="codelist alt"></li><li class="codelist "><span class="key">class</span> Method {</li><li class="codelist alt">  <span class="key">def</span> x(implicit x:X)=println(x.i)</li><li class="codelist ">  <span class="key">def</span> y(implicit y:Y)=println(y.i)</li><li class="codelist alt">}</li><li class="codelist "></li><li class="codelist alt"><span class="key">trait</span> M { </li><li class="codelist ">  <span class="key">self</span> : Method =></li><li class="codelist alt"></li><li class="codelist ">  implicit <span class="key">def</span> x1 = <span class="key">new</span> X(10)</li><li class="codelist alt">  implicit <span class="key">def</span> y1 = <span class="key">new</span> Y(100)</li><li class="codelist "></li><li class="codelist alt">  <span class="key">def</span> testy = y</li><li class="codelist ">  <span class="key">def</span> testx = x</li><li class="codelist alt">}</li><li class="codelist "><span class="key">trait</span> SM <span class="key">extends</span> M {</li><li class="codelist alt">  <span class="key">self</span> : Method =></li><li class="codelist "></li><li class="codelist alt">  implicit <span class="key">def</span> x2 = <span class="key">new</span> X(20)</li><li class="codelist ">  implicit <span class="key">def</span> y2 = <span class="key">new</span> Y(200)</li><li class="codelist alt">  </li><li class="codelist ">  <span class="key">def</span> testy2 = y  </li><li class="codelist alt">}</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// implicit resolved from companion object of X</span></li><li class="codelist "><span class="key">new</span> Method().x</li><li class="codelist alt"><span class="comment">// explicit applied so that value is used</span></li><li class="codelist "><span class="key">new</span> Method().x(<span class="key">new</span> X(3))</li><li class="codelist alt"><span class="comment">// implicit resolved from companion object of X</span></li><li class="codelist "><span class="comment">// NOT from M.  This is because the call site of x </span></li><li class="codelist alt"><span class="comment">// is not within M therefore does not use the implicits in M</span></li><li class="codelist "><span class="comment">// for resolution.</span></li><li class="codelist alt">(<span class="key">new</span> Method <span class="key">with</span> M).x</li><li class="codelist "></li><li class="codelist alt">implicit <span class="key">def</span> x = <span class="key">new</span> X(30)</li><li class="codelist "><span class="comment">// local scope overrides companion object implicit</span></li><li class="codelist alt"><span class="key">new</span> Method().x</li><li class="codelist "><span class="comment">// explicit applied so that value is used</span></li><li class="codelist alt"><span class="key">new</span> Method().x(<span class="key">new</span> X(3))</li><li class="codelist "><span class="comment">// local scope overrides companion object implicit</span></li><li class="codelist alt">(<span class="key">new</span> Method <span class="key">with</span> M).x</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// testy is defined within M so the implicits within M</span></li><li class="codelist ">(<span class="key">new</span> Method <span class="key">with</span> M).testy</li><li class="codelist alt"><span class="comment">// testx is defined within M so the implicit within M</span></li><li class="codelist "><span class="comment">// overrides the companion object implicit</span></li><li class="codelist alt">(<span class="key">new</span> Method <span class="key">with</span> M).testx</li><li class="codelist "><span class="comment">// testy is within M (not SM) so the implicit within M</span></li><li class="codelist alt"><span class="comment">// is used</span></li><li class="codelist ">(<span class="key">new</span> Method <span class="key">with</span> SM).testy</li><li class="codelist alt"><span class="comment">// testy2 is within SM so the implicit within SM </span></li><li class="codelist "><span class="comment">// overrides the implicit in M and the companion object</span></li><li class="codelist alt">(<span class="key">new</span> Method <span class="key">with</span> SM).testy2</li></ol></div></code><br />
Output:<br />
<bq><br />
1<br />
3<br />
1<br />
30<br />
3<br />
30<br />
100<br />
10<br />
100<br />
200<br />
<bq>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1tag:blogger.com,1999:blog-5089773352404981635.post-15984236744010891872010-04-26T00:08:00.000-07:002010-04-27T06:48:20.521-07:00Implicit ParametersEvidently the topic of implicit parameters has not yet been correctly addressed. There have been several topic that refer to implicit parameters but none that directly discuss them. So before I continue with the topic of implicit parameter resolution I will discuss implicit parameters.<br /><br />First, implicit parameters are not the same as implicit object conversions. Implicit parameters provide a way to allow parameters of a method to be "found". This is similar to default parameters at a glance but in fact is a different mechanism for finding the "default" value. It differs from implicit object conversion in that it is only a way for parameters for a method to be resolved. Implicit object conversion allows methods to appear to be called on one object when in fact that object is being converted behind the scenes to another type. (more or less)<br /><br />An implicit parameter is a parameter to method or constructor that is marked as implicit. This means that if a parameter value is not supplied then the compiler will search for an "implicit" value defined within scope (according to resolution rules.) Implicit parameter resolution rules will be discussed soon.<br /><br />Example:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> p(implicit i:<span class="basicType">Int</span>) = print(i)</li><li class="codelist ">p: (implicit i: <span class="basicType">Int</span>)<span class="singleton">Unit</span></li><li class="codelist alt"></li><li class="codelist "><span class="comment">// defining a val/var/def as implicit </span></li><li class="codelist alt"><span class="comment">// means that it will be considered during implicit resolution</span></li><li class="codelist "><span class="repl">scala></span> implicit <span class="key">val</span> v=2</li><li class="codelist alt">v: <span class="basicType">Int</span> = 2</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// scope is searched for a implicit value to sue</span></li><li class="codelist "><span class="comment">// v is found as marked implicit</span></li><li class="codelist alt"><span class="repl">scala></span> p               </li><li class="codelist ">2</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// explicit declarations always overrides implicit values</span></li><li class="codelist alt"><span class="repl">scala></span> p(1)</li><li class="codelist ">1</li></ol></div></code><br />Implicit parameters are very nice for simplifying APIs. For example the collections use implicit parameters to supply CanBuildFrom objects for many of the collection methods. This is because normally the user does not need to be concerned with those parameters. Another example is supplying an encoding to an IO library so the encoding is defined once (perhaps in a package object) and all methods can use the same encoding without having to define it for every method call.<br /><br />One important restriction is that there can only be a single implicit keyword per method. It must be at the start of a parameter list (which also makes all values of that parameter list be implicit). I further understand that only the last parameter list may be implicit.<br /><br />Here are several illegal examples:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="comment">// implicit is not in last parameter list</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(implicit i:<span class="basicType">Int</span>, a:<span class="basicType">Int</span>)(b:<span class="basicType">Int</span>) = println(a,i)                 </li><li class="codelist alt">< console>:1: error: <span class="char">'='</span> expected but <span class="char">'('</span> found.</li><li class="codelist ">       <span class="key">def</span> pp(implicit i:<span class="basicType">Int</span>, a:<span class="basicType">Int</span>)(b:<span class="basicType">Int</span>) = println(a,i)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// there are 2 implicit parameters</span></li><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> pp(implicit j:<span class="basicType">Int</span>, a:<span class="basicType">Int</span>)(implicit i:<span class="basicType">Int</span>,b:<span class="basicType">Int</span>) = println(a,i)</li><li class="codelist ">< console>:1: error: <span class="char">'='</span> expected but <span class="char">'('</span> found.</li><li class="codelist alt">      <span class="key">def</span> pp(implicit j:<span class="basicType">Int</span>, a:<span class="basicType">Int</span>)(implicit i:<span class="basicType">Int</span>,b:<span class="basicType">Int</span>) = println(a,i)</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// implicit is not the first parameter of the parameter list</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(a:<span class="basicType">Int</span>, implicit i:<span class="basicType">Int</span>) = println(i,j)         </li><li class="codelist alt">< console>:1: error: identifier expected but <span class="char">'implicit'</span> found.</li><li class="codelist ">       <span class="key">def</span> pp(a:<span class="basicType">Int</span>, implicit i:<span class="basicType">Int</span>) = println(i,j)</li><li class="codelist alt">                     ^</li></ol></div></code><br />Here are several legal examples (Updated with useage examples):<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> implicit <span class="key">def</span> v = 7</li><li class="codelist ">v: <span class="basicType">Int</span></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> implicit <span class="key">var</span> x = 10L</li><li class="codelist alt">x: <span class="basicType">Long</span></li><li class="codelist "></li><li class="codelist alt"><span class="comment">// i is implicit</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(a:<span class="basicType">Int</span>)(implicit i:<span class="basicType">Int</span>) = println(a,i)</li><li class="codelist alt">pp: (a: <span class="basicType">Int</span>)(implicit i: <span class="basicType">Int</span>)<span class="singleton">Unit</span></li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> pp(3)</li><li class="codelist ">(3,7)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// both i and b are implicit</span></li><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> pp(a:<span class="basicType">Int</span>)(implicit i:<span class="basicType">Int</span>, b:<span class="basicType">Long</span>) = println(a,i,b) </li><li class="codelist ">pp: (a: <span class="basicType">Int</span>)(implicit i: <span class="basicType">Int</span>,implicit b: <span class="basicType">Long</span>)<span class="singleton">Unit</span></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> pp(4)               </li><li class="codelist alt">(4,7,10)</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// both i and b are implicit</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(implicit i:<span class="basicType">Int</span>, b:<span class="basicType">Long</span>) = println(i,b)  </li><li class="codelist alt">pp: (implicit i: <span class="basicType">Int</span>,implicit b: <span class="basicType">Long</span>)<span class="singleton">Unit</span></li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> pp</li><li class="codelist ">(7,10)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// all or none of the parameters must be supplied</span></li><li class="codelist alt"><span class="repl">scala></span> pp(2)</li><li class="codelist ">< console>:13: error: not enough arguments <span class="key">for</span> method pp: (implicit i: <span class="basicType">Int</span>,implicit b: <span class="basicType">Long</span>)<span class="singleton">Unit</span>.</li><li class="codelist alt">Unspecified value parameter b.</li><li class="codelist ">       pp(2)</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// This is syntactically legal but I cannot seem to implicitly invoke this</span></li><li class="codelist alt"><span class="comment">// I would recommend: def pp(b:Long*)(implicit i:Int) = println(i,b)</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(implicit i:<span class="basicType">Int</span>, b:Long*) = println(i,b)</li><li class="codelist alt">pp: (implicit i: <span class="basicType">Int</span>,implicit b: Long*)<span class="singleton">Unit</span></li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> pp(3,1,2,3)</li><li class="codelist ">(3,WrappedArray(1, 2, 3))</li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> pp(b:Long*)(implicit i:<span class="basicType">Int</span>) = println(i,b)</li><li class="codelist alt">pp: (b: Long*)(implicit i: <span class="basicType">Int</span>)<span class="singleton">Unit</span></li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> pp(1,2,3)</li><li class="codelist ">(7,WrappedArray(1, 2, 3))</li></ol></div></code><br />A related topic is <a href="http://daily-scala.blogspot.com/2010/04/companion-object-implicits.html">Companion Object implicits</a>.Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com12tag:blogger.com,1999:blog-5089773352404981635.post-83129612934285686202010-04-23T00:32:00.000-07:002010-04-23T00:35:15.339-07:00Break PerformanceIn the <a href="http://daily-scala.blogspot.com/2010/04/breaks.html">Breaks</a> comments there were several questions about the performance of the Scala break command vs the Java break command. So I decided to take a look. <br /><br />The code for the tests is available on GitHub at: <a href="http://github.com/jesseeichar/Scala-Benchmarks">Scala Benchmarks</a>. Feel free to play around with it.<br /><br />I personally don't think these tests say anything of particular import because they only test how fast the Java break is vs the Scala break without doing any work in the loop. So I don't expect these number would ever been seen in the real world. However that said if you have a tight loop with minimal processing then a Scala break may not be the correct construct to use. <br /><br />Here is the Java test (labelled JavaSimpleBreak)<br /><code class="Java"><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="basicType">int</span> i = 0;</li><li class="codelist "><span class="key">while</span> (i < 10) {</li><li class="codelist alt">  <span class="key">if</span>(i==1) break;</li><li class="codelist ">  i += 1;</li><li class="codelist alt">}</li></ol></div></code><br />Here is the Scala test (labelled ScalaSimpleBreak)<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">var</span> i = 0;</li><li class="codelist ">breakable {</li><li class="codelist alt">  <span class="key">while</span> (i < 10) {</li><li class="codelist ">    <span class="key">if</span>(i==1) break;</li><li class="codelist alt">    i += 1;</li><li class="codelist ">  }</li><li class="codelist alt">}</li></ol></div></code><br />Out of curiosity I also added a test that created a new Exception each iteration (labelled ScalaException):<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">var</span> i = 0;</li><li class="codelist ">  <span class="key">while</span> (i < 10) {</li><li class="codelist alt">    <span class="key">if</span>(i==1) <span class="key">throw</span> <span class="key">new</span> Exception();</li><li class="codelist ">    i += 1;</li><li class="codelist alt">  }</li></ol></div></code><br />And also a test that just throws the same ScalaBreak exception each time. This one is weird since Scala Simple Break also throws the same exception but is much much faster so I think there is something about popping the stack in the example compared to the ScalaSimpleBreak test.<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">var</span> i = 0;</li><li class="codelist ">breakable {</li><li class="codelist alt"> <span class="key">while</span> (i < 10) {</li><li class="codelist "> <span class="key">if</span>(i==1) break;</li><li class="codelist alt"> i += 1;</li><li class="codelist "> }</li><li class="codelist alt">}</li></ol></div></code><br />The results of the tests:<br /><br />First, don't compare the break tests to the Exception tests. They are sufficiently different to not be worth comparing.<br />Second, remember that this is a micro benchmark and has very little relationship to reality.<br /><bq><br />90000000 iterations. Swapping every 90000000 tests<br />JavaSimpleBreak = 254 (0.0016279129387033098)<br />ScalaSimpleBreak = 2475 (0.015862537493270438)<br />ScalaBreakException = 18806 (0.12052964852462379)<br />ScalaException = 156028 (1.0)<br /><br />90000000 iterations. Swapping every 500000 tests<br />JavaSimpleBreak = 772 (0.005138547761203965)<br />ScalaSimpleBreak = 2351 (0.015648608531853004)<br />ScalaBreakException = 19346 (0.12876987692778744)<br />ScalaException = 150237 (1.0)<br /><br />90000000 iterations. Swapping every 500 tests<br />JavaSimpleBreak = 790 (0.005242446563543097)<br />ScalaSimpleBreak = 2247 (0.014911110668710557)<br />ScalaBreakException = 19213 (0.1274976276270298)<br />ScalaException = 150693 (1.0)<br /></bq>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com7tag:blogger.com,1999:blog-5089773352404981635.post-10378586802659450432010-04-21T23:46:00.000-07:002010-04-21T23:49:15.796-07:00Companion Object ImplicitsWhen a method requires an implicit there are several ways that the implicit is resolved. One way is to search for an implicit definition in the <em>companion object</em> of the <em>required</em> type. For example: <code><span class="key">def</span> x(implicit m:MyClass)</code> parameter m will search local scope, class hierarchy and the MyClass companion object for an implicit val or def. (More on implicit resolution later).<br /> <br />To demonstrate the method put the following code block into a file and run the script:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="key">class</span> X(<span class="key">val</span> i:<span class="basicType">Int</span>) {</li><li class="codelist ">  <span class="key">def</span> add(implicit x:X)=println(x.i+i)</li><li class="codelist alt">}</li><li class="codelist "></li><li class="codelist alt"><span class="key">object</span> X {</li><li class="codelist ">  implicit <span class="key">def</span> xx = <span class="key">new</span> X(3)</li><li class="codelist alt">}</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// implicit is obtained from companion object of X</span></li><li class="codelist "><span class="key">new</span> X(3).add</li><li class="codelist alt"></li><li class="codelist "><span class="key">val</span> other = <span class="key">new</span> {</li><li class="codelist alt">  <span class="key">def</span> print(implicit x:X)=println(x.i)</li><li class="codelist ">}</li><li class="codelist alt"></li><li class="codelist "><span class="comment">// implicit is obtained from companion object of X</span></li><li class="codelist alt">other.print</li><li class="codelist "></li><li class="codelist alt">implicit <span class="key">def</span> x = <span class="key">new</span> X(32)</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// implicit is obtained local scope</span></li><li class="codelist ">other.print</li></ol></div></code> <br />Running: scala impl.scala should produce:<br />6<br />3<br />32Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com3tag:blogger.com,1999:blog-5089773352404981635.post-46721279175359198752010-04-20T23:30:00.001-07:002010-04-20T23:30:36.564-07:00BreaksScala 2.8 added the <em>break</em> control flow option. It is not implemented as a special language feature. Rather it is simply implemented as an object/trait using standard Scala mechanisms. If you are interested in creating a control flow object similar to this look at the <a href="http://daily-scala.blogspot.com/2009/11/defining-custom-control-structures.html">Defining Custom Control Structures</a> post.<br /> <br />The Break functionality is works basically how you would expect:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="comment">// Import the control flow methodsmethods</span></li><li class="codelist "><span class="repl">scala></span> <span class="key">import</span> util.control.Breaks._</li><li class="codelist alt"><span class="key">import</span> util.control.Breaks._</li><li class="codelist "></li><li class="codelist alt"><span class="comment">// pass a function to the breakable method</span></li><li class="codelist "><span class="repl">scala></span> breakable {</li><li class="codelist alt">     | <span class="key">for</span> (i <- 1 to 10 ) {</li><li class="codelist ">     | <span class="key">if</span>(i > 5) break  <span class="comment">// call break when done</span></li><li class="codelist alt">     | println(i)</li><li class="codelist ">     | }</li><li class="codelist alt">     | }</li><li class="codelist ">1</li><li class="codelist alt">2</li><li class="codelist ">3</li><li class="codelist alt">4</li><li class="codelist ">5</li></ol></div></code> <br />Pretty intuitive but beware, break only breaks out to the first enclosing breakable. Here is an example of the issue:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> loop(f : <span class="basicType">Int</span> => <span class="basicType">Boolean</span>) = breakable {</li><li class="codelist ">     | <span class="key">for</span> (i <- 1 to 300) <span class="key">if</span> (f(i)) break <span class="key">else</span> println(i)</li><li class="codelist alt">     | }</li><li class="codelist ">loop: (f: (<span class="basicType">Int</span>) => <span class="basicType">Boolean</span>)<span class="singleton">Unit</span></li><li class="codelist alt"></li><li class="codelist "><span class="comment">// This never ends because break is caught by breakable in the loop method</span></li><li class="codelist alt"><span class="repl">scala></span> breakable {</li><li class="codelist ">     | <span class="key">while</span>(<span class="basicType">true</span>) {</li><li class="codelist alt">     | loop{ i => break; <span class="basicType">true</span> }</li><li class="codelist ">     | }</li><li class="codelist alt">     | }</li></ol></div></code> <br />Fortunately the implementers provide an elegant way to handle these sorts of cases. The Breaks object extends the Breaks class. By instantiating other instances of Breaks it is possible to control which breaks capture<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">import</span> scala.util.control._</li><li class="codelist "><span class="key">import</span> scala.util.control._</li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> </li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> loop(f : <span class="basicType">Int</span> => <span class="basicType">Boolean</span>) = {</li><li class="codelist alt">     |   <span class="key">val</span> Inner = <span class="key">new</span> Breaks</li><li class="codelist ">     |   Inner.breakable {</li><li class="codelist alt">     |     <span class="key">for</span> (i <- 1 to 4) <span class="key">if</span> (f(i)) Inner.break <span class="key">else</span> println(i)</li><li class="codelist ">     |   }</li><li class="codelist alt">     | }</li><li class="codelist ">loop: (f: (<span class="basicType">Int</span>) => <span class="basicType">Boolean</span>)<span class="singleton">Unit</span></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> </li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> <span class="key">val</span> Outer = <span class="key">new</span> Breaks</li><li class="codelist alt">Outer: scala.util.control.Breaks = scala.util.control.Breaks<span class="annotation">@</span>1ba4806</li><li class="codelist "></li><li class="codelist alt"><span class="repl">scala></span> Outer.breakable {</li><li class="codelist ">     |   <span class="key">while</span>(<span class="basicType">true</span>) {</li><li class="codelist alt">     |     loop{ i => <span class="key">if</span>(i==4) Outer.break; <span class="basicType">false</span>}</li><li class="codelist ">     |   }</li><li class="codelist alt">     | }</li><li class="codelist ">1</li><li class="codelist alt">2</li><li class="codelist ">3</li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com9tag:blogger.com,1999:blog-5089773352404981635.post-22470635786200638062010-04-19T04:23:00.000-07:002010-04-19T04:24:37.070-07:00Scala 2.8 Arrays are not TraversablesOne performance/consistency change that has been make in Scala 2.8 is to make Scala Array always be a Java Array. This has some consequences which we will examine in this post. The biggest one is that Array <em>is not</em> a Scala Collection/Traversable. It is implicitly converted to one but it is not an instance of a Traversable. There are several reasons this was done. Probably the biggest is for performance. Because a Scala array <em>is</em> a Java array there is no overhead when using a Scala array. <br /> <br />Thanks to implicit type conversion all the normal collection methods are useable with an array. Even better, after running a method like map the result will again be a Java array. So the API is much more consistent.<br /> <br />An example illustrating that an Array is not a Traversable:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="comment">// This does not compile (which is good) </span></li><li class="codelist "><span class="comment">// because Traversable[Int] can never be an array</span></li><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> x(t:Traversable<span class="type-param">[Int]</span>) = t <span class="key">match</span> {</li><li class="codelist ">     | <span class="key">case</span> x : Array<span class="type-param">[Int]</span> => <span class="basicType">true</span>          </li><li class="codelist alt">     | }</li><li class="codelist ">< console>:13: error: pattern <span class="key">type</span> is incompatible <span class="key">with</span> expected <span class="key">type</span>;</li><li class="codelist alt"> found   : Array<span class="type-param">[Int]</span></li><li class="codelist "> required: Traversable<span class="type-param">[Int]</span></li><li class="codelist alt">       <span class="key">case</span> x : Array<span class="type-param">[Int]</span> => <span class="basicType">true</span></li><li class="codelist ">                ^</li><li class="codelist alt">< console>:13: error: <span class="key">type</span> mismatch;</li><li class="codelist "> found   : Array<span class="type-param">[Int]</span></li><li class="codelist alt"> required: Traversable<span class="type-param">[Int]</span></li><li class="codelist ">       <span class="key">case</span> x : Array<span class="type-param">[Int]</span> => <span class="basicType">true</span></li><li class="codelist alt">              ^</li></ol></div></code> <br />Another example:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> x(t:Traversable<span class="type-param">[Int]</span>) = t.isInstanceOf<span class="type-param">[Array</span><span class="type-param">[_]</span>]</li><li class="codelist ">x: (t: Traversable<span class="type-param">[Int]</span>)<span class="basicType">Boolean</span></li><li class="codelist alt"></li><li class="codelist "><span class="comment">/* this evaluates to false because Array is converted</span></li><li class="codelist alt"><span class="comment"> * to WrappedArray because it has to be implicitly converted</span></li><li class="codelist "><span class="comment"> * to a Traversable.  Since Array is not a Traversable the resulting </span></li><li class="codelist alt"><span class="comment"> * object is not an Array</span></li><li class="codelist "><span class="comment"> */</span></li><li class="codelist alt"><span class="repl">scala></span> x(Array(1,2,3))                                     </li><li class="codelist ">res24: <span class="basicType">Boolean</span> = <span class="basicType">false</span></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> <span class="key">def</span> x(t:Traversable<span class="type-param">[Int]</span>) = println(t)</li><li class="codelist alt">x: (t: Traversable<span class="type-param">[Int]</span>)<span class="singleton">Unit</span></li><li class="codelist "></li><li class="codelist alt"><span class="comment">// This method call demonstrates the previous assertion</span></li><li class="codelist "><span class="repl">scala></span> x(Array(1,2,3))                                            </li><li class="codelist alt">WrappedArray(1, 2, 3)</li></ol></div></code> <br />So suppose you want to be able to accept and use arrays and Traversables in a method but you want to be able to <br />check that the parameter is an Array. Why not match against WrappedArray. You probably can, but you may get performance improvements in some cases if you don't require wrapping the array. <br /> <br />For a more concrete example of why you may want to do this. In a Input/Output routine I wrote I would write the data one way if the input was an Array: <code>stream.write(array)</code>. But if the input was a traversable then I would have to handle it differently. My particular issue was more complicated than that but that is the basic issue.<br /> <br />So the work around is to define a Generic parameter for the method:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">def</span> x<span class="type-param">[T <% Traversable</span><span class="type-param">[Int]</span>](t:T) = t <span class="key">match</span> { </li><li class="codelist ">     | <span class="key">case</span> x : Array<span class="type-param">[Int]</span> => <span class="basicType">true</span>                                </li><li class="codelist alt">     | }</li><li class="codelist ">x: <span class="type-param">[T]</span>(t: T)(implicit evidence$1: (T) => Traversable<span class="type-param">[Int]</span>)<span class="basicType">Boolean</span></li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> x(Array(1,2,3))                               </li><li class="codelist alt">res27: <span class="basicType">Boolean</span> = <span class="basicType">true</span></li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com0tag:blogger.com,1999:blog-5089773352404981635.post-47688771198923086992010-04-16T01:56:00.000-07:002010-04-16T01:58:06.724-07:00A quick note. ScalaDays Rocks! Wish you were here :)<br /><br />This topic just demonstrates a cute little trick that can occasionally be quite useful:<br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> List(1,2,3) ++ Some(4)</li><li class="codelist ">res0: List<span class="type-param">[Int]</span> = List(1, 2, 3, 4)</li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> List(1,2,3) ++ None   </li><li class="codelist alt">res1: List<span class="type-param">[Int]</span> = List(1, 2, 3)</li></ol></div></code> <br />Options are implicitly converted to Iterables, so Options can be appended to collections. <br /><code><div class="codelist"><ol class="codelist"><li class="codelist alt"><span class="repl">scala></span> <span class="key">val</span> x : Iterable<span class="type-param">[Int]</span> = None       </li><li class="codelist ">x: Iterable<span class="type-param">[Int]</span> = List()</li><li class="codelist alt"></li><li class="codelist "><span class="repl">scala></span> <span class="key">val</span> x : Iterable<span class="type-param">[Int]</span> = Some(4)</li><li class="codelist alt">x: Iterable<span class="type-param">[Int]</span> = List(4)</li></ol></div></code>Anonymoushttp://www.blogger.com/profile/07600430363435495915noreply@blogger.com1