Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Scala tech talk
Search
Yann Simon
October 07, 2013
Programming
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Scala tech talk
presentation of the Scala language for Java programmers
Yann Simon
October 07, 2013
More Decks by Yann Simon
See All by Yann Simon
Structure a Play application with the cake pattern (and test it)
yanns
1
720
presentation of the Play! Framework
yanns
0
270
Other Decks in Programming
See All in Programming
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
370
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
テーブルをDELETEした
yuzneri
0
110
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
280
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
2.3k
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
240
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
180
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
110
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
860
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
360
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
150
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.3k
Featured
See All Featured
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
190
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
390
First, design no harm
axbom
PRO
2
1.2k
Ruling the World: When Life Gets Gamed
codingconduct
0
290
Music & Morning Musume
bryan
47
7.3k
Chasing Engaging Ingredients in Design
codingconduct
0
240
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
400
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
310
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Context Engineering - Making Every Token Count
addyosmani
9
1k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Transcript
Scala
Who am I?
Yann Simon @simon_yann
None
Why Scala?
Fear to lose job?
None
None
None
Java can be pain #1
public String createInvoiceName( Date invoiceDate, String invoiceId, String userId, String
firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { // ...
String newInvoiceId = invoiceCreator.createInvoiceName( new Date(), "45AE-45F", "872346", "abc-234", true,
false, false );
let's make it readable
String newInvoiceId = invoiceCreator.createInvoiceName( new Date(), // invoiceDate "45AE-45F", //
invoiceId "872346", // userId "abc-234", // firmId true, // directInvoice false, // firmInvoice false // electronic );
OO maybe?
public class NewInvoiceNameCommand { private final Date invoiceDate; private final
String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; public NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; } }
public String createInvoiceName( NewInvoiceNameCommand newInvoiceNameCommand) { // ... return "id";
} String newInvoiceId = invoiceCreator.createInvoiceName( newInvoiceNameCommand);
NewInvoiceNameCommand newInvoiceNameCommand = new NewInvoiceNameCommand( new Date(), "45AE-45F", "872346", "abc-234",
true, false, false );
builder pattern to the rescue
public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private
Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); } public NewInvoiceNameCommandBuilder withInvoiceDate(Date invoiceDate) { this.invoiceDate = invoiceDate; return this; } public NewInvoiceNameCommandBuilder withInvoiceId(String invoiceId) { this.invoiceId = invoiceId; return this; } [...] } } private final Date invoiceDate; private final String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; private NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; }
NewInvoiceNameCommand newInvoiceNameCommand = new NewInvoiceNameCommand.NewInvoiceNameCommandBuilder() .withInvoiceDate(new Date()) .withInvoiceId("45AE-45F") .withUserId("872346") .withFirmId("abc-234")
.withDirectInvoice(true) .withFirmInvoice(false) .withElectronic(false) .build(); String newInvoiceId = invoiceCreator.createInvoiceName(newInvoiceNameCommand);
with default values
public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private
Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommandBuilder() { // default values this.directInvoice = true; this.firmInvoice = false; } public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); }
NewInvoiceNameCommand newInvoiceNameCommand = new NewInvoiceNameCommand.NewInvoiceNameCommandBuilder() .withInvoiceDate(new Date()) .withInvoiceId("45AE-45F") .withUserId("872346") .withFirmId("abc-234")
.withElectronic(false) .build(); String newInvoiceId = invoiceCreator.createInvoiceName(newInvoiceNameCommand);
better!
just need some glue
public class NewInvoiceNameCommand { public static class NewInvoiceNameCommandBuilder { private
Date invoiceDate; private String invoiceId; private String userId; private String firmId; private boolean directInvoice; private boolean firmInvoice; private boolean electronic; public NewInvoiceNameCommandBuilder() { // default values this.directInvoice = true; this.firmInvoice = false; } public NewInvoiceNameCommand build() { return new NewInvoiceNameCommand( invoiceDate, invoiceId, userId, firmId, directInvoice, firmInvoice, electronic); } public NewInvoiceNameCommandBuilder withInvoiceDate(Date invoiceDate) { this.invoiceDate = invoiceDate; return this; } public NewInvoiceNameCommandBuilder withInvoiceId(String invoiceId) { this.invoiceId = invoiceId; return this; } public NewInvoiceNameCommandBuilder withUserId(String userId) { this.userId = userId; return this; } public NewInvoiceNameCommandBuilder withFirmId(String firmId) { this.firmId = firmId; return this; } public NewInvoiceNameCommandBuilder withDirectInvoice(boolean directInvoice) { this.directInvoice = directInvoice; return this; } public NewInvoiceNameCommandBuilder withFirmInvoice(boolean firmInvoice) { this.firmInvoice = firmInvoice; return this; } public NewInvoiceNameCommandBuilder withElectronic(boolean electronic) { this.electronic = electronic; return this; } } private final Date invoiceDate; private final String invoiceId; private final String userId; private final String firmId; private final boolean directInvoice; private final boolean firmInvoice; private final boolean electronic; private NewInvoiceNameCommand( Date invoiceDate, String invoiceId, String userId, String firmId, boolean directInvoice, boolean firmInvoice, boolean electronic) { this.invoiceDate = invoiceDate; this.invoiceId = invoiceId; this.userId = userId; this.firmId = firmId; this.directInvoice = directInvoice; this.firmInvoice = firmInvoice; this.electronic = electronic; } public Date getInvoiceDate() { return invoiceDate; } public String getInvoiceId() { return invoiceId; } public String getUserId() { return userId; } public String getFirmId() { return firmId; } public boolean isDirectInvoice() { return directInvoice; } public boolean isFirmInvoice() { return firmInvoice; } public boolean isElectronic() { return electronic; } }
let's try with Scala
def createInvoiceName( invoiceDate: Date, invoiceId: String, userId: String, firmId: String,
directInvoice: Boolean, firmInvoice: Boolean, electronic: Boolean): String = { // ... }
val newInvoiceId = invoiceCreator.createInvoiceName( new Date, "45AE-45F", "872346", "abc-234", true,
false, false )
Scala can be ugly too (surprise #1)
val newInvoiceId = invoiceCreator.createInvoiceName( new Date, // invoiceDate "45AE-45F", //
invoiceId "872346", // userId "abc-234", // firmId true, // directInvoice false, // firmInvoice false // electronic )
comments exist in Scala (surprise #2)
val newInvoiceId = invoiceCreator.createInvoiceName( invoiceDate = new Date, invoiceId =
"45AE-45F", userId = "872346", firmId = "abc-234", directInvoice = true, firmInvoice = false, electronic = false )
Yes, named parameters!
and default values?
def createInvoiceName( invoiceDate: Date, invoiceId: String, userId: String, firmId: String,
directInvoice: Boolean = true, firmInvoice: Boolean = false, electronic: Boolean): String = {
val newInvoiceId = invoiceCreator.createInvoiceName( invoiceDate = new Date, invoiceId =
"45AE-45F", userId = "872346", firmId = "abc-234", electronic = false )
but I want a command object
case class NewInvoiceNameCommand ( invoiceDate: Date, invoiceId: String, userId: String,
firmId: String, directInvoice: Boolean = true, firmInvoice: Boolean = false, electronic: Boolean )
val newInvoiceNameCommand = NewInvoiceNameCommand ( invoiceDate = new Date, invoiceId
= "45AE-45F", userId = "872346", firmId = "abc-234", electronic = false ) val newInvoiceId = invoiceCreator.createInvoiceName( newInvoiceNameCommand)
Java can be pain #2
public int multiplyBy2(int number) { return number * 2; }
[...] public void multiplyUserInputBy2() { Integer userInput = null; multiplyBy2(userInput); }
def multiplyBy2(number: Int): Int = { number * 2 }
def multiplyUserInputBy2 { //val userInput: Int = null // does not compile //val userInput = Int.unbox(new Integer(null)) throws exception val userInput = 2 multiplyBy2(userInput) }
Java can be pain #3
public class User { private final String name; private final
String gender; private final Date dateOfBirth; public User(String name, String gender, Date dateOfBirth) { this.name = name; this.gender = gender; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public String getGender() { return gender; } public Date getDateOfBirth() { return dateOfBirth; } }
public class User { private final String name; private final
String gender; private final Date dateOfBirth; public User(String name, String gender, Date dateOfBirth) { this.name = name; this.gender = gender; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public String getGender() { return gender; } public Date getDateOfBirth() { return dateOfBirth; } public Integer getAge() { if (dateOfBirth == null) { return null; } Date now = new Date(); long difference = now.getTime() - dateOfBirth.getTime(); Calendar yearCalculator = Calendar.getInstance(); yearCalculator.setTimeInMillis(difference); return yearCalculator.get(Calendar.YEAR); } }
public class UserBusiness { private final UserRepository userRepository = new
UserRepository(); public boolean isUserAllowed(String name) { User user = userRepository.findUserByName(name); if (user != null) { if (user.getGender() != null && user.getGender().equals("F")) { if (user.getAge() != null && user.getAge() >= 18) { return true; } } } return false; } }
case class User ( name: String, gender: Option[String] = None,
dateOfBirth: Option[Date] = None ) { def age: Option[Int] = dateOfBirth.map { dob => calculateAge(dob) } private def calculateAge(dateOfBirth: Date): Int = { val now = new Date() val difference = now.getTime - dateOfBirth.getTime val yearCalculator = Calendar.getInstance() yearCalculator.setTimeInMillis(difference) yearCalculator.get(Calendar.YEAR) } }
class UserBusiness { val userRepository = new UserRepository() def isUserAllowed(name:
String): Boolean = { val allowedUser = for { user <- userRepository.findUserByName(name) gender <- user.gender if gender == "F" age <- user.age if age >= 18 } yield user allowedUser.isDefined } }
Bye bye NullPointerException
Asynchronous IO
Asynchronous IO - What?
None
None
None
Asynchronous IO - Why?
None
None
None
None
Asynchronous IO in Java
public Promise<JsonNode> searchStock(String query) { Promise<WS.Response> responsePromise = WS.url("http://localhost:9001/search") .setQueryParameter("query",
query) .get(); return responsePromise.map(new F.Function<WS.Response, JsonNode>() { @Override public JsonNode apply(WS.Response response) throws Throwable { if (response.getStatus() == 200) { JsonNode jsonNode = response.asJson(); return jsonNode.findPath("results"); } else { throw new Exception("Error calling search service.\nResponse status " + response.getStatus() + "\n"); } } }); }
Asynchronous IO in Scala
def searchStock(query: String): Future[Seq[JsObject]] = { WS.url("http://localhost:9001/search") .withQueryString("query" -> query)
.get() .map { response => response.status match { case 200 => (response.json \ "results").as[Seq[JsObject]] case _ => throw new Exception(s"Error calling search service.\nResponse status ${response.status}\n") } } }
Three sequential calls
public static Promise<Result> index(String userId) { Promise<User> user = backends.getUserById(userId);
Promise<List<Order>> orders = user.flatMap(new F.Function<User, Promise<List<Order>>>() { @Override public Promise<List<Order>> apply(User user) throws Throwable { return backends.getOrdersForUser(user.getEmail()); } }); Promise<List<Product>> products = orders.flatMap(new F.Function<List<Order>, Promise<List<Product>>>() { @Override public Promise<List<Product>> apply(List<Order> orders) throws Throwable { return backends.getProductsForOrders(orders); } }); Promise<List<Stock>> stocks = products.flatMap(new F.Function<List<Product>, Promise<List<Stock>>>() { @Override public Promise<List<Stock>> apply(List<Product> products) throws Throwable { return backends.getStocksForProducts(products); } }); Promise<List<Object>> promises = Promise.sequence(user, orders, products, stocks); return promises.map(new F.Function<List<Object>, Result>() { @Override public Result apply(List<Object> results) throws Throwable { User user = (User)results.get(0); List<Order> orders = (List<Order>)results.get(1); List<Product> products = (List<Product>)results.get(2); List<Stock> stocks = (List<Stock>)results.get(3); return ok(orders.size() + " order(s) for user " + user.getEmail()); } }); }
def index(userId: String) = Action.async { for { user <-
getUserById(userId) orders <- getOrdersForUser(user.email) products <- getProductsForOrders(orders) stocks <- getStocksForProducts(products) } yield Ok(s"${orders.size} order(s) for user ${user.email}") }
OK, I want to try Scala
Be careful
Scala can be pain #1
✗ slow compilation
✗ slow compilation incremental compilation ~run modules Scala 2.11
Scala can be pain #2
functional programming terrorists
use the most appropriate style for the problem (and for
the maintenance)
Scala can be pain #3
# Scala dev < Java
use this problem as opportunity Ex: “Yes, all of us
were quite experienced Java programmers. [...] Because we were all learning together, this worked really well.”
Online courses: Functional Programming Principles in Scala Principles of Reactive
Programming
Scala User Group Play framework User Group
Trainings http://www.leanovate.de/training/software/
I get it I want to try Scala
Integration in my project?
✔ Maven ✔ ANT ✔ SBT ✔ Gradle
Begin with scala-test?
test("content disposition parser extracts the filename") { val header =
"Attachment; filename=example.html" val filename = ContentDispositionHeader.parse(header).filename assert(filename === Some("example.html")) }
it should "replace ä with ae" in { SwiftLatinCharset.from("fooÄfoo") shouldEqual
"fooAefoo" SwiftLatinCharset.from("fooäfoo") shouldEqual "fooaefoo" }
Integration in my firm?
Continuous Integration
sbt test mvn test ...
✔ ✔ ✔
Scala ✔ Integrate with Java ✔ Integrate with existing build
✔ Usual tools
Build products ✔ efficient development ✔ motivated teams ✔ enable
SOA (async IO) ✔ less lines of code ✔ easier maintenance
✔ focus on your product!
thanks for your attention