type safe json using scala...
TRANSCRIPT
![Page 1: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/1.jpg)
Type safe JSON using Scala Macros
Grzegorz Kossakowski
![Page 2: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/2.jpg)
Who am I?
• Software Engineer at Typesafe• I hack Scala compiler and tools
surrounding it• I focus on performance and good
developer experience• In previous life: committer to Apache
Cocoon; Apache Software Foundation member
![Page 3: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/3.jpg)
What this talk is not about?
• Introduction to Scala• Complete, ready to use software product• Tutorial for writing Scala macros
We’ll look into what future interaction with data might look like
![Page 4: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/4.jpg)
How do you read your JSON?
![Page 5: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/5.jpg)
Typical JSON snippet{ "created_at": "Wed May 15 07:13:11 +0000 2013", "id": 334567116512583680, "id_str": "334567116512583680", "text": "Just arrived for #geecon. Big crowd aleady! (@ GeeCON 2013 w/ 3 others) http://t.co/E0LlvfNzOe", "truncated": false, "user": { "id": 26209148, "id_str": "26209148", "name": "Grzegorz Kossakowski", "screen_name": "gkossakowski", "location": "San Francisco", "created_at": "Tue Mar 24 10:03:50 +0000 2009" }, "lang": "en"} api.twitter.com
![Page 6: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/6.jpg)
Accessing JSON
• If you are using a dynamically typed language, e.g. JavaScriptvar json = parseJson("tweets.json")var username = json.user.screen_name
ObjectMapper m = new ObjectMapper();JsonNode rootNode = m.readTree(new File("tweets.json"));JsonNode userNode = rootNode.path("user");String userName = userNode.path("screen_name").getTextValue()
• If you are using a statically typed language, e.g. Java
![Page 7: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/7.jpg)
Accessing JSONpublic class Tweet { public static class User { private String screen_name, ...;
public String getScreen_name() { return screen_name; } public void setScreen_name(String n) { screen_name = s; } ... } private User user; ...}
ObjectMapper mapper = new ObjectMapper();Tweet tweet = mapper.readValue(new File("tweets.json"), Tweet.class);String userName = tweet.getUser().getScreen_name();
![Page 8: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/8.jpg)
Accessing JSONpublic class Tweet { public static class User { @JsonProperty("screen_name") private String screenName, ...;
public String getScreenName() { return screenName; } public void setScreenName(String n) { screenName = s; } ... } private User user; ...}
ObjectMapper mapper = new ObjectMapper();Tweet tweet = mapper.readValue(new File("tweets.json"), Tweet.class);String userName = tweet.getUser().getScreenName();
![Page 9: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/9.jpg)
Is it choice between static typing & code completion or little ceremony?
![Page 10: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/10.jpg)
F#
type Tweet = JsonProvider<"tweet.json">let tweet = Tweet.Parse(text)let tweet = tweet.user.screen_name
• F# has a concept of type providers• They let user write a piece of code that compiler will
execute to determine a type• They can perform I/O
![Page 11: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/11.jpg)
Scala macros
• Macro is a piece of code that compiler will execute and feed the result back to compiled program
• Scala macros are hygienic which means results of their expansion have to type check
• They can perform I/O like reading files, connecting to web services, etc.
val tweet = parseJson("tweet.json")val username = tweet.user.screen_name
![Page 12: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/12.jpg)
DEMO
![Page 13: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/13.jpg)
What parseJson returns?
• Macros are hygienic so they have to return a valid Scala expression
parseJson("tweet.json") =>
class Json_1(...)class Json_2(...)new Json_1(...)
Not all
owed
!
![Page 14: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/14.jpg)
What parseJson returns?
• Macros are hygienic so they have to return a valid Scala expression
parseJson("tweet.json") =>
{ class Json_1(...) class Json_2(...) new Json_1(...)}
![Page 15: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/15.jpg)
Structural typing
• Most of statically typed languages used nominal (name-based) types
• In nominal type system type equivalence and subtyping is determined by names
• In structural type system types are defined by their structure; names of types are irrelevant
• Scala supports both nominal and structural typing
![Page 16: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/16.jpg)
Structural typing
scala> class A1(val x: Int)defined class A1
scala> class A2(val x: Int)defined class A2
scala> val test1: {val x: Int} = new A1(78)test1: AnyRef{val x: Int} = A1@14cb5de2
scala> val test2: {val x: Int} = new A2(78)test2: AnyRef{val x: Int} = A2@45fcb00e
scala> val test: A2 = new A1(78)<console>:9: error: type mismatch; found : A1 required: A2 val test: A2 = new A1(78) ^
![Page 17: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/17.jpg)
Structural typing & type inference
scala> val test = { | class Foo(val x: Int, val y: String) | new Foo(78, "abc") | }
test: Object{val x: Int; val y: String} = Foo$1@6be4b53d
![Page 18: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/18.jpg)
Structural typing & type inference
scala> :paste// Entering paste mode (ctrl-D to finish)
val test = { class Foo(val x: Int, val y: String) class Bar(val f1: Foo, f2: Foo) val foo = new Foo(78, "abc") new Bar(foo, foo)}
// Exiting paste mode, now interpreting.
test: Bar forSome { type Bar <: Object{val f1: Foo}; type Foo <: Object{val x: Int; val y: String}} = Bar$1@1ae3043b
![Page 19: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/19.jpg)
DEMO 2
![Page 20: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/20.jpg)
Scala macros, scary or useful?
• Initially, I found them scary for numerous reasons:• Hard to understand what’s going on in your program• Compilation results might depend on external system; no
reproducible build?• IDE performance might suffer very easily due to poorly
written macros• Macros are extremely hard to write
• There are still very good use cases for them• These days I’m a fan of ephemeral macros that live for a
very short time
![Page 21: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/21.jpg)
Ephemeral macros
• Executed only by IDE• Live for a very short time• Code generated by a macro gets
expanded and committed as a regular source code
![Page 22: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/22.jpg)
Walkthrough macro implementation
![Page 23: Type safe JSON using Scala Macross3-eu-west-1.amazonaws.com/presentations2013/56_presentation.pdfScala macros • Macro is a piece of code that compiler will execute and feed the result](https://reader035.vdocument.in/reader035/viewer/2022070722/5f01dadd7e708231d4015cd4/html5/thumbnails/23.jpg)
Questions?
@gkossakowski