{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "
\n",
"object Example {\n",
" \n",
" abstract class Tree\n",
" case class Branch(left: Tree, right: Tree) extends Tree\n",
" case class Leaf(x: Int) extends Tree\n",
"\n",
" val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4)))\n",
"\n",
" def sumLeaves(t: Tree): Int = t match {\n",
" case Branch(l, r) => sumLeaves(l) + sumLeaves(r)\n",
" case Leaf(x) => x\n",
" }\n",
"\n",
" println(\"sum of leafs=\" + sumLeaves(tree1)) \n",
"}\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Basics of Scala\n",
"\n",
"Slides are loosely based on \n",
"* [Essential scala](https://underscore.io/training/courses/essential-scala/) the delightful and free book on Scala\n",
"* [Essential essential Scala](https://github.com/underscoreio/eescala) (online slides)\n",
"by Noel Welsh and Dave Gurnell.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Expressions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Expressions are program text\n",
"* Expressions evaluate to values\n",
"* Expressions have a type"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"(5 + 3) * 8"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"List(1,2,3).toString\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Values\n",
"\n",
"* Expressions can be named using ```val```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val myCalculation = (5 + 3) * 8 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val myExtendedCalculation = myCalculation * 10"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Types\n",
"\n",
"* Every expression has a type"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val a : Int = (5 + 3) * 8"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val b = ((5 + 3 ) * 8).toString"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val c : String = (5 + 3 ) * 8"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Expression, types and values\n",
"\n",
"![expression-types-values](./images/expression-types-values.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Blocks\n",
"\n",
"* Sequence of expressions\n",
"* Last line is result of block \n",
" * Block is itself expression"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"{\n",
" val x = 1 + 1\n",
" x + 1\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Blocks\n",
"\n",
"* Blocks are expressions - can be named"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"val result = {\n",
" val x = 1 + 1\n",
" x + 1\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Blocks \n",
"\n",
"* Can be placed everywhere an expression is required"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"println( { val x = 1 + 1\n",
" x + 1} ) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Functions\n",
"\n",
"* Expressions that take parameter\n",
"\n",
"![functions](./images/functions.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Functions "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"(x : Int) => x + 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Function body can be a block (as block is expression)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[36mres5\u001b[39m: \u001b[32mInt\u001b[39m => \u001b[32mInt\u001b[39m = ammonite.$sess.cmd5$Helper$$Lambda$3763/1257149155@7b903bac"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(x : Int) => {\n",
" val y = 1\n",
" x + y\n",
"} \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Functions\n",
"\n",
"* Functions are expressions, hence values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"val f = (x : Int) => {\n",
" val y = 1\n",
" x + y\n",
"} \n",
"\n",
"f(3)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Types of a function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Type of a function\n",
" * ```A => B```: map a value of type ```A``` to a value of type ```B```"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[36mf\u001b[39m: \u001b[32mInt\u001b[39m => \u001b[32mInt\u001b[39m = ammonite.$sess.cmd6$Helper$$Lambda$3767/474480687@1ceb390c"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val f : Int => Int = (x : Int) => {\n",
" val y = 1\n",
" x + y\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Exercises\n",
"\n",
"* Create the function ```square``` which takes a number ```x``` (of type ```Double```) and returns $x \\cdot x$.\n",
"* Create a function ```sumOfSquares``` which takes two arguments ```x``` and ```y``` and returns $x^2 + y^2$.\n",
"* Can you create a function ```apply twice```, which takes a function ```f``` of type ```Double => Double``` and a number ```x``` of type ```Double``` as parameters and returns ```f(f(x)```?\n",
"* Can you create a function ```compose```, which takes two functions $f$ and $g$ as a parameter and returns the composition of f and g, i.e. $f \\circ g := f(g(x))$?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Methods\n",
"\n",
"\n",
"![methods](./images/methods.png)\n",
"\n",
"> Similar to functions, but with special syntax"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"def add(x : Int, y : Int) = x + y\n",
"\n",
"add(5, 3)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Classes\n",
"\n",
"* Similar to Java \n",
" * Main difference: Argument list as constructor\n",
" * ```val ``` before argument: variable is public"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"defined \u001b[32mclass\u001b[39m \u001b[36mMyClass\u001b[39m"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"class MyClass(field1 : String, val field2 : Int) {\n",
" def printOut() : Unit = {\n",
" println(field1 + \", \" +field2)\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"abc, 5\n"
]
},
{
"data": {
"text/plain": [
"\u001b[36mmyClass\u001b[39m: \u001b[32mMyClass\u001b[39m = ammonite.$sess.cmd14$Helper$MyClass@6b4fac02"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val myClass = new MyClass(\"abc\", 5)\n",
"myClass.printOut()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Case classes\n",
"\n",
"* Special classes for organizing data\n",
" * Ensure proper equality\n",
" * Do not need new keyword\n",
" * constructor arguments are public by default"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"case class Point(x : Double, y : Double)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"val p = Point(3, 5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Objects\n",
"\n",
"* Whenever only a single instance is needed\n",
"* Often associated to class with same name\n",
" * Called *companion object*\n",
" \n",
"```scala\n",
"class PositiveNumber(num : Int) { \n",
" // some methods\n",
"}\n",
"\n",
"object PositiveNumber {\n",
" val MaxValue : Int = java.lang.Integer.MAX_VALUE\n",
" val MinValue : Int = 0\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Exercises:\n",
"\n",
"* Create a class ```Vector2D```, which represents a vector in two dimensional space.\n",
" * Implement the method ```plus```, which adds two vectors and returns a new vector. \n",
" * Implement the method ```dot```, which computes the scalar product\n",
" * Create two instances of the Vector $(0, 1)$ and compare them for equality. \n",
" * Define the class once as a case class and once as a normal class. What is the difference?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Parametric types\n",
"\n",
"> Types in Scala can be parametric\n",
"\n",
"```scala\n",
"case class Pair[A, B](first : A, second : B)\n",
"```\n",
"\n",
"Usage:\n",
"```scala\n",
"val pair1 = Pair(3, 5.0) \n",
"val pair2 : Pair[String, Int] = Pair(\"abc\", 5)\n",
"```\n",
"\n",
"\n",
"* Types are inferred automatically when possible\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Parametric types\n",
"\n",
"> Methods can be parametric\n",
"\n",
"```scala\n",
"def first[A, B](pair : Pair[A, B]) : A = pair.first\n",
"\n",
"val pair = Pair(3, 5.0)\n",
"first(pair)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Pattern matching\n",
" \n",
" * Generalizes switch/case statement from java\n",
" \n",
"```scala\n",
"expression match { \n",
" case pattern1 => expression1 \n",
" case pattern2 => expression2 \n",
" // ...\n",
"}\n",
"```\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Pattern matching"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[36mres\u001b[39m: \u001b[32mAny\u001b[39m = \u001b[32m\"two\"\u001b[39m"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"val res = 2 match { \n",
" case 1 => \"one\" \n",
" case 2 => \"two\" \n",
" case _ => 5\n",
"} "
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"defined \u001b[32mfunction\u001b[39m \u001b[36mmatchTest2\u001b[39m\r\n",
"\u001b[36mres20_1\u001b[39m: \u001b[32mInt\u001b[39m = \u001b[32m55\u001b[39m"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def matchTest2(x: Any): Int = x match { \n",
" case 1 => 1\n",
" case \"two\" => 2 \n",
" case y: Int => y\n",
" case _ => 99\n",
"} \n",
"matchTest2(55)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Next time - Scala, the simple parts\n",
"\n",
"> How these concepts fit together"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Scala",
"language": "scala",
"name": "scala"
},
"language_info": {
"codemirror_mode": "text/x-scala",
"file_extension": ".sc",
"mimetype": "text/x-scala",
"name": "scala",
"nbconvert_exporter": "script",
"version": "2.13.1"
},
"livereveal": {
"transition": "none"
}
},
"nbformat": 4,
"nbformat_minor": 2
}