• News
  • About us
  • Our Work
  • Blog
  • Join Us
  • Contact

7 July 2015 / Krzysztof Romanowski

Tool-friendly Scala code. What? Why?

pattern-matching, scala, tool-friendly



People complain a lot about Scala tooling. People complain a lot about weather. But is Scala tooling like weather? Something you can’t do anything about except from moving to different climate (language)? Luckily no.

Scala tooling was created for Java (especially metadata handling that is vital for tools) and usually has only the JVM stack to work with. Tool-friendly code for me is Scala code that make tools’ lives easier.

I’m not trying to convince anyone to write java-like code. I just want to to point out some small details that can make your code much more tool-friendly. In forthcoming blog posts I will show a few codestyle ideas that will make your code easier to debug, profile and – surprisingly – understand. Let’s start with pattern matching.

Tool-friendly pattern matching

Pattern matching is one of the features we love in Scala. Is it tool-friendly?

Let’s look at a standard pattern match snippet:

Scala
1
2
3
4
5
6
foo match {
  case bar @ Bar if bar.isOk() => bar.doIt()
  case baz @ Bar(foo) if foo.isOk() => baz.doIt()
  case _ => ???
}
 

Let’s see how the first case statement is compiled into byte code:

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
      18: instanceof    #15                 // class test/Bar
      21: ifeq          51
      24: iconst_1      
      25: istore_3      
      26: aload         5
      28: checkcast     #15                 // class test/Bar
      31: astore        4
      33: aload         4
      35: invokevirtual #20                 // Method test/Bar.isOk:()Z
      38: ifeq          51
      41: aload         4
      43: invokevirtual #23                 // Method test/Bar.doIt:()Ljava/lang/String;
      46: astore        6
      48: goto          70
      51: iload_3      
      52: ifeq          176
      55: aload         4
      57: invokevirtual #20                 // Method test/Bar.isOk:()Z
      60: ifeq          176
      63: aload         4
      65: invokevirtual #23                 // Method test/Bar.doIt:()Ljava/lang/String;
      68: astore        6
      70: aload         6
      72: astore_2      
      73: aload_1      
      74: astore        8
      76: aload         8
      78: instanceof    #15                 // class test/Bar
      81: ifeq          109
      84: aload         8
      86: checkcast     #15                 // class test/Bar
      89: astore        9
      91: aload         9
      93: invokevirtual #20                 // Method test/Bar.isOk:()Z
      96: ifeq          109
      99: aload         9
     101: invokevirtual #23                 // Method test/Bar.doIt:()Ljava/lang/String;
     104: astore        10
     106: goto          139
     109: aload         8
 

There is a lot going on in the single line. Let’s assume that we want to check if our case is hit and we put a breakpoint on the case line. What happens? It is hit every time the condition is being checked!

Why? Checking a condition is also in our line, so tooling gets the information: “I was there”.

How would tools like to see the code?

Scala
1
2
3
4
5
6
7
8
9
10
11
12
foo match {
  case bar @ Bar
    if bar.isOk() =>
      bar.doIt()
 
  case baz @ Bar(foo)
    if foo.isOk() =>
      baz.doIt()
 
  case _ => ???
}
 

The only difference is line breaking, but this isn’t python so why does it matter? Tools like code coverage or debuggers usually use JDI, which is line-based: every line of the bytecode has its mapping to a line in the source code.

Conclusion

Let’s write cases this way:

Scala
1
2
3
4
5
6
7
8
foo match {
  case bar: Bar if bar.isOk() =>
    bar.doIt()
  case baz @ Bar(foo) if foo.isOk() =>
    baz.doIt()
  case _ => ???
}  
 

Then, when we place breakpoint inside a case body, it will be hit only when the body is about to be invoked.

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedIn


Select Partner

Training Division

About us


  • Our Team
  • Technologies
  • Open Source
  • IT Events
  • Company Atmosphere
  • Beyond IT
  • Ogłoszenie Planu Połączenia VIRTUS LAB spółka z ograniczoną odpowiedzialnością z siedzibą w Rzeszowie oraz Nexelem spółka z ograniczoną odpowiedzialnością z siedzibą w Krakowie

Our Work


  • Scala Experts
  • Data Science & Engineering
  • Lean Software Solutions
  • Idea Lab

Contact


Headquarters
Smoleńsk 21/15 Street
Kraków, Poland

Contact
info@virtuslab.com
phone: +48 608 366 649

© 2013 Virtus Lab Sp. z o.o. All trademarks © their respective owners.
This site uses cookies More info