# Core Scala 2.x Masterclass

This is a great course that familiarises developers with The Scala Programming language.

This fresh and comprehensive course equips developers with all the tools necessary to function as a successful and productive team member on all Scala projects.

##### Prerequisites

Students should be familiar with another programming language such as Java, C#, C++, Rust, Javascript/Typescript, Python etc. Having knowledge of typed language will be beneficial.

##### Course Contents

We are aware that many teams and developers follow Scala courses using recorded session or perhaps live webinar type of training and even more so during pandemic and economic crises.

These kinds of courses are great for learning *products* and *easier concepts*. However, they don't lend
themselves to understanding new and often **difficult concepts** as they don't allow the ability to ask **your own questions**. Everybody is **unique**
in their ability to comprehend and understand new concepts. And everyone needs a **personalized approach**. In addition,
hearing questions/concerns from **other students** can help you tremendously. There might be ideas and answers you haven't
thought about. Even **without** you asking a question, an instructor on a live instructor-led course will see from **non-verbal communication** that a particular concept needs to be rephrased, needs a different diagram or example or needs to be revisited later.

EDC4IT has been working with Scala since the early 2000s, and has taught many teams.

We worked together with different teams on their projects.

This course covers:

- Introduction to Scala, tools and the language
- Using OO concepts
- Functional Programming with Scala
- Higher kinded Types
- Collections
- using and building ADTs
- Bundled Monads and Functors
- Error Handling
- Concurrency and Futures
- Type bounds and variance
- Implicits
- Type classes

This course is unique in:

- being not just example driven, but bringing a deeper understanding of the Scala language
- explaining concepts that are often challenging in a clear manner (illustrating many approaches to different issues with the help of useful diagrams)
- focusing on preparation for real-world projects (discussing real problems, caveats, best practices )

## Introduction

- Introduction to the Scala language
- Understand
**key features**of the language - Scala on the
**JVM** - Scala versions and Java Requirements
**Installing**Scala using*coursier*- List popular scala tools (sbt, ammonite, scalafmt, …)
- Introduction to the
**Scala REPL** - Using
**sbt**to setup a project

## Language Basics

- Explore
**lexical syntax** - Explore scala's
**literal values** - Understand basic
**declarations and definitions**(`var`

,`val`

and`def`

) - Declaring and using
**variables** - Understand
**basic types**(Integers, floating point, …) - Types with fixed cardinality (
`Nothing`

,`Null`

,`Unit`

and`Boolean`

) - Working with
**Strings**

### Method and functions

- Explore the
**methods**syntax - Understand aspects such as
**multiple parameter clauses**,**default values**,**repeated parameters** - Appreciate type
**inference** - Understand
**function application**("calling" functions) Explore more

**expressions**(e.g,`if`

-expressions)

### Recursion

- Use
**recursion**to problems - Learn how to
**recognise**recursive solutions - Recursion and the stack
- Explain
*tail-call*, its elimination and in particular**tail recursive**

## Classes, Objects and Traits

- Understand scala's hierarchy (
`Any`

,`AnyVal`

) - Understand the
**bottom types**`Nothing`

and`Null`

- Understand
**equality** - Understand the difference between
**objects, classes and traits** - Understand the difference between
**instances and objects**

### Classes

- Be able to
**define classes** - Appreciate the
**access modifiers**and further qualification - Adding
**fields and properties** - Recap
**methods declarations** **infix notation**(and**symbolic**methods)- Define
**constructors**(primary and auxiliary) - Method
**overloading** - Define
**type aliases** - Understand class
**inheritance**(nominal sub-typing) - Be able to apply the
**Liskov Substitution Principle** Concepts such as

**abstract**members and**overriding**(methods and vals)

### Objects

- Define
**Objects**in Scala - Understand the concepts of
**Companion Objects**and their typical use - Understand the
**apply**and**unapply**methods

### Case classes

- Appreciate
**case classes** - Discuss
**immutability** - "updating" objects and
**immutability** - Understand
**use-cases**for case classes

### Value Classes

- Define
**value classes** - Why you should not use
**simple types**(String, Int etc) - Understand caveats with value classes

### Packages

- Organise classes/objects in
**packages** - Discuss different styles of
**importing**packages and classes/objects - Appreciate the
**package object** - Organising your code

## Traits

- Introduce traits
- Discuss the principle of
**mix-ins** - Different ways of mixing in traits
- Use traits to enrich interfaces of of other types
- Discuss
**sealed types** - Traits vs
**abstract classes**, when to use which - Understand the
**linearisation**process - Solve
**conflicts** - Understand the
**stackable trait**pattern

### Type Constructors (Introduction)

- Understand the different
**kind of types** - What are
**higher-kinded**types - Appreciate
**type constructors** - Mixin traits with type constructors (e.g,
`Ordered`

)

## Functions

### Theory

- Understand
**domain**,**codomain**and and**image**of a function - Discuss different type of functions:
**injective**,**Surjective**,**Bijective**and**Partial** - Understand the
**arity**of a function - Properties of a function
Functions as

**values**

### Functions in Scala Introduction

- Defining
**functions** - Difference between
**functions and methods** - Use methods on functions (
`compose`

, ...) - The
**function literal**syntax - The
**function type literal**syntax - Use
**Lambda expressions** - Using methods as functions (
**η/eta-expansion**) - Functions as
**objects**(e.g,`Function0`

,`Function1`

, …) - Function
**composition**

### High-order function

