summaryrefslogtreecommitdiff
path: root/book/src/main/scalatex/book/Intro.scalatex
blob: 33e01889eab2a14b5aedad6b6d489b6468657a6f (plain) (blame)
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
@p
  Scala.js compiles Scala code to equivalent, executable Javascript. Here's the compilation of a trivial hello-world example:

@div(cls:="pure-g")
  @div(cls:="pure-u-1 pure-u-md-1-2")
    @hl.scala
      object Example extends js.JSApp{
        def main() = {
          var x = 0
          while(x < 10) x += 3
          println(x)
        }
      }

  @div(cls:="pure-u-1 pure-u-md-1-2")
    @hl.javascript
      ScalaJS.c.LExample$.prototype.main__V = (function() {
        var x = 0;
        while ((x < 10)) {
          x = ((x + 3) | 0)
        };
        ScalaJS.m.s_Predef().println__O__V(x)
      });

@p
  As you can see, both of the above programs do identical things: it's just that the one on the left is written in Scala and the one on the right is in Javascript.

@p
  Traditionally, Scala has been a language which runs on the JVM. This eliminates it from consideration in many cases, e.g. when you need to build interactive web apps, you need to fall back to Javascript to run your client-side code, at a great loss in terms of toolability and maintainability. Scala.js lets you to develop web applications with the safety and toolability that comes with a statically typed language:

@ul
  @li
    Typo-safety due to its compiler which catches many silly errors before the code is run
  @li
    In-editor support for autocomplete, error-highlghting, refactors, and intelligent navigation
  @li
    Very small compiled executables, in the 100-400kb range
  @li
    Source-maps for ease of debugging

@p
  The value proposition is that due to the superior language and tooling, writing a web application in Scala.js will result in a codebase that is more flexible and robust than an equivalent application written in Javascript.

