Showing posts with label control structure. Show all posts
Showing posts with label control structure. Show all posts
Tuesday, April 20, 2010
Breaks
Scala 2.8 added the break 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 Defining Custom Control Structures post.
The Break functionality is works basically how you would expect:
Pretty intuitive but beware, break only breaks out to the first enclosing breakable. Here is an example of the issue:
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
The Break functionality is works basically how you would expect:
- // Import the control flow methodsmethods
- scala> import util.control.Breaks._
- import util.control.Breaks._
- // pass a function to the breakable method
- scala> breakable {
- | for (i <- 1 to 10 ) {
- | if(i > 5) break // call break when done
- | println(i)
- | }
- | }
- 1
- 2
- 3
- 4
- 5
Pretty intuitive but beware, break only breaks out to the first enclosing breakable. Here is an example of the issue:
- scala> def loop(f : Int => Boolean) = breakable {
- | for (i <- 1 to 300) if (f(i)) break else println(i)
- | }
- loop: (f: (Int) => Boolean)Unit
- // This never ends because break is caught by breakable in the loop method
- scala> breakable {
- | while(true) {
- | loop{ i => break; true }
- | }
- | }
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
- scala> import scala.util.control._
- import scala.util.control._
- scala>
- scala> def loop(f : Int => Boolean) = {
- | val Inner = new Breaks
- | Inner.breakable {
- | for (i <- 1 to 4) if (f(i)) Inner.break else println(i)
- | }
- | }
- loop: (f: (Int) => Boolean)Unit
- scala>
- scala> val Outer = new Breaks
- Outer: scala.util.control.Breaks = scala.util.control.Breaks@1ba4806
- scala> Outer.breakable {
- | while(true) {
- | loop{ i => if(i==4) Outer.break; false}
- | }
- | }
- 1
- 2
- 3
Labels:
2.8,
break,
control structure,
intermediate,
Scala
Friday, February 5, 2010
Introducing Structural Types
Structural types allows one to declare types based on the methods the type has. For example you could define a method that takes a class containing a close method. This is fairy analogous to duck-typing in dynamic languages. Except that it is statically enforced.
The main example used here was from a comment on the Code Monkeyism Blog. The commenter further explains that this example is in fact from Beginning Scala chapter 4 (which I would like to read but have not yet had the time.)
That is extremely powerful and the consequences will be visited more in the future. But because structural typing is statically enforced it is not quite as flexible as dynamic language's version of duck typing. For example you cannot do:
An alternative to the first using example is to use call by name to construct the closeable. The reason one might want to do that is because it allows currying of the method:
The main example used here was from a comment on the Code Monkeyism Blog. The commenter further explains that this example is in fact from Beginning Scala chapter 4 (which I would like to read but have not yet had the time.)
- /*
- A can be any object that has a close method.
- This is statically typed which makes some restrictions which are explained later
- */
- scala> def using[A <: {def close(): Unit}, B](param: A)(f: A => B): B =
- | try {
- | f(param)
- | } finally {
- | try {
- | param.close()
- | } catch { case _ => () }
- | }
- using: [A <: AnyRef{def close(): Unit},B](param: => A)(f: (A) => B)B
- scala> using(new java.io.ByteArrayInputStream("hello world".getBytes)){ in =>
- | io.Source.fromInputStream(in) foreach (print)
- | }
- hello world
- scala> using(new java.io.ByteArrayInputStream("hello world".getBytes)){ in =>
- | io.Source.fromInputStream(in) mkString ""
- | }
- res8: String = hello world
That is extremely powerful and the consequences will be visited more in the future. But because structural typing is statically enforced it is not quite as flexible as dynamic language's version of duck typing. For example you cannot do:
- scala> val i:Any = new java.io.ByteArrayInputStream("hello world".getBytes)
- i: Any = java.io.ByteArrayInputStream@145a25f3
- /*
- This does not work because 'i' is defined as type Any. Not a type that is closeable.
- Casting can be used to get around this issue. I will address that in its own post
- */
- scala> using(i){ in =>
- | io.Source.fromInputStream(in) mkString ""
- | }
- < console>:8: error: inferred type arguments [Any,B] do not conform to method using's type parameter bounds [A <: AnyRef{def close(): Unit},B]
- using(i){ in =>
An alternative to the first using example is to use call by name to construct the closeable. The reason one might want to do that is because it allows currying of the method:
- scala> def using[A <: {def close(): Unit}, B](param: =>A)(f: A => B): B =
- | val closeable = param // notice param is only referenced once
- | try {
- | f(closeable)
- | } finally {
- | try {
- | closeable.close()
- | } catch { case _ => () }
- | }
- using: [A <: AnyRef{def close(): Unit},B](param: => A)(f: (A) => B)B
- /*
- if this was accessing a database a new connection would be made automatically each time this function was used
- */
- scala> val usingTheWorld = using[BStream,Int](new java.io.ByteArrayInputStream("hello world".getBytes))_
- usingTheWorld: ((java.io.ByteArrayInputStream) => Int) => Int = < function1>
- scala> usingTheWorld { s => io.Source.fromInputStream(s).length}
- res3: Int = 11
- scala> usingTheWorld { s => io.Source.fromInputStream(s).getLines().length}
- res5: Int = 0
Labels:
control structure,
intermediate,
Scala,
structural types
Wednesday, January 13, 2010
Comparing Manifests
Manifests are Scala's solution to Java's type erasure. It is not a complete solution as of yet but it does have several useful applications. Manifests were originally added to Scala 2.7 in an extremely limited form but have been improved a great deal for Scala 2.8. Now more powerful comparisons of manifests are possible. For another introduction to Manifests (2.7 manifests) see Manifests.
This post looks at a few ways to create manifests as well as how to compare manifests. The goal is to create a method that can be used in testing to require that a certain exception is thrown during a code block:
The code snippet above is a failure because println does not throw an exception. In addition to requiring manifests this code snippet also is a custom control structure, for more information on those see Control Structure Tag
But before writing the intercepts methods a short inspection of the new manifest comparison operators:
Now the implementation of intercepts:
This post looks at a few ways to create manifests as well as how to compare manifests. The goal is to create a method that can be used in testing to require that a certain exception is thrown during a code block:
- scala> intercepts[Exception] {println("hi :)")}
- hi :)
- Expected java.lang.Exception but instead no exception was raised
The code snippet above is a failure because println does not throw an exception. In addition to requiring manifests this code snippet also is a custom control structure, for more information on those see Control Structure Tag
But before writing the intercepts methods a short inspection of the new manifest comparison operators:
- scala> import scala.reflect.{
- | Manifest, ClassManifest
- | }
- import scala.reflect.{Manifest, ClassManifest}
- // from class creates a manifest object given a class object
- scala> import ClassManifest.fromClass
- import ClassManifest.fromClass
- // several comparisons using <:<
- scala> fromClass(classOf[Exception]) <:< fromClass(classOf[Exception])
- res4: Boolean = true
- scala> fromClass(classOf[Exception]) <:< fromClass(classOf[RuntimeException])
- res5: Boolean = false
- scala> fromClass(classOf[Exception]) <:< fromClass(classOf[AssertionError])
- res6: Boolean = false
- // now the opposite operator >:>
- scala> fromClass(classOf[Exception]) >:> fromClass(classOf[AssertionError])
- res7: Boolean = false
- scala> fromClass(classOf[Exception]) >:> fromClass(classOf[RuntimeException])
- res8: Boolean = true
- scala> fromClass(classOf[Exception]) >:> fromClass(classOf[Error])
- res9: Boolean = false
- scala> fromClass(classOf[Exception]) >:> fromClass(classOf[Throwable])
- res10: Boolean = false
- // the method singleType creates a manifest given an object
- scala> ClassManifest.singleType(new RuntimeException())
- res12: scala.reflect.Manifest[Nothing] = java.lang.RuntimeException.type
- scala> ClassManifest.singleType(new RuntimeException()) <:< fromClass(classOf[Throwable])
- res13: Boolean = true
- scala> fromClass(classOf[Exception]) <:< fromClass(classOf[Throwable])
- res14: Boolean = true
Now the implementation of intercepts:
- scala> import scala.reflect.{
- | Manifest, ClassManifest
- | }
- import scala.reflect.{Manifest, ClassManifest}
- scala>
- scala> import ClassManifest.singleType
- import ClassManifest.singleType
- scala> def intercepts[E <: Throwable](test : => Unit)(implicit m:Manifest[E]) : Unit = {
- | import Predef.{println => fail}
- | try {
- | test
- | // this is a failure because test is expected to throw an exception
- | fail("Expected "+m.toString+" but instead no exception was raised")
- | }catch{
- | // this checks that the expected type (m) is a superclass of the class of e
- | case e if (m >:> singleType(e)) => ()
- | // any other error is handled here
- | case e => fail("Expected "+m.toString+" but instead got "+e.getClass)
- | }
- | }
- intercepts: [E <: Throwable](test: => Unit)(implicit m: scala.reflect.Manifest[E])Unit
- scala> intercepts[Exception] {println("hi :)")}
- hi :)
- Expected java.lang.Exception but instead no exception was raised
- scala> intercepts[Exception] { throw new IllegalArgumentException("why not throw this :)")}
- scala> intercepts[Exception] { throw new AssertionError("The method should complain")}
- Expected java.lang.Exception but instead got class java.lang.AssertionError
Labels:
Advanced,
control structure,
manifest,
Scala
Wednesday, December 16, 2009
By-name-parameter to Function
Today's topic is related to Defining Custom Control Structures. By name parameters are not function objects in the same way as other functions. Normally you need to invoke a function:
Compare that to a by-name-parameter function:
So the issue is how can you pass a by-name-parameter to a method that takes a function as a parameter without having to do:
the alternative syntax is:
- scala> def exec(func: () => Int) = func()
- exec: (() => Int)Int
- // exec invokes the function so 10 is the result
- scala> exec (() => 10)
- res1: Int = 10
- scala> def exec(func: () => Int) = func
- exec: (() => Int)() => Int
- // here exec returns the function:
- scala> exec (() => 10)
- res2: () => Int = <function>
Compare that to a by-name-parameter function:
- scala> def exec(func: => Int) = func
- exec: (=> Int)Int
- // by-name-parameters are executed when they are referenced
- // so the result is 10
- scala> exec {10}
- res3: Int = 10
- // This is not legal because by-name-parameters
- // are not normal functions
- scala> def exec(func: => Int) = func()
- <console>:4: error: func of type Int does not take parameters
- def exec(func: => Int) = func()
So the issue is how can you pass a by-name-parameter to a method that takes a function as a parameter without having to do:
- scala> def takesFunc(func: () => Int) = println(func())
- takesFunc: (() => Int)Unit
- scala> def send(x: => Int) = takesFunc(() => x)
- send: (=> Int)Unit
- scala> send{2}
- 2
the alternative syntax is:
- scala> def send(x: => Int) = takesFunc (x _)
- send: (=> Int)Unit
- scala> send {2}
- 2
Labels:
by-name-parameter,
control structure,
function,
Scala
Friday, November 27, 2009
Defining Custom Control Structures
Scala has only a handful of built-in control structures: for, while, try-catch, if, etc... However it is quite simple to define custom control structures. There are several good examples in the Scala 2.8 library. For some examples look at the classes in the scala.util.control package.
For this topic, we will develop a simplified version of the Exception class. First a demonstration of the 2.8 version.
A question that often arises when presented with the Exception control flow is why not use try-catch. There are two main reasons in my opinion.
First, people coming from certain functional style languages find that form more comfortable (so I have heard.) So in this case it is a style issue.
The other reason (and the one more pertinent to Java developers), is that it provides a nice way to handle common exceptions. Why do I say nice? First it declares when exceptions are handled before the code and that provides more context while reading the code. In addition, if you create the Catch object and assign it to a nicely named variable then it is clear what the intent is. For example there may be several reasons to catch a runtime exception and they should be handled differently. A few well-named variables can really assist in readability. A final point is that several of these variables can be defined in on object and shared throughout a project adding some consistency to a project.
Back to the topic at hand.
We will develop a simplified version: a catching method that will return Some(...) if no exception occurs or None if one of the declared exceptions has occurred or throw exception if the exception is not one we declare as handling. Now this is not what I would necessarily call a custom control flow because it does not offer a choice of execution flows. To do that I would add more components like int the Exceptions object. However, this is a good demonstration of the parts required to create a custom control struction. The key is the => in
Now for the complete catching example:
For this topic, we will develop a simplified version of the Exception class. First a demonstration of the 2.8 version.
- scala> import scala.util.control.Exception._
- import scala.util.control.Exception._
- scala> val numberFormat = catching(classOf[NumberFormatException])
- numberFormat: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)
- scala> val result = numberFormat opt { "10".toInt }
- result: Option[Int] = Some(10)
- scala> result match {
- | case Some(n) => // do something
- | case None => // handle this situation
- |
A question that often arises when presented with the Exception control flow is why not use try-catch. There are two main reasons in my opinion.
First, people coming from certain functional style languages find that form more comfortable (so I have heard.) So in this case it is a style issue.
The other reason (and the one more pertinent to Java developers), is that it provides a nice way to handle common exceptions. Why do I say nice? First it declares when exceptions are handled before the code and that provides more context while reading the code. In addition, if you create the Catch object and assign it to a nicely named variable then it is clear what the intent is. For example there may be several reasons to catch a runtime exception and they should be handled differently. A few well-named variables can really assist in readability. A final point is that several of these variables can be defined in on object and shared throughout a project adding some consistency to a project.
Back to the topic at hand.
We will develop a simplified version: a catching method that will return Some(...) if no exception occurs or None if one of the declared exceptions has occurred or throw exception if the exception is not one we declare as handling. Now this is not what I would necessarily call a custom control flow because it does not offer a choice of execution flows. To do that I would add more components like int the Exceptions object. However, this is a good demonstration of the parts required to create a custom control struction. The key is the => in
def method(arg: => T)
This is a special type construct which means that a no param function is passed in but is not executed until called within the method. A few comparisons:- scala> def method(arg: =>Int) = println(arg)
- method: (arg: => Int)Unit
- scala> def method2(arg: =>Int) = println("not calling arg")
- method2: (arg: => Int)Unit
- scala> var x = 1
- x: Int = 1
- // when method is called x is incremented because method calls the argument
- scala> method { x += 1; x }
- 2
- scala> println(x)
- 2
- // when method2 is called x is not incremented because
- // the argument is not called/referenced
- scala> method2 { x += 1; x }
- not calling arg
- scala> println(x)
- 2
- // arg is referenced 2 times in method three so x is incremented 2 times
- scala> def method3(arg: => Int) = println("first call="+arg+" second call="+arg)
- method3: (arg: => Int)Unit
- scala> method3 { x += 1; x }
- first call=3 second call=4
- // Now demonstrate the standard way of defining arguments
- // the value passed is calculated before calling the method
- // so is at most called once
- scala> def byValue(arg: Int) = println(arg)
- byValue: (arg: Int)Unit
- scala> def byValue2(arg: Int) = println("not calling arg")
- byValue2: (arg: Int)Unit
- scala> def byValue3(arg: Int) = println("first call="+arg+" second call="+arg)
- byValue3: (arg: Int)Unit
- scala> byValue{ x += 1; x }
- 5
- scala> byValue2{ x += 1; x }
- not calling arg
- scala> println(x)
- 6
- scala> byValue3{ x += 1; x }
- first call=7 second call=7
- // And finally show the normal way to pass in a function.
- // This has the benefit of allowing the reader of the code to
- // realize that the argument is a function
- // but is not a nice syntax for control flow
- scala> def stdFunc(arg: ()=>Int) = println(arg())
- stdFunc: (arg: () => Int)Unit
- scala> def stdFunc2(arg: ()=>Int) = println("not calling arg")
- stdFunc2: (arg: () => Int)Unit
- scdef stdFunc3(arg: ()=>Int) = println("first call="+arg()+" second call="+arg())
- stdFunc3: (arg: () => Int)Unit
- scala> stdFunc {() => x += 1; x }
- 8
- scala> stdFunc2 {() => x += 1; x }
- not calling arg
- scala> println(x)
- 8
- scala> stdFunc3 {() => x += 1; x }
- first call=9 second call=10
Now for the complete catching example:
- scala> def catching[T](exceptions: Class[_]*)(body: => T) = {
- | try {
- | Some (body)
- | } catch {
- | case e if (exceptions contains e.getClass) => None
- | }
- | }
- catching: [T](exceptions: Class[_]*)(body: => T)Option[T]
- scala> val runtime = catching[Number](classOf[NullPointerException], classOf[NumberFormatException])_
- runtime: (=> java.lang.Number) => Option[java.lang.Number] = < function1>
- scala> runtime { "".toInt }
- res2: Option[java.lang.Number] = None
- scala> runtime { "10".toInt }
- res3: Option[java.lang.Number] = Some(10)
- scala> runtime { throw new NullPointerException }
- res6: Option[java.lang.Number] = None
- scala> runtime { throw new RuntimeException }
- java.lang.RuntimeException
- at $anonfun1ドル.apply(< console>:10)
- at $anonfun1ドル.apply(< console>:10)
- at .catching(< console>:9)
- at $anonfun1ドル.apply(< console>:8)
- at $anonfun1ドル.apply(< console>:8)
- at .< init>(< console>:10)
- at .< clinit>(< console>)
- at RequestResult$.< init>(< console>:4)
- at RequestResult$.< clinit>(< console>)
- at RequestResult$result(< console>)
- ...
Labels:
control structure,
function,
intermediate,
Scala
Monday, August 31, 2009
Java vs Scala Control Structures
This topic is mainly for completeness. We will quickly cover the standard control structures you find in Java and see how they are the same or different in Scala.
The first thing to note is that in Scala 2.7 there is no break keyword. In Scala 2.8 there is a break control structure but it is slightly different than the Java break keyword. We will encounter that topic in a later lesson. The control structures I will quickly cover are: do-while, while, for and if.
For information about the Java case statement take a look at the several matching topics covered now and in the future.
Note: The Java ternary if statement does not exist in Scala instead the standard if statement is to be used. It is slightly more verbose but returns a value in the same way as a ternary if statement.
The first thing to note is that in Scala 2.7 there is no break keyword. In Scala 2.8 there is a break control structure but it is slightly different than the Java break keyword. We will encounter that topic in a later lesson. The control structures I will quickly cover are: do-while, while, for and if.
For information about the Java case statement take a look at the several matching topics covered now and in the future.
Note: The Java ternary if statement does not exist in Scala instead the standard if statement is to be used. It is slightly more verbose but returns a value in the same way as a ternary if statement.
- scala> var i = 0;
- i: Int = 0
- scala> while( i<3 ){
- | println( i )
- | i += 1
- | }
- 0
- 1
- 2
- scala> i = 0
- i: Int = 0
- scala> do {
- | println( i )
- | i += 1
- | } while (i<3)
- 0
- 1
- 2
- scala> for(j <- 0 until 3) println (j)
- 0
- 1
- 2
- scala> if (i<3)
- more
- scala> val result = if (i<3)
- result: Int = 10
- scala> println (result)
- 10
- scala> if (i>10) println(1)
- scala> if (i<10)
- 1
- // Note that the return value is (). You can only get a meaningful return value if there is an else-clause.
- scala> val r = if (i<10)>
- r: Unit = ()
- scala> println(r)
- ()
Monday, August 17, 2009
Return values
As with most functional languages, most control structures ( if, for, try ) return values. The common java idiom:
can be replaced by
The benefit (other than less boiler plate code) is that name can now be a val instead of a var.
Another other point about returns: The return keyword is not required when returning a value from methods or control structures. The last value is always the return value. This is why you will get an error if the last line in a method or control structure is an assignment.
Examples:
- String name=null;
- if( xxx ) name="yyy";
- else name="zzz";
can be replaced by
- val name = if( xxx ) "yyy"; else "zzz";
The benefit (other than less boiler plate code) is that name can now be a val instead of a var.
Another other point about returns: The return keyword is not required when returning a value from methods or control structures. The last value is always the return value. This is why you will get an error if the last line in a method or control structure is an assignment.
Examples:
- scala> val name = if( 1==2 ) "Jesse" else "Mauricio"
- name: java.lang.String = Mauricio
- scala> println(name)
- Mauricio
- scala> val collection = for( i <- 1 to 100; if(i%20 == 3) ) yield i
- collection: Seq.Projection[Int] = RangeFM(3, 23, 43, 63, 83)
- scala> collection.foreach( i => print( i +" ") )
- 3 23 43 63 83
- scala> val someObj:AnyRef = "Hello"
- someObj: AnyRef = Hello
- scala> val choice = someObj match {
- | case _:java.io.File => "File"
- | case _:String => "String"
- | case _ => "Dunno"
- | }
- choice: java.lang.String = String
- scala> val result = try {
- | "two".toInt
- | }catch{
- | case e:NumberFormatException => -1
- | case _ => 0
- | }
- result: Int = -1
- scala> var i=0
- i: Int = 0
- // while and do-while do not have return values
- scala> while( i<4 ){
- | "22"
- | i += 2
- | }
- scala> println( if(i>0) "great" else "less" )
- great
- // code blocks return the last statement
- scala> val m = {
- | val x = 1
- | x + 2
- | }
- m: Int = 3
Subscribe to:
Posts (Atom)