Draft scala slides

This commit is contained in:
Oliver Kennedy 2021-01-31 22:46:57 -05:00
parent 4f37d64944
commit cfa49abf4f
Signed by: okennedy
GPG key ID: 3E5F9B3ABD3FDB60
2 changed files with 463 additions and 0 deletions

View file

@ -0,0 +1,457 @@
---
template: templates/cse4562_2021_slides.erb
title: Scala Introduction
date: Feb 4, 2021
---
<section>
<section>
<h3>My assumptions</h3>
<p>(assuming you don't already know Scala)</p>
<ul>
<li>You know Java (or at least some other object oriented language like C++ or C#)</li>
<li>You are familiar with the JVM ecosystem (Java, Kotlin, JRruby, Jython, etc...)</li>
</ul>
<p class="fragment">This lecture will focus on <u>syntax</u>.</p>
</section>
<section>
<h3>Some Terms</h3>
<dl>
<dt>Package</dt>
<dd>An organizational unit clustering related functionality</dd>
<dt>Object</dt>
<dd>A 'singleton' class. (Like Java's <b>static</b>)</dd>
<dt>Companion Object</dt>
<dd>A 'singleton' class implementing methods related to a class</dd>
<dt>Case Class</dt>
<dd>A class with bonus features (we'll discuss shortly).</dd>
</dl>
</section>
</section>
<section>
<section>
<h3>Hello World</h3>
<pre><code class="scala">
package edu.buffalo.myapp
import java.io.File
import scala.io._
object MyApp
{
val message: String = "Hello World"
def main(args: Array[String]): Unit = {
println(message)
var stream: Stream = Stream.fromFile(new File("Hello.txt"))
for(line <- stream.getLines){
println(line)
}
}
}
</code></pre>
</section>
<section>
<pre><code class="scala">
package edu.buffalo.myapp
</code></pre>
Package definitions are exactly like Java.
</section>
<section>
<pre><code class="scala">
import java.io.File
</code></pre>
Import statements bring classes into the namespace, making them available for use.
<div class="fragment">
<pre><code class="scala">
import scala.io._
</code></pre>
<tt>'_'</tt> acts like a wildcard in scala.<br/> This is like <tt>import scala.io.*</tt> in Java.
</div>
<div class="fragment">
<pre><code class="scala">
import java.io.{ File, FileInputStream }
</code></pre>
Curly braces group class names together as a shorthand when you import multiple classes from the same package.
</div>
</section>
<section>
<pre><code class="scala">
object MyApp {
</code></pre>
Objects in scala are "singletons". They act like Java classes with only static methods. E.g., you could call <tt>MyApp.main(...)</tt>
<div class="fragment">
<pre><code class="scala">
class MyClass(name: String, age: Int) {
</code></pre>
Classes are defined much like java, except constructor fields are given directly in the class definitions. e.g., you would instantiate this class as <tt>new MyClass("Bob", "102")</tt>.
</div>
</section>
<section>
<pre><code class="scala">
class MyClass(name: String, age: Int)
extends MyAncestorClass
with MyTrait
with MyOtherTrait {
</code></pre>
Inheritence is defined with the <tt>extends</tt> keyword. Like Java, Scala only allows single inheritance, but you add define interfaces and mixins through the <tt>with</tt> keyword.
<div class="fragment">
Objects can also use the <tt>extends</tt> and <tt>with</tt> keywords.
</div>
</section>
<section>
<pre><code class="scala">
trait MyTrait {
...
}
</code></pre>
<p>Traits are (almost) like what Java calls interfaces.</p>
<p>Unlike Java, a trait can define methods with implementations.</p>
</section>
<section>
<pre><code class="scala">
sealed trait MyTrait {
...
}
</code></pre>
<p>Sealed traits can only be extended/with-ed within the same file.</p>
</section>
<section>
<pre><code class="scala">
val message: String = "Hello World"
</code></pre>
<p>Variables are defined by the <tt>val</tt> or <tt>var</tt> keywords. <tt>val</tt> variables are immutable (like Java's <tt>final</tt> keyword).</p>
<p>Anywhere a variable is declared, it <u>may</u> be followed by a colon and a type. If omitted, Scala will guess.</p>
<p class="final">Generally prefer to use <tt>val</tt> wherever you can.</p>
</section>
<section>
<pre><code class="scala">
args: Array[String]
</code></pre>
Generic types use square brackets (<tt>[]</tt>). This is like Java's angle brackets (<tt>&lt;&gt;</tt>)
</section>
<section>
<pre><code class="scala">
def main(args: Array[String]): Unit = {
</code></pre>
<p>Define functions with the <tt>def</tt> keyword.</p>
<p class="fragment">The Colon-Type syntax is used to define the return type. <tt>Unit</tt> is like Java's <tt>void</tt>.</p>
<p class="fragment">The last line of the function will be returned by default, but you can use <tt>return</tt> to return a value sooner.</p>
<p class="fragment">Don't forget the <tt>=</tt></p>
</section>
<section>
<pre><code class="scala">
for(line <- stream.getLines){
...
}
</code></pre>
This is scala's iterator syntax (Like Java's <tt>for(line : stream.getLines</tt>)
<div class="fragment">
<pre><code class="scala">
stream.getLines.foreach { line =>
...
}
</code></pre>
This is another way to write the same thing. <br/>
<tt>{ line => ... }</tt> is a <b>lambda</b> function <br/>
with <tt>line</tt> as a parameter.
</div>
</section>
<section>
<pre><code class="scala">
class Foo(bar: String) {
def apply(baz: String): String =
{ bar + " " + baz }
}
</code></pre>
The special function <tt>apply</tt> is used to let a class instance (or object) pretend to be a function.
<pre><code class="scala">
val myFoo = new Foo("Abe")
val result = myFoo("Lincoln")
println(result)
</code></pre>
prints <tt>Abe Lincoln</tt>
</section>
</section>
<section>
<section>
<h3>Collections</h3>
<p>Scala has a robust library of collection types. Collections are usually referenced by their role.</p>
<p>Collections are immutable by default, and already in the namespace (no more import <tt>java.util.*</tt>).</p>
<p class="fragment">Mutable collections live in the <tt>collections.mutable</tt> package if needed.</p>
</section>
<section>
<ul style="font-size: 80%">
<li><tt>Seq[T]</tt>: An ordered sequence of items of type <tt>T</tt>.</li>
<li><tt>IndexedSeq[T]</tt>: An ordered sequence of items with O(1) access to individual elements of type <tt>T</tt>.</li>
<li><tt>Set[T]</tt>: An unordered collection of unique elements of type <tt>T</tt>.</li>
<li><tt>Map[K,V]</tt>: A map from unique keys of type <tt>K</tt> to values of type <tt>V</tt>.</li>
<li><tt>Iterator[T]</tt>: A stateful, usually non-repeatable traversal of some collection of elements of type <tt>T</tt></li>
<li><tt>Option[T]</tt>: A 0 or 1 element collection of type <tt>T</tt></li>
</ul>
</section>
<section>
For example <tt>List[T]</tt> and <tt>Array[T]</tt> are both <tt>Seq[T]</tt>, but only the latter is also an <tt>IndexedSeq[T]</tt>.
</section>
<section>
You almost never create collections of a specific type. The following all create collections:
<pre><code class="scala">
val seq = Seq[Int](1, 2, 3, 4)
val iseq = IndexedSeq[Int]("Alice", "Bolesław", "Coreline")
val map = Map(
"Cookie" -> "Chocolate Chip",
"Cake" -> "Red Velvet",
"Confection" -> "Gulab Jamun"
)
val opt = if(yes) { Some("A thing") } else { None }
</code></pre>
</section>
<section>
<p>Scala uses round brackets to access collection elements (remember <tt>apply</tt>?).</p>
<pre><code class="scala">
println(seq(1))
println(iseq(2))
println(map("Cookie"))
</code></pre>
prints <tt>2</tt>, <tt>Coreline</tt>, and <tt>Chocolate Chip</tt>
</section>
<section>
<h3>Tuples</h3>
<pre><code class="scala">
val a = (1, "Cookie", "Alice")
val b = (2, "Cake", "Bolesław")
val all = Seq(a, b)
</code></pre>
<p>Scala also has a "Tuple" type (like Python).</p>
<p>The type is also parenthesized. The elements above would have type <tt>(Int, String, String)</tt></p>
<p>Access elements of a tuple by <tt>a._1</tt>, <tt>a._2</tt>, and so forth. <br/>
For example <tt>all(1)._2</tt> is <tt>"Cake"</tt></p>
</section>
<section>
Hint: <tt>x -> y</tt> is shorthand for <tt>(x, y)</tt>. Use this with Map constructors.
</section>
<section>
<ul>
<li><tt>.map { v => ... }</tt>: Get a new collection by transforming every element of the collection using the lambda.</li>
<li><tt>.filter { v => ... }</tt>: Get a new collection by deleting every element of the collection on which the lambda returns false.</li>
<li><tt>.flatten</tt>: Assuming the target is a collection of collections, get a new collection by concatenating all of the nested collections.</li>
</ul>
</section>
<section>
<pre><code class="scala">
all.filter { x => x._2.equals("Cookie") }
.map { x => x._3 }
</code></pre>
Returns <tt>Seq("Alice")</tt>
</section>
<section>
<ul>
<li><tt>.foldLeft(x) { (accum, v) => ... }</tt>: Start with x. Apply the lambda to (x, firstElement) to get a new x. Repeat for every element of the target and return the final value of x.</li>
</ul>
</section>
<section>
<pre><code class="scala">
all.fold(0) { (accum, v) => accum + v._1 }
</code></pre>
Returns <tt>3</tt> (the sum of the first tuple field)
</section>
<section>
<h3>A Shorthand</h3>
<pre><code class="scala">
all.fold(0) { _ + _._1 }
</code></pre>
Underscores can <i>sometimes</i> be used as shorthands for lambda functions when a variable is only used once.
</section>
</section>
<section>
<section>
<pre><code class="scala">
foo match {
case "bar" => println("It was bar")
case "baz" => println("Baz be here")
case x => println("It was actually "+x+" the whole time!")
}
</code></pre>
<p><tt>match</tt> is like a <tt>switch</tt> statement in C/C++, or an <tt>elif</tt> chain in Python...</p>
<p class="fragment">... but far more powerful.</p>
</section>
<section>
<pre><code class="scala">
val longFoo = foo match {
case x:String => x.toLong
case y:Int => y * 100l
case _ => println("giving up!")
}
</code></pre>
You can match based on type.
</section>
<section>
<pre><code class="scala">
val longFoo = foo match {
case (x, y) => x.toLong
case y:Int => y * 100l
case _ => println("giving up!")
}
</code></pre>
You can match based on tuple nesting.
</section>
<section>
<h3>Case Classes</h3>
<pre><code class="scala">
case class Foo(a: String, b: Int)
case class Bar(foo: Foo, baz: String)
</code></pre>
<p>Case classes give you a bunch of stuff for "free"</p>
<pre><code class="scala">
val myFoo = Foo("Abe", 1)
</code></pre>
<p>For example, you don't need to use "new" to construct one.</p>
</section>
<section>
<pre><code class="scala">
val name = bar match {
case Foo(name, id) => name
}
</code></pre>
<p>But the big perk is that you can use them in match blocks.</p>
</section>
<section>
<pre><code class="scala">
val name = bar match {
case Bar(Foo(name, id), baz) => name
}
</code></pre>
<p>... even nested.</p>
</section>
<section>
<p>Scala uses case classes to make implementing union types easy.</p>
<pre><code class="scala">
sealed trait MyFooOrBar
case class Foo(a: String, b: Int) extends MyFooOrBar
case class Bar(foo: Foo, baz: String) extends MyFooOrBar
</code></pre>
<p>Scala's compiler will warn you if you have a match block for a sealed trait that doesn't match every possible case.</p>
</section>
</section>
<section>
<section>
<h3>SBT</h3>
<p>Scala relies on the <a href="https://www.scala-sbt.org/">Scala Build Tool</a> for compilation. It's similar to Maven.</p>
</section>
<section>
<ul>
<li><tt>build.sbt</tt>: Project definition</li>
<li><tt>src/</tt>: Source code <ul>
<li><tt>main/</tt>: Production code <ul>
<li><tt>scala/</tt>: Scala code <ul>
<li><tt>package/package/class.scala</tt></li>
</ul></li>
</ul></li>
<li><tt>test/</tt>: Testing code <ul>
<li><tt>scala/</tt>: Scala code <ul>
<li><tt>package/package/testClass.scala</tt></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
</section>
<section>
One class should have an <tt>object</tt> with a method defined as:
<tt>def main(args: Array[String])</tt>.
</section>
<section>
<h3>A simple <tt>build.sbt</tt></h3>
<pre><code>
name := "myproject"
version := "0.1"
organization := "edu.buffalo.cse.odin",
</code></pre>
</section>
<section>
<p>Many IDEs provide SBT integration. See the Scala <a href="https://docs.scala-lang.org/getting-started/index.html">Getting Started Page</a> and Scala <a href="https://scalameta.org/metals/">Metals Page</a> for more details.</p>
</section>
</section>

View file

@ -46,6 +46,8 @@
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*
* with edits (C) 2017-2021 Oliver Kennedy.
*/
/*********************************************
* GLOBAL STYLES
@ -157,6 +159,10 @@ body {
bottom: -10px;
text-align: right;
}
.reveal tt {
font-family: courier;
font-weight: bold;
}
/* Ensure certain elements are never larger than the slide itself */
.reveal img, .reveal video, .reveal iframe {