@sect{About Javascript}
  @p
    Javascript is the language supported by web browsers, and is the only language available if you wish to write interactive web applications. As more and more activity moves online, the importance of web apps will only increase over time.

  @sect{Javascript-the-language}
    @p
      However, Javascript is not an easy language to work in. Apart from being untyped (which some people don't mind) Javascript is also extremely verbose, has a lot of surprising behavior, and has a culture that make even the simplest of patterns (e.g. instantiating an object) a debate between a dozen different and equally-bad options.
    @p
      To work in Javascript, you need the discipline to limit yourself to the sane subset of the language, avoiding all the pitfalls along the way:

    @img(src:="images/javascript-the-good-parts-the-definitive-guide.jpg")

  @sect{Javascript-the-platform}
    @p
      However, even as Javascript-the-language sucks, Javascript-the-platform has some very nice properties that make it a good target for application developers:

    @ul
      @li
        Zero-install distribution: just go to a URL and have the application downloaded and ready to use.
      @li
        Hyperlinks: being able to link to a particular page or item within a web app is a feature other platforms lack, and makes it much easier to cross-reference between different systems
      @li
        Sandboxed security: before the advent of mobile apps, web apps were the most secure runtime available, offering none of the risk or worry that comes with installing desktop software

    @p
      These features are all very nice to have, and together have made the web platform the success it is today.

  @hr

  @p
    This is where Scala.js comes in. As developers we want Javascript-the-platform, with its ease-of-distribution, hyperlinks and security characteristics. We do not want Javascript-the-language, with its propensity for bugs, verbosity, and fragility.

@sect{The Promise}

  @p
    Scala.js promises to save us from this mess: with Scala.js, you can cross compile your Scala code to a Javascript executable that can run on all major web browsers, thus saving you from the endless stream of gotcha's like the one below:

  @hl.javascript
    javascript> ["10", "10", "10", "10"].map(parseInt)
    [10, NaN, 2, 3] // WTF

  @hl.scala
    scala> List("10", "10", "10", "10").map(parseInt)
    List(10, 10, 10, 10) // Yay!

  @sect{The Language}
    @p
      At a first approximation, Scala.js provides you a sane language to do development in the web browser. Not only do you have an expressive language with static types, you also have great tooling with IDEs like IntelliJ and Eclipse, a rich library of standard collections, and many other modern conveniences that we take for granted but are curiously missing when working in the wild west of web development: the browser!

    @p
      While not useful for small applications, where most of the logic is gluing together external APIs, this comes in very useful in large applications where a lot of the complexity and room-for-error is entirely internal. With larger apps, you can no longer blame browser vendors for confusing APIs that make your code terrible: these confusing APIs only lurk in the peripherals around a larger, complex application. One thing you learn working in large-ish web client-side code-bases is that the bulk of the confusion and complexity is no-one's fault but your own, as a team.

    @p
      At this point, all of Google, Facebook, and Microsoft have all announced work on a typed variant of Javascript. These are not academic exercises: @lnk("Dart", "https://www.dartlang.org/")/@lnk("AtScript", "https://docs.google.com/document/d/11YUzC-1d0V1-Q3V0fQ7KSit97HnZoKVygDxpWzEYW0U/edit")/@lnk("Flow", "https://lobste.rs/s/fp9ibi/flow_facebook_s_new_javascript_type_checker")/@lnk("Typescript", "http://www.typescriptlang.org/") are all problems that solve a real need, that these large companies have all faced once they've grown beyond a certain size. Clearly, Javascript isn't cutting it anymore, and the convenience and "native-ness" of the language is more than made up for in the constant barrage of self-inflicted problems. Scala.js takes this idea and runs with it!

  @sect{Sharing Code}
    @p
      Scala.js does not just stop at writing code on the client, though! Scala itself is a very successful, capable language for writing all sorts of systems, from web servers to backend infrastructure. With Scala.js, you can utilize the same libraries you use writing your Scala servers when writing your Scala web clients! On one end, you are sharing your templating language with @lnk("Scalatags", "https://github.com/lihaoyi/scalatags") or sharing your serialization logic with @lnk("uPickle", "https://github.com/lihaoyi/upickle"). At the other, you are sharing large, abstract libraries like @lnk("Scalaz", "https://github.com/japgolly/scalaz") or @lnk("Shapeless", "https://groups.google.com/forum/#!searchin/scala-js/shapeless/scala-js/5Sf2up0z3PU/9F9SYB0qHEcJ").

    @p
      Sharing code means several things:

    @ul
      @li
        Not having to find two libraries to do a particular common task
      @li
        Not having to re-learn two different ways of doing the exact same thing
      @li
        Not needing to implement the same algorithms twice, for the times you can't find a good library to do what you want
      @li
        Not having to debug problems caused by subtle differences in the two implementations
      @li
        Not having to resort to awkward Ajax-calls or pre-computation to avoid duplicating logic between the client and server

    @p
      Shared code doesn't just mean sharing pre-made libraries between the client and server. You can easily @sect.ref("Cross Publishing Libraries", "publish your own libraries") that can be used on both Scala-JVM and Scala.js. This means that as a library author, you can at once target two completely different platforms, and (with some work) take advantage of the intricacies of each platform to optimize your library for each one. Take Scalatags as an example: as the first client-server Scala.js-ScalaJVM shared libraries, it enjoys a roughly event split of downloads from people using it on both platforms:

    @img(src:="images/Scalatags Downloads.png", width:="100%")

    @p
      Shared code means that if you, as an application writer, want some logic to be available on both the client and server, you simply put it in a "shared" folder, and that's the end of the discussion. No architectural patterns to follow, no clever techniques need to be involved. Shared logic, whether that means constants, functions, data structures, all the way to algorithms and entire libraries, can simply be placed in "shared" and be instantly accessible from both your client-side web code and your server.

    @p
      Shared code has long been the holy-grail of web development. Even now, people speak of shared code as if it were a myth. With Scala.js, shared code is the simple, boring reality. And there's a lot to like in that!

  @sect{Client-Server Integration}
    @p
      There is an endless supply of new platforms which have promised to change-the-way-we-do-web-development-forever. From old-timers like @lnk("Ur-Web", "http://www.impredicative.com/ur/"), to @lnk("GWT", "http://www.gwtproject.org/"), to Asana's @lnk("LunaScript", "https://asana.com/luna"), to more recently things like @lnk("Meteor.js", "https://www.meteor.com/").
    @p
      One common theme in all these platforms is that their main selling point is their tight, seamless client-server integration, to the point where you can just make method calls across the client-server boundary and the platform/language/compiler figures out what to do.
    @p
      With Scala.js and Scala-JVM, such conveniences like making method calls across the client-server boundary is the @sect.ref("Integrating Client-Server", "boring reality"). Not only are the calls transparent, they are also statically checked, so any mistake in the route name or the parameters it expects, or the result type it returns to you, will be caught by the compiler long before even manual testing.

  @hr

  @p
    In many ways, Scala.js all-at-once provides many of the traditional holy-grails of web development: People have always dreamed about doing web development in a sane, best-of-breed language that compiles to both client and server. Of not having to worry too hard about whether code goes on the client or on the server, and being able to move or share it if necessary. Of having a compiler that will verify and check that your entire system is correct.

  @p
    Scala.js provides all these things, and much more.

@sect{The Agenda}

  @p
    This book will be roughly divided into three sections. These sections can be read in any order. Although the later chapters will make references to earlier chapters, there'll be hyperlinks so you can quickly go back and catch up on what you missed skipping over ,

  @sect{Part 1: Hands On}
    @p
      A @sect.ref("Hands On", "whirlwind tour") of the various things that Scala.js can be used for. We will cover:

    @ul
      @li
        @sect.ref("Getting Started"): setting up your development environment, cloning the example repository, debugging and finally publishing your first toy application
      @li
        @sect.ref("Interactive Web Pages"): how you interact with the HTML DOM, how you utilize Ajax calls and other browser APIs that are common in Javascript-heavy applications
      @li
        @sect.ref("Cross Publishing Libraries"): how to write a module that can be depended on by applications both your own and by others, and be used both with Scala.js and Scala-on-the-JVM
      @li
        @sect.ref("Client-Server Integration"): We will build a simple web application with a Scala server and Scala.js client. In the process, we'll explore how to share code between client and server, how to get compiler-checked/boilerplate-free Ajax calls between client and server, and many other long-standing holy-grails of web development

    @p
      After going through this chapter and following along with the exercises, you should have a good sense of how Scala.js works and how it feels building things in Scala.js. You would not be an expert, but you'll know where to get started if you decide to try out Scala.js for your next project.

  @sect{Part 2: In Depth}
    @p
      @sect.ref("In Depth", "This section of the book") will cover lots of content that does not fit in the earlier Hands-On portion of the book. Things that aren't immediately necessary to get something up and running, things that only advanced users would care about, things that you probably don't need to know but you'd like to know out of intellectual curiosity.

    @p
      In general, this section of the book will go much deeper into Scala.js, much more than is necessary to get your first applications built. We will talk about the small number of @sect.ref("Deviations from Scala-JVM", "Semantic Differences") between Scala.js and Scala, details of the foreign-function-interface used for @sect.ref("Javascript Interoperability"), @sect.ref("The Compilation Pipeline") with its various optimization levels and what they do. Nothing pressing or urgently needed, but all very interesting, and worth reading if you want to really understand Scala.js in depth.

  @hr

  @p
    As mentioned earlier, these chapters can be read in any order. In keeping with the spirit of the book, we'll jump right into the Hands On to give you the experience, and save the talking and philosophizing for later. Let's go!