Presentation on how to chat with PDF using ChatGPT code interpreter
Intro to Scala.js - Scala UG Cologne
1. Intro to Scala.js
Marius Soutier
Freelance Software Engineer
@mariussoutier
Write JavaScript in Scala
2. What is Scala.js?
Scala.js compiles Scala to JavaScript
object HelloUg extends JSApp {
override def main(): Unit = {
// FP for the win
var res, i = 0
val values = js.Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
while (i < values.length) {
res = res + values(i)
i += 1
}
println(res)
}
}
$c_Lug_HelloUg$.prototype.main__V = (function() {
var res = 0;
var i = 0;
var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
while ((i < $uI(values["length"]))) {
res = ((res + $uI(values[i])) | 0);
i = ((1 + i) | 0)
};
var x = res;
var this$2 = $m_s_Console$();
var this$3 = this$2.outVar$2;
$as_Ljava_io_PrintStream(this$3.tl$1.get__O()).println__O__V(x)
});
$e["ug"] = ($e["ug"] || {});
$e["ug"]["HelloUg"] = $m_Lug_HelloUg$;
3. But Why?
• Web development is moving to client-side apps,
JavaScript is the browser’s only language
• JavaScript is beyond broken
• Maintaining a large JavaScript project can be difficult
• Keeping up with JavaScript’s ecosystem is nigh-
impossible
(See JavaScript Drinking Game)
5. Scala.js to the Rescue
• We all love Scala
• Type-safety, packages, traits, …
• Rich standard library
• Share code between backend and front-end
• Full editor support (same file suffix)
• Access to all JS libs and a lot of the Scala ecosystem
7. • Size of compiled JavaScript
• Compile Speed
• JS libraries must be wrapped
• Scala is developed with JVM in mind, some things
just don't work in JS land, some JDK parts missing
• Front-end developers might not want to learn Scala
(slackers!)
Drawbacks
8. • Scala libraries available for Scala.js
• Scalatags, ScalaCSS
• Shapeless, Scalaz, Cats, Monocle
• Sharing code inside a project via common cross-compiled
sbt sub-project
• Data exchange via JSON
• upickle
• JavaScript doesn't necessarily understand your JSON,
e.g. Longs aren't that long in JavaScript
Sharing Code & Data
9. How Does It Work?
.scala
.class
.sjsir
run/test
~fastOptJS
fullOptJS
Google
Closure
-opt.js
-fastopt.js
Rhino / Node.js
Rhino / PhantomJS
No DOM
DOM
-jsdeps.min.js
jsDependencies ++= Seq(
"org.webjars" % "jquery" % "1.10.2" / "jquery.js",
"org.webjars" % "angularjs" % "1.4.8" / "angular.js" dependsOn "jquery.js"
)
10. Targeting JavaScript
Scala / JVM JavaScript
Byte, Short, Int, Float, Double Number
Unit Undefined
Char, Long Scala classes
Custom Scala classes JavaScript class with @JSExport
NullPointerException,
ArrayIndexOutOfBoundsException,
ClassCastException, StackOverflowError, …
Undefined
Reflection -
String.split JS RegEx is different
Pattern Matching on Byte, Short, Int, Float, Double Determined by runtime value, not type
11. JavaScript Native Types
JS-native Type Maps to Example JS
js.FunctionN scala.FunctioN val fn: js.Function1[Int, Int] =
(i: Int) => i * 2
var fn = function(i)
{
return i * 2;
};
js.Array[T] Seq[T] js.Array(1, 2, 3) [1, 2, 3]
js.Dictionary[T] mutable.Map[String, T] js.Dictionary("a" -> 1, "b" -> 2) {"a": 1, "b": 2}
js.UndefOr[T] Option[T]
val some: js.UndefOr[Int] = 1
val none: js.UndefOr[Int] =
js.undefined
Option(1).orUndefined
1
undefined
1
js.TupleN TupleN js.Tuple2(42, “Scala UG") [42, "Scala UG"]
12. Dynamic JS
When interacting with JavaScript libraries, its dynamic
nature can’t always be ignored
val guest = js.Dynamic.literal(
name = "Scala User Group"
)
But we can give it a nicer interface
trait Guest extends js.Object {
val name: String = js.native
}
object Guest {
def apply(name: String): Guest =
js.Dynamic.literal(name = name).asInstanceOf[Guest]
}
import js.Dynamic.{global => g}
g.console.log(guest)
val dom = g.document
val p = dom.createElement("p")
p.innerHTML = s"Hi ${guest.name}!"
dom.getElementById("main").appendChild(p)
15. Manipulating the DOM
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "0.8.2"
)
import org.scalajs.dom._
val main = document.getElementById("main")
val p = document.createElement("p")
val text = document.createTextNode("Hi Scala User Group!")
p.appendChild(text)
main.appendChild(p)
17. • Export classes to JS for use from other JS code
• Can even publish as NPM module
Using Scala.js from JS
@JSExport
case class ExportedUser(
@(JSExport@field) name: String,
@(JSExport@field) email: String
)
@JSExport
@ScalaJSDefined
class Foo extends js.Object {
val x: Int = 4
def bar(x: Int): Int = x + 1
}