Top Banner
81

Scala in practice

Apr 13, 2017

Download

Software

patforna
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 2: Scala in practice
Page 3: Scala in practice

!"#$%"&'()'$"#'*© ThoughtWorks, Inc 2010

!"#$%"&'#()*+,#-*$.&/-%+"0.1*+#(%2-/*2&/#-*+$-30(*&2-3+2-3+1.2-+"#4+&#+$*0+&"0+.2&0*&+/--#52&/#-*+/-+6!+2-3+*#7&42(0+&08"-#.#%9+&#+3/770(0-&/2&0+1(#3$8&*:+*&02.+;2()0&+*"2(0:+3(2;2&/82..9+8$&+&"0+&/;0+2-3+0<10-*0+#7+8(02&/-%+*#7&42(0+1(#3$8&*:+#(+2..=#7=&"0=2>#50+2-3+;#(0?+

@#(0+&"2-+)001/-%+$1

Optimising ITOrganisations

technology

Consulting

Testing

Build & ReleaseManagement

Experience Design

Our consulting engagements, like our delivery projects, are collaborative and fast. The focus is on creating a shared understanding, solving problems and making practical improvements, not just leaving you with slideware and reports. Each and every one of our consultants is active in delivery projects, not purely focused on advisory work. We are well known and respected in academia, but our thinking is firmly grounded in reality. We’re business savvy – and know that quick wins are just as important as long-term goals.

Be warned. We aren’t going to concentrate on an easy way out – our consultants will always give you the honest, full picture – even if it means pointing out something large and difficult. The root cause is important if we are actually going to fix anything, so we won’t shy away from it. But once we are agreed on the causes, the road map we create for improvement will deliver measurable value at regular, well-paced, milestones. No matter what the problem or objective, we don’t believe in plans with all results skewed to the end. And neither should you.

Page 4: Scala in practice

Offices

2

Page 5: Scala in practice

presentation Containscode examples

Warning

Page 6: Scala in practice

ContextA bit of

about the project

Page 7: Scala in practice
Page 8: Scala in practice
Page 9: Scala in practice
Page 10: Scala in practice

?Why Scala

Page 11: Scala in practice
Page 12: Scala in practice

What is Scala

?

Page 13: Scala in practice

Scala

FunctionalObjectOriented

StaticallyTyped

Scriptable

JVM-based

Page 14: Scala in practice

JVMByte CodeCompileScala

Page 15: Scala in practice

Benefits

Page 16: Scala in practice

“Functional

Programming”

Page 17: Scala in practice

List<String> features = Arrays.asList("noFeature", "featureC", "featureB", "featureA");

for (String feature : features) { System.out.println(feature);}

Page 18: Scala in practice

List<String> javaFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA");

for (String feature : javaFeatures) { System.out.println(feature);}

val scalaFeatures = List( "noFeature", "featureC", "featureB", "featureA")

scalaFeatures foreach { println _ }

Page 19: Scala in practice

val currentFeatures = List("noFeature", "featureC", "featureB", "featureA")

Result: "featureA_toggle, featureB_toggle"

currentFeatures.filter { _.startsWith("feature") }

.mkString(", ") .map { _ + "_toggle" }

.sorted .take(2)

?

Page 20: Scala in practice

String result = "";List<String> currentFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA");Collections.sort(currentFeatures);

int i = 0, j = 0, take = 2; while(i < take && j < currentFeatures.size()) { String feature = currentFeatures.get(j++);

if(feature.startsWith("feature")) { result += feature + "_toggle" + ((i++ != take) ? ", " : ""); }}

currentFeatures.filter { _.startsWith("feature") }

.mkString(", ") .map { _ + "_toggle" }

.sorted .take(2)

Page 21: Scala in practice

“Less

Boilerplate”

Page 22: Scala in practice

public class Property {}

Page 23: Scala in practice

class Property {}

Page 24: Scala in practice

public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } }

Page 25: Scala in practice

class Property(key: String, value: String, default: String) {}

Page 26: Scala in practice

public class Property { // ... public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; }

}

Page 27: Scala in practice

class Property(val key: String, val value: String, val default: String) {}

Page 28: Scala in practice

public class Property { // ... public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); }

@Override public String toString() { return String.format("%s=%s", key, value); }

}

Page 29: Scala in practice

class Property(val key: String, val value: String, val default: String) {

def changeTo(newValue: String) = new Property(key, newValue, default)

def reset = new Property(key, default)

override def toString = "%s=%s" format(key, value)}

Page 30: Scala in practice

public class Property { // ...

@Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; }}

Page 31: Scala in practice

case class Property(key: String, value: String, default: String) {

def changeTo(newValue: String) = Property(key, newValue, default)

def reset = Property(key, default)

override def toString = "%s=%s" format(key, value)}

Page 32: Scala in practice

public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; }

public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); }

@Override public String toString() { return String.format("%s=%s", key, value); }

@Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; }}

Page 33: Scala in practice

case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value)}

Page 34: Scala in practice

public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; }

public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); }

@Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; }

@Override public String toString() { return String.format("%s=%s", key, value); }}

case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value)}

45 vs 5LOCs

* ignoring blank lines

Page 35: Scala in practice

Another Example:{ Blocks }

“Less

Boilerplate”

Page 36: Scala in practice

val content = get("http://foo.com") { toString }

val statusCode = get("http://foo.com") { statusCode }

get("http://foo.com")