- Understand the concept of
**Higher order functions** - Accepting functions and parameters
- returning functions from functions
- Understand
**clojures** - Discuss various use cases
- Using
**placeholder**syntax (understand the expansion) - Understand
**by name**paramaters

### Currying

- Appreciate
**currying**(methods and functions) - Discuss use-cases
- Use
**partial function application** - Using
**optional partial application**

## Types and ADTs

- Rethink the concepts of Types
- Types (e.g, case classes) and their
**cardinality** - Introduction to Algebraic Data Types (
**ADTs**) - Understand the concept of
**product types** - Introduce
**Pairs**and their projections - Introduce
**coproducts**(aka**sum types**) - Defining
**coproducts** **Algebra**with product types- A categorical view of ADTs
- Parametrised ADTs
- Mention and discuss Generalized algebraic data types (
**GADT**) - Discuss various ways to build
**enumerated**values in Scala

### Pattern Matching

- Introduce the power of pattern matching
- Understand
**various patterns** - Understand the role of
**case classes** - Build
**extractors** - Understand
**sealed traits** - Pattern matching on ADTs
- Understand pattern matching in value definitions
- Introduce the concept of
**Partial Functions**

### Optional Values

- How to abstract the
**absents of a value** - Problem with using a bottom values such as
**null** - Using the
**Option ADT** - Using
`Option`

in your programs - How to use option with
**side-effects** - Using option as a
**Functor**(mapping with`map`

) - Using option as a
**Monad**(sequentially compose using`flatmap`

) - Introduce
**for-comprehensions** - Adding
**definitions**and**guards**

## Collections

### Introduction

- Understand the type hierarchy (
`IterableOnce`

,`Iterable`

etc) - Understand the collection's architecture
- Understand the role of
**ops**types (e.g,`IterableOnceOps`

) - Mutable and immutable collections
- Creating collection instances
- Collections and
**equality** **Ordering**collections- Integrating with JVM collections
- Using
**for-comprehensions**on collections

### IterableOnce and Iterable

- Using collections as functors (mapping using
`map`

) **Getting**elements from the collection**Finding**and**Filtering**elements- Using partial functions to
**collect**elements **Adding**elements to a collection**Splitting**and**combining**collections

### Seq

- Working with indexed collections
**Searching**for elements**Adding**to the head or the tail**Replacing**elements**Sorting**indexed collections**Comparing**and using**set-operations**on collections- Discuss implementation and each of their benefits
- When to use
**Vector**,**List**and other implementations - Discuss
**performance**consideration (operations and big-O)

### List as a GADT

- Understand concepts such as
**head**,**tail**,**Cons**,**init**, … - Using
**Cons**to construct a list **Pattern matching**Lists

### Sets and Maps

- Working with
**Sets** - Performing set operations (intersection, union, …)
**Adding and removing**set elements- List various implementations and their benefits (
`TreeSet`

,`HashSet`

, …) - Discuss different algorithms and their performance
- Using
**Map** **getting**,**updating**and**iterating**over maps- Map implementations (
`TreeMap`

,`HashMap`

, …) and their**perforce**

### Folding and Reducing

- Using
**reduction** - Using associative
**folds**using monoidal reduction - Using linear fold using an
**initial value** - Understand the difference between
**reduce and fold** - Understand the role of the
**natural element**in folds - The difference between
**fold, foldRight and foldLeft** - When to use which
- Using
**scan**

## Core effects

### Errors

- Understand Errors and
**exceptions**on the JVM - Using JVM exception in Scala
- Using the
**Try**ADT instead - Working with the Try ADT as a functor (
`map`

) **composing**using`flatmap`

- Translating to other ADTs
- Discuss the various ways of
**recovery** - Using the
**Either**ADT - Using
`Either`

as an**alternative**for errors - Building your own
**error ADT** - Translating errors.

### Concurrency and Futures

- Understand the difference between
**concurrency and Parallelism** - Understand
**JVM Threads**and its**pools** - Using
**Futures**for concurrency - Understand the role of the
**Execution Context** **Lifting**values into a`Future`

- Using
`Future`

as a functor/monad - Working with
**side-effects**after completion - Handling and recovering from
**failures** **Combing**futures (fold, zip, …)- Appreciate
**Traverse**and**Sequence**

## Types

- Recap
**Higher kinded**types - Introduce
**polymorphic methods** - Type bounds (
**Upper**,**Lower**and**Context**) - Introduce the concept of
**variance** - Learn when to use
**covariance or contravariance** - When to keep types
**invariant** - Understand covariance or contravariance
**positions** - When to use
**Lower Bounds** - Introduce
**Abstract Type Definitions** - Using Abstract Type Definitions to solve different problems
- Using
**Path Dependent types** **Refinement types**and**Structural types****Caveats**of using Structural types- Using
**Self Types** - Using self types for
**dependency injection**(DI) - Discuss
**DI alternatives**

## Implicits

- Understand the concept of the
**implicit context** - Understand the
**rules**for brining in implicits into**scope** - Appreciate priorisating of implicits
- Define
**low priority**implicits **Best practices**for implicits- Use
**implicit conversions**to convert types - Use
**implicit classes**to enrich types (extension methods) - Use
**implicit params**as contextual parameters

### Type classes

- Understand the limitations of
**subtype polymorphism** - Introduce the concept of
**ad-hoc**polymorphism**Type classes** - What makes up a type class in Scala?
**Define**a type class- Provide
**instances** - Add an
**interface**(object and/or**syntax**) **Summoning**implicates in the current context- Using
**Context Bounds**