int statusCode = httpSupport.get("http://foo.com", new Block<Integer>() { public Integer execute(HttpResponse response) { return response.getStatusLine().getStatusCode()); }});

String content = httpSupport.get("http://foo.com", new Block<String>() { public Integer execute(HttpResponse response) { return EntityUtils.toString(response.getEntity()); }});

httpSupport.get("http://foo.com", new VoidBlock() { public void execute(HttpResponse response) {}});

Page 37: Scala in practice

“Java

Compatibility”

Page 38: Scala in practice

java -cp "lib/*" com.springer.core.app.Casper

Scala library goes in here!

Page 39: Scala in practice

val java = new java.util.ArrayList[String]

val scala: Seq[String] = foo filter { ... }

Page 40: Scala in practice

val log = Logger.getLogger("com.foo")

log.debug("Hello!")

Page 41: Scala in practice
Page 42: Scala in practice

“Gentle

Learning Curve”

“Java without ;”

Libraryre-use JVM

Page 43: Scala in practice

<XML-Support/>

Page 44: Scala in practice

<PdfInfo hasAccess="false"> <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo>

val pdfInfo =

val contentType = (pdfInfo \ "ContentType").text

val hasAccess = (pdfInfo \ "@hasAccess").text.toBoolean

Page 45: Scala in practice

val pdfInfoList = <PdfInfoList> <PdfInfo hasAccess="false"> <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo> <PdfInfo hasAccess="true"> <DDSId>54321</DDSId> <ContentType>Book</ContentType> </PdfInfo> </PdfInfoList>

case class PdfInfo(xml: NodeSeq) { val ddsId = (xml \ "DDSId").head.text val hasAccess = (xml \ "@hasAccess").head.text val contentType = (xml \ "ContentType").head.text}

(pdfInfoList \ "PdfInfo") map { PdfInfo(_) }

Page 46: Scala in practice

“DSL-

Friendly”

Page 47: Scala in practice

System

App2

App3

Functional

App1

Unit

DB

Integration

Levels of Testing

Page 48: Scala in practice

Unit Test DSL

class PropertyTest extends Spec with ShouldMatchers {

it("should render key and value separated with an equals sign") { Property("shark", "fish").toString should equal ("shark=fish") } }

Page 49: Scala in practice

class ForgottenPasswordPageTests extends FunctionalTestSpec with ForgottenPasswordSteps with Uris {

it("should validate user email") { given(iNavigateTo(ForgottenPasswordPage)) when(iSubmitEmail("[email protected]")) then(iShouldSeeInvalidEmailErrorMessage) }

}

Functional Test DSL

Page 50: Scala in practice

Document Validation DSL

trait DDSValidationRules extends JournalXPaths with APlusPlusElements { val journalRules = List( No(JournalTitle) is Invalid, MoreThanOneElementIn(JournalArticle) is Invalid, BadLanguageIn(JournalArticleLanguage) is Invalid,

JournalIssue With No(JournalIssueCoverYear) is Invalid, Bibliography With No(BibliographyHeading) is Invalid,

MarkupIn(JournalTitle) is Unsupported, MarkupIn(JournalAuthor) is Unsupported )

}

Page 51: Scala in practice

“Active

Community”

Page 52: Scala in practice

“Fun”

Page 53: Scala in practice

“Fun”

Page 54: Scala in practice

“Fun”

val foo = (7 to 21)

Page 55: Scala in practice

“Fun”

List<Integers> foo = new ArrayList<Integers>()for (int i = 7; i <= 21; i++) { foo.add(i); }

Page 56: Scala in practice

“Fun”

def eat(food: String = "plankton")

Page 57: Scala in practice

“Fun”

public void eat(String food) {...}

public void eat() { eat("plankton");}

Page 58: Scala in practice

get("http://foo.com") { statusCode }

“Fun”

Page 59: Scala in practice

httpSupport.get("http://foo.com", new Block<Integer>() { public Integer execute(HttpResponse response) { return response.getStatusLine().getStatusCode()); }});

“Fun”

Page 60: Scala in practice

Drawbacks

Page 61: Scala in practice

“Tool

Support”

Page 62: Scala in practice
Page 63: Scala in practice
Page 64: Scala in practice

!?

Page 65: Scala in practice

1:10

Page 66: Scala in practice

“More rope...”

Page 67: Scala in practice

def ++ [B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]):That

Scala Collection Library

Page 68: Scala in practice

class JournalPageTests extends Spec with FunctionalTestSpec with JournalPageSteps with SearchResultsPageSteps with LanguageSteps with LanguageSupport with JavascriptSupport with Uris with IssuePageSteps with VolumesAndIssuesPageSteps with CoverImageUrlBuilders with FakeEntitlementSteps with FullTextPageSteps with CommonAbstractSteps with GoogleAnalyticsSteps with ActionSectionSteps { ... }

Traits Galore in our codebase...

Page 69: Scala in practice

xsbt

Page 70: Scala in practice

scalaz

Page 71: Scala in practice

→Can Should

Page 72: Scala in practice

Risk Mitigations

Page 73: Scala in practice
Page 74: Scala in practice
Page 75: Scala in practice
Page 76: Scala in practice
Page 77: Scala in practice
Page 78: Scala in practice
Page 79: Scala in practice

Would wedo it again

?

Page 80: Scala in practice

disclaimer

use scalaat your own risk

Page 81: Scala in practice

Thanks for

Listening

@patforna | @mhoefi