├── .gitignore ├── Colls-Array └── CollsArray.sc ├── Colls-ArrayBuffer-Access-Update └── CollsArrayBufferAccessUpdate.sc ├── Colls-ArrayBuffer-Add-Elements └── CollsArrayBufferAdd.sc ├── Colls-ArrayBuffer-Initially-Populate └── CollsArrayBufferInitiallyPopulate.sc ├── Colls-ArrayBuffer-Other-Methods └── CollsArrayBufferOtherMethods.sc ├── Colls-ArrayBuffer-Remove-Elements └── CollsArrayBufferRemoveElements.sc ├── Colls-ArrayBuffer └── CollsArrayBuffer.sc ├── Colls-Combine-map-filter └── CollsCombineMapFilter.sc ├── Colls-Even-More-Sequence-Methods └── EvenMoreSequenceMethods.sc ├── Colls-List-Updating-Elements └── CollsListUpdatingElements.sc ├── Colls-List └── CollsList.sc ├── Colls-Map-Adding-Elements └── CollsMapAdding.sc ├── Colls-Map-Class └── CollsMap.sc ├── Colls-Map-Common-Methods └── CollsMapCommonMethods.sc ├── Colls-Map-Deleting-Elements └── CollsMapDeletingElements.sc ├── Colls-Map-How-To-Loop-Over └── CollsMapHowToLoopOver.sc ├── Colls-Map-Updating-Elements └── CollsMapUpdatingElements.sc ├── Colls-More-Sequence-Methods └── CollsMoreSequenceMethods.sc ├── Colls-Other-Sequence-Classes └── CollsOtherSequenceClasses.sc ├── Colls-Ranges-Creating-Collections-From-Ranges └── CollsCreatingFromRanges.sc ├── Colls-Ranges └── CollsRange.sc ├── Colls-Set └── CollsSet.sc ├── Colls-filter-Method └── CollsFilterMethod.sc ├── Colls-foreach-Method-Anon-Functions └── CollsForeachMethod.sc ├── Colls-map-Method └── CollsMapMethod.sc ├── Constructs-Add-if-for-Expressions └── ConstructsAddIfToForExpressions.sc ├── Constructs-for-Expressions-Mult-Generators └── ForExpressionsMultipleGenerators.sc ├── Constructs-for-Expressions └── ConstructsForExpressions.sc ├── Constructs-for-Loops └── ConstructsForLoops.sc ├── Constructs-match-Expressions-More-Details └── ConstructsMatchExpressionsMoreDetails.sc ├── Constructs-match-Expressions └── ConstructsMatchExpressions.sc ├── Constructs-while-Loop └── ConstructsWhileLoop.sc ├── DM-An-OOP-Domain-Modeling-Example ├── OOPExample1.sc └── OOPExample2.sc ├── DM-Case-Classes └── CaseClasses.sc ├── DM-Classes-1-Constructors └── Classes1Constructors.sc ├── DM-Classes-2-Adding-Members-and-Getters └── Classes2AddingMembersGetter.sc ├── DM-Classes-3-Adding-Setters └── Classes3AddingSetters.sc ├── DM-Classes-Auxiliary-Constructors └── ClassesAuxiliaryConstructors.sc ├── DM-Classes-Default-Constructor-Parameters └── ClassesDefaultConstructorParameters.sc ├── DM-Enums-More-Details └── EnumsMoreDetails.scala ├── DM-Enums ├── Enums1.scala └── Enums2.sc ├── DM-Objects-1-Singletons ├── ObjectsSingletons1.scala └── ObjectsSingletons2.sc ├── DM-Objects-2-Companion-Objects └── CompanionObjects.scala ├── DM-Objects-3-apply-Methods └── ObjectsApplyMethods.sc ├── DM-Traits-Adding-Behaviors └── TraitsAddingBehaviors.sc ├── DM-Traits-Using-As-Interfaces └── TraitsAsInterfaces.sc ├── DM-Union-Types └── UnionTypes.sc ├── Domain-Modeling └── DomainModeling.sc ├── EOP └── EOP.sc ├── Examples-Command-Line-IO ├── CmdLine.sc └── NameAndAge.sc ├── Examples-HTTP ├── HttpGet.scala └── HttpPost.scala ├── Examples-Swing └── Swing.scala ├── Examples-Timer └── timer.sc ├── Examples-TryCatchFinally └── TryCatchFinally.scala ├── Explicit-Data-Type └── ExplicitDataTypes.sc ├── Extras └── ReadCsvFile.scala ├── Functions-Creating-main-Method ├── Hello.scala └── HelloParameters.scala ├── Functions-Defaults-For-Function-Parameters └── FunctionsDefaultsForFunctionParameters.sc ├── Functions-Functional-Error-Handling-2 └── FunctionalErrorHandling.sc ├── Functions-Handling-Variable-Number-Parameters └── FunctionsVarargs.sc ├── Functions-Named-Parameters └── FunctionsNamedParameters.sc ├── Functions-Options-and-Functional-Error-Handling └── FunctionsOptions.sc ├── Functions └── Functions.sc ├── Importing-Code-With-import └── Imports.sc ├── Learn-Scala-3-The-Fast-Way-small.jpg ├── Math-Expressions └── MathExpressions.sc ├── Numeric-Data-Types └── NumericDataTypes.sc ├── README.md ├── Scala-REPL └── repl.sc ├── Strings-Common-Methods └── StringMethods.sc ├── Strings-Interpolators └── StringInterpolators.sc ├── Strings-Multiline └── StringsMultiline.sc ├── Tests ├── P1.sc └── PrintAll.sc ├── TryCatchFinally └── TryCatchFinally.sc ├── TryCatchFinally2 └── TryCatchFinally2.sc ├── Tuples └── Tuples.sc ├── Using-Scala-CLI ├── Hello.scala ├── HelloWorld.sc ├── MyScript.sc └── PrintAll.sc ├── if-then-else └── IfThenElse.sc ├── println └── Println.sc ├── val-fields └── ValFields.sc └── var-fields └── VarFields.sc /.gitignore: -------------------------------------------------------------------------------- 1 | *.wav 2 | *.DS_Store 3 | *.class 4 | *.jar 5 | .bsp/ 6 | .scala-build/ 7 | -------------------------------------------------------------------------------- /Colls-Array/CollsArray.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArray.sc 5 | 6 | "foo bar".split(" ") // Array(foo, bar) 7 | 8 | "foo bar".split(" ").toList // List(foo, bar) 9 | 10 | "foo bar".split(" ").toVector // Vector(foo, bar) 11 | 12 | "foo bar".split(" ").toBuffer // ArrayBuffer(foo, bar) 13 | 14 | 15 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer-Access-Update/CollsArrayBufferAccessUpdate.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBufferAccessUpdate.sc 5 | 6 | 7 | import scala.collection.mutable.ArrayBuffer 8 | 9 | 10 | val names = ArrayBuffer("Bert", "Ernie", "Grover") 11 | println(names(0)) // prints "Bert" 12 | println(names(1)) // prints "Ernie" 13 | println(names(2)) // prints "Grover" 14 | 15 | for name <- names do println(name) 16 | names.foreach(println) 17 | 18 | 19 | // update the elements 20 | names(0) = "BERT" 21 | names(1) = "ERNIE" 22 | names(2) = "GROVER" 23 | names.foreach(println) 24 | 25 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer-Add-Elements/CollsArrayBufferAdd.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBufferAdd.sc 5 | 6 | import scala.collection.mutable.ArrayBuffer 7 | 8 | val ints = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3) 9 | ints += 4 // ArrayBuffer(1, 2, 3, 4) 10 | ints ++= List(5, 6) // ArrayBuffer(1, 2, 3, 4, 5, 6) 11 | ints ++= Vector(7, 8) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8) 12 | 13 | 14 | // More methods you can use 15 | 16 | val a = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3) 17 | a.append(4) // ArrayBuffer(1, 2, 3, 4) 18 | a.appendAll(List(5, 6)) // ArrayBuffer(1, 2, 3, 4, 5, 6) 19 | 20 | a.clear // ArrayBuffer() 21 | a += 9 // ArrayBuffer(9) 22 | a.append(10) // ArrayBuffer(9, 10) 23 | a.prepend(7) // ArrayBuffer(7, 9, 10) 24 | 25 | a.insert(0, 6) // ArrayBuffer(6, 7, 9, 10) 26 | a.insert(2, 8) // ArrayBuffer(6, 7, 8, 9, 10) 27 | a.insertAll(0, Vector(4, 5)) // ArrayBuffer(4, 5, 6, 7, 8, 9, 10) 28 | a.prependAll(List(2, 3)) // ArrayBuffer(2, 3, 4, 5, 6, 7, 8, 9, 10) 29 | 30 | 31 | // A note about 'for' loops 32 | 33 | { 34 | val ints = ArrayBuffer[Int]() 35 | for i <- 1 to 5 do ints += i 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer-Initially-Populate/CollsArrayBufferInitiallyPopulate.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBufferInitiallyPopulate.sc 5 | 6 | import scala.collection.mutable.ArrayBuffer 7 | 8 | 9 | ArrayBuffer.range(1, 3) // ArrayBuffer(1, 2) 10 | ArrayBuffer.range('a', 'c') // ArrayBuffer(a, b) 11 | 12 | ArrayBuffer.range(1, 6, 2) // ArrayBuffer(1, 3, 5) 13 | 14 | List.range(1, 3) // List(1, 2) 15 | Vector.range(1, 3) // Vector(1, 2) 16 | 17 | 18 | // Using 'to' and 'until' 19 | 20 | (1 to 3).toBuffer // ArrayBuffer(1, 2, 3) 21 | (1 until 3).toBuffer // ArrayBuffer(1, 2) 22 | 23 | ('a' to 'c').toBuffer // ArrayBuffer('a', 'b', 'c') 24 | ('a' until 'c').toBuffer // ArrayBuffer('a', 'b') 25 | 26 | 27 | (1 to 5 by 2).toBuffer // ArrayBuffer(1, 3, 5) 28 | (1 until 5 by 2).toBuffer // ArrayBuffer(1, 3) 29 | 30 | (1 to 5).by(2).toBuffer // ArrayBuffer(1, 3, 5) 31 | (1 until 5).by(2).toBuffer // ArrayBuffer(1, 3) 32 | 33 | 34 | ('a' to 'f').by(2).toBuffer // ArrayBuffer('a', 'c', 'e') 35 | 36 | 37 | // 'to' and 'until' are just methods 38 | 39 | (1 to 5).toBuffer 40 | (1 to 5 by 2).toBuffer 41 | 42 | 1.to(5).toBuffer 43 | 1.to(5).by(2).toBuffer 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer-Other-Methods/CollsArrayBufferOtherMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBufferOtherMethods.sc 5 | 6 | 7 | import scala.collection.mutable.ArrayBuffer 8 | 9 | 10 | // map 11 | { 12 | val a = ArrayBuffer(1, 2, 3) 13 | val b = a.map(_ * 2) // b: ArrayBuffer(2, 4, 6) 14 | } 15 | 16 | { 17 | var a = ArrayBuffer(1, 2, 3) 18 | a = a.map(_ * 2) // a: ArrayBuffer(2, 4, 6) 19 | } 20 | 21 | 22 | // mapInPlace 23 | { 24 | val a = ArrayBuffer(1, 2, 3) 25 | a.mapInPlace(_ * 2) // ArrayBuffer(2, 4, 6) 26 | } 27 | 28 | 29 | // filter and filterInPlace 30 | { 31 | // filter 32 | val a = ArrayBuffer(1, 2, 3, 4, 5) 33 | val b = a.filter(_ > 2) // ArrayBuffer(3, 4, 5) 34 | } 35 | 36 | { 37 | // filterInPlace 38 | val a = ArrayBuffer(1, 2, 3, 4, 5) 39 | a.filterInPlace(_ > 2) // ArrayBuffer(3, 4, 5) 40 | } 41 | 42 | 43 | // Other functional methods 44 | { 45 | val a = ArrayBuffer.range(0, 5) // ArrayBuffer(0, 1, 2, 3, 4) 46 | val b = a.drop(2) // b: ArrayBuffer(2, 3, 4) 47 | val c = a.dropWhile(_ < 3) // c: ArrayBuffer(3, 4) 48 | val d = a.take(2) // d: ArrayBuffer(0, 1) 49 | val e = a.takeWhile(_ < 3) // e: ArrayBuffer(0, 1, 2) 50 | } 51 | 52 | { 53 | val a = ArrayBuffer.range(0, 4) // ArrayBuffer(0, 1, 2, 3) 54 | val f = a.toList // f: List(0, 1, 2, 3) 55 | val g = a.toVector // g: Vector(0, 1, 2, 3) 56 | } 57 | 58 | 59 | // trimStart, trimEnd, reduceToSize 60 | { 61 | val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g) 62 | a.trimStart(2) // ArrayBuffer(c, d, e, f, g) 63 | a.trimEnd(2) // ArrayBuffer(c, d, e) 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer-Remove-Elements/CollsArrayBufferRemoveElements.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBufferRemoveElements.sc 5 | 6 | import scala.collection.mutable.ArrayBuffer 7 | 8 | 9 | { 10 | val a = ArrayBuffer.range('a', 'g') // ArrayBuffer(a, b, c, d, e, f) 11 | a -= 'a' // ArrayBuffer(b, c, d, e, f) 12 | 13 | a --= List('b', 'c') // ArrayBuffer(d, e, f) 14 | a --= Vector('e', 'f') // ArrayBuffer(d) 15 | } 16 | 17 | 18 | // Other methods 19 | 20 | { 21 | val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g) 22 | a.clear // ArrayBuffer[Char] = ArrayBuffer() 23 | } 24 | 25 | val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g) 26 | a.remove(0) // ArrayBuffer(b, c, d, e, f, g) 27 | a.remove(2, 3) // ArrayBuffer(b, c, g) 28 | 29 | // remove can throw exceptions 30 | a.clear // clears 'a' so it contain no elements 31 | a.remove(0) // ERROR: java.lang.IndexOutOfBoundsException 32 | a.remove(100, 10) // ERROR: java.lang.IndexOutOfBoundsException 33 | 34 | 35 | -------------------------------------------------------------------------------- /Colls-ArrayBuffer/CollsArrayBuffer.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsArrayBuffer.sc 5 | 6 | 7 | import scala.collection.mutable.ArrayBuffer 8 | 9 | val strings = ArrayBuffer[String]() 10 | val ints = ArrayBuffer[Int]() 11 | 12 | 13 | val ints1 = new ArrayBuffer[Int](100_000_000) 14 | 15 | 16 | val names = ArrayBuffer("Bert", "Ernie", "Grover") 17 | names.foreach(println) 18 | -------------------------------------------------------------------------------- /Colls-Combine-map-filter/CollsCombineMapFilter.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsCombineMapFilter.sc 5 | 6 | 7 | val colors = List("red", "blue", "yellow", "green", "purple") 8 | 9 | // 1st example 10 | val result = colors.filter(_.length < 5) 11 | .map(_.toUpperCase) 12 | println(result) 13 | 14 | 15 | // 2nd example 16 | val result1 = colors.filter(_.length < 5) 17 | val result2 = result1.map(_.toUpperCase) 18 | println(result2) 19 | 20 | 21 | // 3rd example 22 | { 23 | val colors: List[String] = List( 24 | "red", "blue", "yellow", "green", "purple" 25 | ) 26 | 27 | // short solution 28 | val result: List[String] = colors.filter(_.length < 5) 29 | .map(_.toUpperCase) 30 | 31 | // longer solution 32 | val result1: List[String] = colors.filter(_.length < 5) 33 | val result2: List[String] = result1.map(_.toUpperCase) 34 | } 35 | 36 | 37 | // 4th example 38 | { 39 | val colors: List[String] = List( 40 | "red", "blue", "yellow", "green", "purple" 41 | ) 42 | 43 | val result = colors.filter(_.length < 5) 44 | .filter(_.startsWith("r")) 45 | .map(_.toUpperCase) 46 | 47 | println(result) 48 | } 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Colls-Even-More-Sequence-Methods/EvenMoreSequenceMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli EvenMoreSequenceMethods.sc 5 | 6 | 7 | val firstTen = (1 to 10).toList 8 | 9 | println(firstTen.contains(2)) 10 | println(firstTen.containsSlice(List(3,4,5))) 11 | println(firstTen.count(_ % 2 == 0)) 12 | println(firstTen.endsWith(List(9,10))) 13 | println(firstTen.exists(_ > 10)) 14 | println(firstTen.forall(_ < 20)) 15 | println(firstTen.indexWhere(_ == 3)) 16 | 17 | println(firstTen.max) 18 | println(firstTen.min) 19 | println(firstTen.sum) 20 | println(firstTen.product) 21 | 22 | println(firstTen.startsWith(List(1,2))) 23 | 24 | 25 | println(firstTen.count(_ % 2 == 0)) 26 | println(firstTen.count(i => i % 2 == 0)) 27 | 28 | 29 | -------------------------------------------------------------------------------- /Colls-List-Updating-Elements/CollsListUpdatingElements.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsListUpdatingElements.sc 5 | 6 | 7 | // note that i create blocks of code inside the 8 | // curly braces so i can reuse the variable names, 9 | // and then this code is the same as the book. 10 | { 11 | val a = List(1, 2, 3) 12 | val b = a :+ 4 // add one element 13 | val c = b ++ List(5, 6) // add multiple elements 14 | println(c) 15 | } 16 | 17 | 18 | { 19 | val a = List(2, 3) // List(2, 3) 20 | val b = 1 :: a // List(1, 2, 3) 21 | val c = 0 :: b // List(0, 1, 2, 3) 22 | println(c) 23 | } 24 | 25 | 26 | { 27 | val a = List(1, 2, 3, 4, 5) 28 | val b = a.filter(_ > 3) // b: List(4, 5) 29 | println(b) 30 | } 31 | 32 | 33 | { 34 | val a = List(1, 2, 3) 35 | val b = a.updated(0, 100) // b: List(100, 2, 3) 36 | val c = b.updated(1, 200) // c: List(100, 200, 3) 37 | println(c) 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /Colls-List/CollsList.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsList.sc 5 | 6 | 7 | // something new! putting code inside curly braces 8 | // creates a new “block” of code. code inside the 9 | // braces is in its own scope, so even though i use 10 | // the same variable names in this block as i do in 11 | // the next block, the code compiles because the 12 | // variables are within different scopes. you won’t 13 | // normally write code like this, but it’s great for 14 | // creating examples like these, because then i can 15 | // use the same variable names that are in the book. 16 | 17 | { 18 | // this block of code is in one scope 19 | val ints = List(1, 2, 3) 20 | val doubles = List(1.1, 2.2, 3.3) 21 | val names = List("Aleka", "Christina", "Alvin") 22 | } 23 | 24 | 25 | { 26 | // this block of code is in a different scope 27 | val ints: List[Int] = List(1, 2, 3) 28 | val doubles: List[Double] = List(1.1, 2.2, 3.3) 29 | val names: List[String] = List("Aleka", "Christina", "Alvin") 30 | } 31 | 32 | 33 | val list = List("a", "b", "c") 34 | println(list(0)) // prints a 35 | println(list(1)) // prints b 36 | println(list(2)) // prints c 37 | 38 | // these would be errors: 39 | // list += 4 // error 40 | // list(0) = 10 // error 41 | 42 | 43 | var xs = List(1, 2, 3) 44 | xs = xs ++ List(4, 5) 45 | println(xs) 46 | 47 | // you can also print the individual list 48 | // elements like this: 49 | xs.foreach(println) 50 | for x <- xs do println(x) 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Colls-Map-Adding-Elements/CollsMapAdding.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapAdding.sc 5 | 6 | val a = scala.collection.mutable.Map(1 -> "a") 7 | 8 | // adding elements 9 | a += (2 -> "b") // add using a tuple 10 | a ++= Map(3 -> "c", 4 -> "d") // add with another Map 11 | a ++= List(5 -> "e", 6 -> "f") // you can even add new pairs with a sequence 12 | 13 | println(a) 14 | 15 | 16 | a.clear 17 | println(a) 18 | 19 | a.clear 20 | a += (2 -> "b") 21 | println(a) 22 | 23 | 24 | -------------------------------------------------------------------------------- /Colls-Map-Class/CollsMap.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMap.sc 5 | 6 | 7 | // you get an immutable Map by default 8 | val peeps = Map( 9 | "first_name" -> "Alvin", 10 | "last_name" -> "Alexander" 11 | ) 12 | 13 | 14 | // Creating a mutable Map 15 | import scala.collection.mutable.Map 16 | 17 | val states = scala.collection.mutable.Map( 18 | "AL" -> "Alabama", 19 | "AK" -> "Alaska" 20 | ) 21 | 22 | 23 | // Accessing elements 24 | println(states("AL")) // prints "Alabama" 25 | println(states("AK")) // prints "Alaska" 26 | 27 | 28 | // Creating an empty Map 29 | val a = scala.collection.mutable.Map[Int, String]() 30 | 31 | 32 | // If Maps are difficult ... 33 | { 34 | val letters = List("a", "b", "c") 35 | letters(0) // "a" 36 | letters(1) // "b" 37 | letters(2) // "c" 38 | } 39 | 40 | { 41 | val letters = scala.collection.mutable.Map( 42 | 0 -> "a", 43 | 1 -> "b", 44 | 2 -> "c", 45 | ) 46 | letters(0) // "a" 47 | letters(1) // "b" 48 | letters(2) // "c" 49 | } 50 | 51 | { 52 | val letters = scala.collection.mutable.Map( 53 | 0.0 -> "a", 54 | 1.1 -> "b", 55 | 2.2 -> "c", 56 | ) 57 | } 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Colls-Map-Common-Methods/CollsMapCommonMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapCommonMethods.sc 5 | 6 | 7 | val map = collection.mutable.Map( 8 | 1 -> "one", 9 | 2 -> "two", 10 | 3 -> "three" 11 | ) 12 | map.filterInPlace((k,v) => k > 1) 13 | println(map) 14 | 15 | 16 | // mapValuesInPlace 17 | { 18 | val map = collection.mutable.Map( 19 | 1 -> "one", 20 | 2 -> "two", 21 | 3 -> "three" 22 | ) 23 | 24 | map.mapValuesInPlace((k,v) => v.toUpperCase) 25 | } 26 | 27 | 28 | // Other methods 29 | { 30 | val map = collection.mutable.Map( 31 | 1 -> "one", 32 | 2 -> "two", 33 | 3 -> "three" 34 | ) 35 | 36 | map.contains(1) // true (tests your value against the keys) 37 | map.count((k,v) => k > 1) // 2 38 | map.exists((k,v) => k == 1) // true 39 | map.isEmpty // false 40 | map.keys // Set(1, 2, 3) 41 | map.size // 3 42 | map.getOrElse(50, "fifty") 43 | } 44 | 45 | // clear 46 | { 47 | val map = collection.mutable.Map( 48 | 1 -> "one", 49 | 2 -> "two", 50 | 3 -> "three" 51 | ) 52 | 53 | // will be empty, with the type Map[Int, String]: 54 | map.clear 55 | println(map) 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /Colls-Map-Deleting-Elements/CollsMapDeletingElements.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapDeletingElements.sc 5 | 6 | // start with this Map 7 | val a = scala.collection.mutable.Map(1 -> "a") 8 | a += (2 -> "b") // add using a tuple 9 | a ++= Map(3 -> "c", 4 -> "d") // add with another Map 10 | a ++= List(5 -> "e", 6 -> "f") // you can even add new pairs with a sequence 11 | a(1) = "AA" 12 | a(2) = "BB" 13 | println(a) 14 | 15 | a -= 6 // remove one element, where the key is 6 16 | a --= List(4, 5) // remove multiple elements using a sequence 17 | println(a) 18 | 19 | -------------------------------------------------------------------------------- /Colls-Map-How-To-Loop-Over/CollsMapHowToLoopOver.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapHowToLoopOver.sc 5 | 6 | 7 | val shipmates = scala.collection.mutable.Map( 8 | "Captain" -> "Kirk", 9 | "1st Officer" -> "Spock", 10 | "Doctor" -> "McCoy" 11 | ) 12 | 13 | for (k, v) <- shipmates do println(s"key: $k, value: $v") 14 | 15 | 16 | // Updating a mutable Map in a loop 17 | { 18 | val shipmates = scala.collection.mutable.Map( 19 | "Captain" -> "Kirk", 20 | "1st Officer" -> "Spock", 21 | "Doctor" -> "McCoy" 22 | ) 23 | 24 | for 25 | (k, v) <- shipmates 26 | do 27 | shipmates(k) = v.toUpperCase 28 | 29 | for (k, v) <- shipmates do println(s"key: $k, value: $v") 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /Colls-Map-Updating-Elements/CollsMapUpdatingElements.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapUpdatingElements.sc 5 | 6 | 7 | // start with this Map 8 | val a = scala.collection.mutable.Map(1 -> "a") 9 | a += (2 -> "b") // add using a tuple 10 | a ++= Map(3 -> "c", 4 -> "d") // add with another Map 11 | a ++= List(5 -> "e", 6 -> "f") // you can even add new pairs with a sequence 12 | 13 | println(a(1)) 14 | 15 | a(1) = "AA" 16 | println(a(1)) 17 | 18 | a(2) = "BB" 19 | println(a) 20 | 21 | -------------------------------------------------------------------------------- /Colls-More-Sequence-Methods/CollsMoreSequenceMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMoreSequenceMethods.sc 5 | 6 | 7 | val a = List(10, 20, 30, 40, 10) 8 | 9 | println(a.filter(_ < 25)) 10 | println(a.filter(_ > 100)) 11 | println(a.filterNot(_ < 25)) 12 | 13 | println(a.drop(2)) 14 | println(a.dropRight(2)) 15 | println(a.dropWhile(_ < 25)) 16 | 17 | println(a.take(3)) 18 | println(a.takeRight(2)) 19 | println(a.takeWhile(_ < 30)) 20 | 21 | println(a.distinct) 22 | println(a.intersect(List(19,20,21))) 23 | println(a.slice(2, 4)) 24 | 25 | 26 | -------------------------------------------------------------------------------- /Colls-Other-Sequence-Classes/CollsOtherSequenceClasses.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsOtherSequenceClasses.sc 5 | 6 | 7 | // this lesson doesn’t have any examples, but i wanted 8 | // to show that you create a List and Vector in the 9 | // same way: 10 | val a = List(1, 2, 3) 11 | val b = Vector(1, 2, 3) 12 | 13 | 14 | // when you use ArrayBuffer you need to import it first: 15 | import scala.collection.mutable.ArrayBuffer 16 | val c = ArrayBuffer(1, 2, 3) 17 | 18 | 19 | -------------------------------------------------------------------------------- /Colls-Ranges-Creating-Collections-From-Ranges/CollsCreatingFromRanges.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsCreatingFromRanges.sc 5 | 6 | 7 | val r = 1 to 5 // result: Range 1 to 5 8 | 9 | r.toList // List(1, 2, 3, 4, 5) 10 | r.toVector // Vector(1, 2, 3, 4, 5) 11 | 12 | r.filter(_ > 3) // Vector(4, 5) 13 | r.filter(_ > 3).toList // List(4, 5) 14 | r.filter(_ > 3).map(_ * 2.0) // Vector(8.0, 10.0) 15 | 16 | // creates a Map 17 | r.filter(_ > 3) 18 | .map(i => (i, i * 2.0)) 19 | .toMap 20 | 21 | 22 | // Char ranges 23 | val letters1 = ('a' to 'c').toList // List(a, b, c) 24 | val letters2 = ('a' to 'f').by(2).toList // List(a, c, e) 25 | 26 | 27 | // Populating sequences with the ‘range’ method 28 | 29 | Vector.range(1, 3) // Vector(1, 2) 30 | List.range(1, 6, 2) // List(1, 3, 5) 31 | 32 | import collection.mutable.ArrayBuffer 33 | ArrayBuffer.range(1, 3) // ArrayBuffer(1, 2) 34 | 35 | List.range(1, 10) // List(1, 2, 3, 4, 5, 6, 7, 8, 9) 36 | List.range(1, 10, 2) // List(1, 3, 5, 7, 9) 37 | List.range(1, 10, 3) // List(1, 4, 7) 38 | List.range(1, 10, 4) // List(1, 5, 9) 39 | 40 | -------------------------------------------------------------------------------- /Colls-Ranges/CollsRange.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsRange.sc 5 | 6 | 7 | for i <- 1 to 3 do println(i) 8 | 9 | for i <- 1 until 3 do println(i) 10 | 11 | 1 to 3 12 | 1.to(3) 13 | 14 | 15 | // Creating a range with ‘to’ 16 | 1 to 5 // will contain Range(1, 2, 3, 4, 5) 17 | 1 to 10 by 2 // will contain Range(1, 3, 5, 7, 9) 18 | 1 to 10 by 3 // will contain Range(1, 4, 7, 10) 19 | 20 | 21 | // But ranges are lazy 22 | 1 to 10 by 2 23 | (1 to 10 by 2).toList 24 | 25 | 26 | // Laziness 27 | val r = 1 to 10 28 | r.by(2) // Range 1 to 10 by 2 29 | r.drop(5) // Range 6 to 10 30 | r.distinct // Range 1 to 10 31 | r.tail // Range 2 to 10 32 | 33 | r.filter(_ > 5) // Vector(6, 7, 8, 9, 10) 34 | r.min // 1 35 | r.max // 10 36 | r.size // 10 37 | r.toList // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 38 | 39 | val a = 1 to Int.MaxValue 40 | 41 | // this one will consume a lot of memory and probably fail 42 | // val a = (1 to Int.MaxValue).toList 43 | 44 | 45 | // Creating a range with ‘until’ 46 | (1 to 3).toVector // Vector(1, 2, 3) 47 | (1 until 3).toVector // Vector(1, 2) 48 | 49 | (1 to 10 by 3).toList // List(1, 4, 7, 10) 50 | (1 until 10 by 3).toList // List(1, 4, 7) 51 | 52 | 53 | // Char ranges 54 | 'a' to 'e' // NumericRange a to e 55 | 'a' until 'e' // NumericRange a until e 56 | 57 | // 'to' is inclusive, 'until' is not 58 | ('a' to 'e').toList // List(a, b, c, d, e) 59 | ('a' until 'e').toList // List(a, b, c, d) 60 | 61 | // you can also use a step with Char 62 | ('a' to 'e' by 2).toList // List(a, c, e) 63 | ('a' to 'e').by(2).toList // List(a, c, e) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Colls-Set/CollsSet.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsSet.sc 5 | 6 | 7 | val set = Set(1, 1, 1, 2, 2, 3) 8 | println(set) 9 | 10 | 11 | // The Iterable type, and Set methods 12 | set.foreach(println) // prints "1 2 3" on separate lines 13 | for s <- set do println(s) // same result as 'foreach' 14 | 15 | // add one element while creating a new set: 16 | val a = set + 4 // Set(1, 2, 3, 4) 17 | 18 | // add multiple elements from another sequence: 19 | val b = set ++ List(4, 5) // Set(1, 2, 3, 4, 5) 20 | 21 | 22 | -------------------------------------------------------------------------------- /Colls-filter-Method/CollsFilterMethod.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsFilterMethod.sc 5 | 6 | 7 | val ints = Vector(1, 2, 3, 4, 5) 8 | 9 | { 10 | val smallInts = ints.filter(_ < 3) 11 | println(smallInts) 12 | } 13 | 14 | 15 | { 16 | val smallInts = ints.filter(i => i < 3) 17 | println(smallInts) 18 | } 19 | 20 | 21 | { 22 | val smallInts = 23 | for 24 | i <- ints 25 | if i < 3 26 | yield 27 | i 28 | println(smallInts) 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Colls-foreach-Method-Anon-Functions/CollsForeachMethod.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsForeachMethod.sc 5 | 6 | 7 | { 8 | val ints = List(1, 2, 3) 9 | ints.foreach(println) 10 | } 11 | 12 | 13 | { 14 | val ints = List(1, 2, 3) 15 | ints.foreach(i => println(i)) 16 | ints.foreach(println(_)) 17 | ints.foreach(println) 18 | } 19 | 20 | 21 | val strings = List("a", "bb", "ccc") 22 | for s <- strings do println(s.length) 23 | strings.foreach(s => println(s.length)) 24 | 25 | 26 | -------------------------------------------------------------------------------- /Colls-map-Method/CollsMapMethod.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CollsMapMethod.sc 5 | 6 | 7 | val strings = List("a", "bb", "ccc") 8 | strings.foreach(s => println(s.length)) 9 | for s <- strings do println(s.length) 10 | 11 | 12 | val lengths1 = for s <- strings yield s.length 13 | println(lengths1) 14 | 15 | 16 | val lengths2 = strings.map(_.length) 17 | println(lengths2) 18 | 19 | 20 | val ucStrings = strings.map(_.toUpperCase) 21 | println(ucStrings) 22 | 23 | 24 | val lengths3 = strings.map(s => s.length) 25 | println(lengths3) 26 | 27 | -------------------------------------------------------------------------------- /Constructs-Add-if-for-Expressions/ConstructsAddIfToForExpressions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsAddIfToForExpressions.sc 5 | 6 | 7 | val fruits = List("apple", "banana", "cherry", "date") 8 | 9 | for 10 | f <- fruits 11 | if f.length > 5 12 | do 13 | println(f) 14 | 15 | 16 | 17 | val capFruits = 18 | for 19 | f <- fruits 20 | // add as many guards as you need 21 | if f.length > 5 22 | if f.length < 10 23 | if f.startsWith("c") 24 | yield 25 | // add as much business logic as 26 | // you need here 27 | f.capitalize 28 | 29 | capFruits.foreach(println) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Constructs-for-Expressions-Mult-Generators/ForExpressionsMultipleGenerators.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ForExpressionsMultipleGenerators.sc 5 | 6 | 7 | for i <- 1 to 3 do println(i) 8 | 9 | 10 | { 11 | val ints = List(1, 2, 3) 12 | for i <- ints do println(i) 13 | } 14 | 15 | 16 | // multiple generators 17 | val ints = List(1, 2) 18 | val chars = List('a', 'b') 19 | 20 | for 21 | i <- ints 22 | c <- chars 23 | do 24 | println(s"i = $i, c = $c") 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Constructs-for-Expressions/ConstructsForExpressions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsForExpressions.sc 5 | 6 | 7 | val xs = List(1, 2, 3) 8 | val ys = for x <- xs yield x * 2 9 | println(ys) 10 | 11 | 12 | val names = Seq("luke", "leia") 13 | 14 | val capNames = 15 | for 16 | name <- names 17 | yield 18 | // put as many lines of code as are necessary 19 | // for your algorithm 20 | name.capitalize 21 | println(capNames) 22 | 23 | 24 | { 25 | val xs = List("a", "bb", "ccc") 26 | val ys = for x <- xs yield x.length 27 | println(ys) 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Constructs-for-Loops/ConstructsForLoops.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsForLoops.sc 5 | 6 | 7 | val ints = List(1, 2, 3) 8 | for i <- ints do println(i) 9 | 10 | 11 | for 12 | i <- ints 13 | do 14 | // this doesn’t really require multiple lines, 15 | // but imagine that it does 16 | val j = i * 10 17 | println(j) 18 | 19 | 20 | val names = List("adam", "alex", "bob") 21 | 22 | // again imagine that this requires multiple lines: 23 | for name <- names do 24 | val capName = name.capitalize 25 | println(capName) 26 | 27 | for name <- names do println(name.capitalize) 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Constructs-match-Expressions-More-Details/ConstructsMatchExpressionsMoreDetails.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsMatchExpressionsMoreDetails.sc 5 | 6 | 7 | 8 | // MATCHING MULTIPLE PATTERNS PER LINE 9 | 10 | val i = 1 11 | i match 12 | case 1 | 3 | 5 | 7 | 9 => println("odd") 13 | case 2 | 4 | 6 | 8 | 10 => println("even") 14 | case _ => println("something else") 15 | 16 | val cmd = "start" 17 | cmd match 18 | case "start" | "go" => 19 | println("starting") 20 | case "stop" | "quit" | "exit" => 21 | println("stopping") 22 | case _ => 23 | println("doing nothing") 24 | 25 | 26 | 27 | // ADDING ‘IF’ STATEMENTS TO CASES 28 | 29 | { 30 | val i = 10 31 | 32 | i match 33 | case a if 0 to 9 contains a => 34 | println("0-9 range: " + a) 35 | case b if 10 to 19 contains b => 36 | println("10-19 range: " + b) 37 | case c if 20 to 29 contains c => 38 | println("20-29 range: " + c) 39 | case _ => 40 | println("Hmmm...") 41 | } 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Constructs-match-Expressions/ConstructsMatchExpressions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsMatchExpressions.sc 5 | 6 | 7 | // EXAMPLE 1 8 | 9 | { 10 | enum Suit: 11 | case Clubs, Diamonds, Hearts, Spades 12 | 13 | import Suit.* 14 | 15 | val suit = Hearts 16 | 17 | suit match 18 | case Clubs => println("clubs") 19 | case Diamonds => println("diamonds") 20 | case Hearts => println("hearts") 21 | case Spades => println("spades") 22 | } 23 | 24 | 25 | 26 | // EXAMPLE 2 27 | 28 | // assume that 'number' is an Int that’s set earlier in the code: 29 | val number = 1 30 | 31 | // and then some time later in the code: 32 | number match 33 | case 1 => println("One") 34 | case 2 => println("Two") 35 | case _ => println("Some other value") 36 | 37 | 38 | 39 | // EXAMPLE 3 40 | 41 | { 42 | enum Suit: 43 | case Clubs, Diamonds, Hearts, Spades 44 | 45 | import Suit.* 46 | 47 | def suitToString(suit: Suit): String = suit match 48 | case Clubs => "clubs" 49 | case Diamonds => "diamonds" 50 | case Hearts => "hearts" 51 | case Spades => "spades" 52 | 53 | println(suitToString(Clubs)) 54 | println(suitToString(Diamonds)) 55 | println(suitToString(Hearts)) 56 | println(suitToString(Spades)) 57 | } 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Constructs-while-Loop/ConstructsWhileLoop.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ConstructsWhileLoop.sc 5 | 6 | 7 | { 8 | var i = 0 9 | while i < 3 do 10 | println(i) 11 | i += 1 12 | } 13 | 14 | 15 | { 16 | var i = 0 17 | while i < 3 do 18 | println(i) 19 | i += 1 20 | end while 21 | } 22 | 23 | -------------------------------------------------------------------------------- /DM-An-OOP-Domain-Modeling-Example/OOPExample1.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli OOPExample1.sc 5 | 6 | 7 | enum Topping: 8 | case Cheese, Pepperoni, Sausage, Mushrooms, Onions 9 | 10 | enum CrustSize: 11 | case Small, Medium, Large 12 | 13 | enum CrustType: 14 | case Regular, Thin, Thick 15 | 16 | 17 | import collection.mutable.ArrayBuffer 18 | 19 | import Topping.* 20 | import CrustSize.* 21 | import CrustType.* 22 | 23 | class Pizza( 24 | var crustSize: CrustSize = Medium, 25 | var crustType: CrustType = Regular, 26 | val toppings: ArrayBuffer[Topping] 27 | ): 28 | def addTopping(t: Topping): Unit = 29 | toppings += t 30 | 31 | def addToppings(ts: Topping*): Unit = 32 | toppings.appendAll(ts) 33 | 34 | def removeAllToppings(): Unit = 35 | toppings.clear() 36 | 37 | override def toString = s""" 38 | |A $crustSize pizza with a $crustType crust. 39 | |Toppings: ${p.toppings.mkString(", ")}""".stripMargin 40 | 41 | end Pizza 42 | 43 | 44 | val p = Pizza(Medium, Regular, ArrayBuffer(Cheese)) 45 | 46 | p.crustSize = Large 47 | p.crustType = Thin 48 | println(p.toppings) 49 | 50 | // but these methods DO NOT exist yet 51 | p.addTopping(Pepperoni) 52 | p.addToppings(Pepperoni, Mushrooms) 53 | p.removeAllToppings() 54 | println(p.toppings) 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /DM-An-OOP-Domain-Modeling-Example/OOPExample2.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli OOPExample2.sc 5 | 6 | enum Topping: 7 | case Cheese, Pepperoni, Sausage, Mushrooms, Onions 8 | 9 | enum CrustSize: 10 | case Small, Medium, Large 11 | 12 | enum CrustType: 13 | case Regular, Thin, Thick 14 | 15 | 16 | import collection.mutable.ArrayBuffer 17 | 18 | import Topping.* 19 | import CrustSize.* 20 | import CrustType.* 21 | 22 | class Pizza( 23 | var crustSize: CrustSize = Medium, 24 | var crustType: CrustType = Regular, 25 | val toppings: ArrayBuffer[Topping] 26 | ): 27 | def addTopping(t: Topping): Unit = 28 | toppings += t 29 | 30 | def addToppings(ts: Topping*): Unit = 31 | toppings.appendAll(ts) 32 | 33 | def removeAllToppings(): Unit = 34 | toppings.clear() 35 | 36 | override def toString = s""" 37 | |A $crustSize pizza with a $crustType crust. 38 | |Toppings: ${p.toppings.mkString(", ")}""".stripMargin 39 | 40 | end Pizza 41 | 42 | 43 | val p = Pizza(Medium, Regular, ArrayBuffer(Cheese)) 44 | 45 | p.crustSize = Large 46 | p.crustType = Thin 47 | println(p.toppings) 48 | 49 | // but these methods DO NOT exist yet 50 | p.addTopping(Pepperoni) 51 | p.addToppings(Pepperoni, Mushrooms) 52 | p.removeAllToppings() 53 | println(p.toppings) 54 | 55 | 56 | 57 | // MORE DATA TYPES 58 | 59 | class Customer( 60 | var firstName: String, 61 | var lastName: String, 62 | var phone: String, 63 | var address: Address 64 | ): 65 | // from the "Adding Behaviors" section 66 | def fullName = s"$firstName $lastName" 67 | end Customer 68 | 69 | 70 | class Address( 71 | var street1: String, 72 | var street2: Option[String], 73 | var city: String, 74 | var state: String, 75 | var postalCode: String 76 | ) 77 | 78 | val address1 = Address( 79 | "123 Main Street", 80 | None, 81 | "Talkeetna", 82 | "AK", 83 | "99676" 84 | ) 85 | 86 | val address2 = Address( 87 | "123 Main Street", 88 | Some("Unit 101"), 89 | "Talkeetna", 90 | "AK", 91 | "99676" 92 | ) 93 | 94 | class Order( 95 | val pizzas: ArrayBuffer[Pizza], 96 | var customer: Customer 97 | ) 98 | 99 | // use those new data types here as desired 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /DM-Case-Classes/CaseClasses.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CaseClasses.sc 5 | 6 | 7 | case class Person(name: String, relation: String) 8 | val christina = Person("Christina", "niece") 9 | 10 | println(christina.name) 11 | 12 | // error: reassignment to val field: 13 | // christina.name = "Joe" 14 | 15 | val hannah = Person("Hannah", "niece") 16 | println(christina == hannah) 17 | 18 | // demonstrates toString (prints "Person(Christina,niece)"): 19 | println(christina) 20 | 21 | 22 | case class BaseballTeam(name: String, lastWorldSeriesWin: Int) 23 | val cubs1908 = BaseballTeam("Chicago Cubs", 1908) 24 | val cubs2016 = cubs1908.copy(lastWorldSeriesWin = 2016) 25 | println(cubs1908) 26 | println(cubs2016) 27 | 28 | 29 | -------------------------------------------------------------------------------- /DM-Classes-1-Constructors/Classes1Constructors.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Classes1Constructors.sc 5 | 6 | 7 | class Person( 8 | var firstName: String, 9 | var lastName: String 10 | ) 11 | 12 | val john = Person("John", "Doe") 13 | val mary = Person("Mary", "Doe") 14 | 15 | 16 | 17 | // ACCESSING THE CONSTRUCTOR PARAMETERS 18 | val p = Person("Reginald", "Dwight") 19 | 20 | println(p.firstName) // prints "Reginald" 21 | println(p.lastName) // prints "Dwight" 22 | 23 | p.firstName = "Elton" 24 | p.lastName = "John" 25 | 26 | println(p.firstName) // prints "Elton" 27 | println(p.lastName) // prints "John" 28 | 29 | 30 | 31 | // VAR VS VAL 32 | { 33 | class Person( 34 | val firstName: String, 35 | val lastName: String 36 | ) 37 | 38 | // create a new Person 39 | val p = Person("Reginald", "Dwight") 40 | 41 | // print the fields 42 | println(p.firstName) // prints "Reginald" 43 | println(p.lastName) // prints "Dwight" 44 | 45 | // intentional errors 46 | // p.firstName = "Elton" // ERROR: Reassignment to val firstName 47 | // p.lastName = "John" // ERROR: Reassignment to val lastName 48 | } 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /DM-Classes-2-Adding-Members-and-Getters/Classes2AddingMembersGetter.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Classes2AddingMembersGetter.sc 5 | 6 | 7 | { 8 | class Employee(var firstName: String, var lastName: String): 9 | def fullName: String = s"$firstName $lastName" 10 | end Employee 11 | 12 | val e = Employee("Reginald", "Dwight") 13 | 14 | println(e.firstName) // prints "Reginald" 15 | println(e.lastName) // prints "Dwight" 16 | 17 | e.firstName = "Elton" 18 | e.lastName = "John" 19 | 20 | println(e.fullName) // prints "Elton John" 21 | } 22 | 23 | 24 | // A PRIVATE FIELD AND GETTER METHOD 25 | { 26 | class Employee(var firstName: String, var lastName: String): 27 | private var _salary = 0d 28 | def salary: Double = _salary 29 | def fullName: String = s"$firstName $lastName" 30 | end Employee 31 | 32 | val e = Employee("John", "Doe") 33 | 34 | // print the constructor parameter fields 35 | println(s"firstName = ${e.firstName}, lastName = ${e.lastName}") 36 | 37 | // print the salary field 38 | println(s"Salary = ${e.salary}") 39 | } 40 | 41 | 42 | // NOTE: DON’T USE DOUBLE FOR CURRENCY 43 | println(0.10 + 0.20) 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /DM-Classes-3-Adding-Setters/Classes3AddingSetters.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Classes3AddingSetters.sc 5 | 6 | 7 | /** 8 | * The complete class. 9 | * Employee is a class that takes two constructor parameters, 10 | * and both parameters are mutable. 11 | */ 12 | class Employee(var firstName: String, var lastName: String): 13 | 14 | // This is a private, mutable field that has the Double type. 15 | // Note that the field is named _salary, but it could be named 16 | // theSalary, or any other meaningful name. Also, because the 17 | // field is private, it can’t be accessed outside the class. 18 | private var _salary = 0d 19 | 20 | // This is a “getter” method for the _salary field. Users 21 | // will call this method to get the current salary value. 22 | def salary: Double = _salary 23 | 24 | // This is the “setter” method for the _salary field. Users 25 | // will call this method to update the salary. Note that it 26 | // can be declared on one line, but I use two lines here to 27 | // make it more clear. 28 | def salary_=(newSalary: Double): Unit = 29 | _salary = newSalary 30 | 31 | // This method returns the full name of the Employee as a 32 | // String. 33 | def fullName: String = s"$firstName $lastName" 34 | end Employee 35 | 36 | 37 | val e = Employee("John", "Doe") 38 | 39 | // update the salary field 40 | e.salary = 1_000_000.01d 41 | 42 | println(s"firstName = ${e.firstName}, lastName = ${e.lastName}") 43 | println(s"Salary = ${e.salary}") 44 | 45 | 46 | 47 | // As a bonus, this code shows how to format the salary 48 | // using a Locale, such as "US" for the United States. 49 | // I show a few more examples of how to work with this 50 | // in the Scala Cookbook (https://amzn.to/3du1pMR): 51 | import java.text.NumberFormat 52 | import java.util.Locale 53 | val formatter = NumberFormat.getInstance(Locale.US) 54 | val formattedSalary = formatter.format(e.salary) 55 | println(s"Salary = $$${formattedSalary}") 56 | 57 | // the $$$ in that code is necessary because $$ prints 58 | // one $ when used with the 's' interpolator, and then 59 | // the third $ belongs to the '${formattedSalary}' code. 60 | // try removing one or two of the $ characters and see 61 | // what happens. 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /DM-Classes-Auxiliary-Constructors/ClassesAuxiliaryConstructors.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ClassesAuxiliaryConstructors.sc 5 | 6 | 7 | // [0] this is the primary constructor 8 | class Person(var firstName: String, var lastName: String): 9 | 10 | // [1] a one-arg auxiliary constructor 11 | def this(firstName: String) = 12 | this(firstName, "") 13 | 14 | // [2] a zero-arg auxiliary constructor 15 | def this() = 16 | this("", "") 17 | 18 | override def toString = s"$firstName $lastName" 19 | 20 | end Person 21 | 22 | 23 | println(Person("Alvin", "Alexander")) 24 | println(Person("Alvin")) 25 | println(Person()) 26 | 27 | -------------------------------------------------------------------------------- /DM-Classes-Default-Constructor-Parameters/ClassesDefaultConstructorParameters.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ClassesDefaultConstructorParameters.sc 5 | 6 | 7 | class Person( 8 | var firstName: String = "", 9 | var lastName: String = "" 10 | ): 11 | override def toString = s"$firstName $lastName" 12 | 13 | 14 | println(Person("Alvin", "Alexander")) 15 | println(Person("Alvin")) 16 | println(Person()) 17 | 18 | -------------------------------------------------------------------------------- /DM-Enums-More-Details/EnumsMoreDetails.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | //> using lib "org.scalameta::munit::0.7.27" 3 | 4 | /** 5 | * To make this a little more interesting (and challenging), 6 | * this code uses a testing framework along with Scala CLI. 7 | * The testing framework is named MUnit (https://scalameta.org/munit). 8 | * Notice that it is included in the second line in this file. 9 | * 10 | * For more information on running tests with Scala CLI, 11 | * see: https://scala-cli.virtuslab.org/docs/commands/test 12 | */ 13 | 14 | /** 15 | * Run this code with either of these commands. The second 16 | * command recompiles and re-tests your code any time 17 | * there is a change: 18 | * $ scala-cli test EnumsMoreDetails.scala 19 | * $ scala-cli test EnumsMoreDetails.scala --watch 20 | */ 21 | 22 | enum HttpResponse(val code: Int): 23 | case Ok extends HttpResponse(200) 24 | case MovedPermanently extends HttpResponse(301) 25 | case InternalServerError extends HttpResponse(500) 26 | 27 | import HttpResponse.* 28 | 29 | class EnumTests extends munit.FunSuite { 30 | test("code tests") { 31 | assert(Ok.code == 200) 32 | assert(MovedPermanently.code == 301) 33 | assert(InternalServerError.code == 500) 34 | } 35 | } 36 | 37 | 38 | // See the complete 'Planet' example here: 39 | // https://https://dotty.epfl.ch/docs/reference/enums/enums.html 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /DM-Enums/Enums1.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Enums1.scala 5 | 6 | 7 | enum Suit: 8 | case Clubs, Diamonds, Hearts, Spades 9 | 10 | @main def enumTest = 11 | 12 | // import the enum cases 13 | import Suit.* 14 | 15 | // use those cases in your code like any other data type 16 | def printEnum(suit: Suit): Unit = suit match 17 | case Clubs => println("clubs") 18 | case Diamonds => println("diamonds") 19 | case Hearts => println("hearts") 20 | case Spades => println("spades") 21 | 22 | // print the values 23 | printEnum(Clubs) // clubs 24 | printEnum(Diamonds) // diamonds 25 | printEnum(Hearts) // hearts 26 | printEnum(Spades) // spades 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /DM-Enums/Enums2.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Enums2.sc 5 | 6 | 7 | enum CrustSize: 8 | case Small, Medium, Large 9 | 10 | enum CrustType: 11 | case Thin, Thick, Regular 12 | 13 | enum Topping: 14 | case Cheese, Pepperoni, Mushrooms, GreenPeppers, Olives 15 | 16 | 17 | import CrustSize.* 18 | import CrustType.* 19 | import Topping.* 20 | 21 | val currentCrustSize = Large 22 | 23 | 24 | if 25 | currentCrustSize == Small 26 | then 27 | println("Small!") 28 | else 29 | println("Something else") 30 | 31 | 32 | currentCrustSize match 33 | case Small => println("small") 34 | case Medium => println("medium") 35 | case Large => println("large") 36 | 37 | 38 | import scala.collection.mutable.ArrayBuffer 39 | class Pizza( 40 | var crustSize: CrustSize, 41 | var crustType: CrustType, 42 | val toppings: ArrayBuffer[Topping] 43 | ) 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /DM-Objects-1-Singletons/ObjectsSingletons1.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ObjectsSingletons1.scala 5 | 6 | object CashRegister: 7 | def open() = println("opened") 8 | def close() = println("closed") 9 | 10 | @main def objectTest = 11 | CashRegister.open() 12 | CashRegister.close() 13 | 14 | 15 | -------------------------------------------------------------------------------- /DM-Objects-1-Singletons/ObjectsSingletons2.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ObjectsSingletons2.sc 5 | 6 | 7 | object CashRegister: 8 | 9 | // two private counters that cannot be accessed directly 10 | private var numOpens = 0 11 | private var numCloses = 0 12 | 13 | // two methods related to physically opening and closing 14 | // the register drawer 15 | def open() = 16 | // in the real world, here you would do whatever 17 | // is needed to open the register drawer 18 | numOpens += 1 19 | def close() = 20 | // assume that you got a signal here that the register 21 | // drawer was closed 22 | numCloses += 1 23 | 24 | // "getter" methods for the private variables 25 | def getNumberOfOpens = numOpens 26 | def getNumberOfCloses = numCloses 27 | 28 | end CashRegister 29 | 30 | CashRegister.open() 31 | CashRegister.close() 32 | println(CashRegister.getNumberOfOpens) 33 | println(CashRegister.getNumberOfCloses) 34 | 35 | 36 | 37 | // UTILITY CLASSES 38 | 39 | object StringUtils: 40 | 41 | // return true if the string is null or empty 42 | def isNullOrEmpty(s: String): Boolean = 43 | if s==null || s.trim.equals("") then true else false 44 | 45 | // convert "big belly burger" to "Big Belly Burger" 46 | def capitalizeAllWords(s: String): String = 47 | s.split(" ") 48 | .map(_.capitalize) 49 | .mkString(" ") 50 | 51 | end StringUtils 52 | 53 | 54 | println(StringUtils.isNullOrEmpty("")) 55 | println(StringUtils.capitalizeAllWords("big belly burger")) 56 | 57 | import StringUtils.* 58 | 59 | println(isNullOrEmpty("")) 60 | println(capitalizeAllWords("big belly burger")) 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /DM-Objects-2-Companion-Objects/CompanionObjects.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli CompanionObjects.scala 5 | 6 | 7 | class Person(var name: String) 8 | object Person 9 | 10 | 11 | // companion class 12 | class Pizza (var crustType: String): 13 | override def toString = s"Crust type is $crustType" 14 | 15 | // companion object 16 | object Pizza: 17 | // two fields 18 | val CRUST_TYPE_THIN = "THIN" 19 | val CRUST_TYPE_THICK = "THICK" 20 | 21 | // one method 22 | def calculatePrice(p: Pizza): Double = 23 | // put a fancy pizza-pricing algorithm here 24 | 0.0 25 | 26 | @main def pizzaTest = 27 | val p = Pizza(Pizza.CRUST_TYPE_THICK) 28 | println(p) 29 | println(Pizza.calculatePrice(p)) 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /DM-Objects-3-apply-Methods/ObjectsApplyMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ObjectsApplyMethods.sc 5 | 6 | { 7 | class Person private(val name: String): 8 | override def toString = name 9 | 10 | object Person: 11 | // the “constructor” 12 | def apply(name: String): Person = new Person(name) 13 | 14 | val bert = Person("Bert") 15 | val a = List(Person("Bert"), Person("Ernie")) 16 | 17 | println(bert) 18 | println(a) 19 | 20 | val p1 = Person("Fred Flintstone") 21 | val p2 = Person.apply("Fred Flintstone") 22 | 23 | println(p1) 24 | println(p2) 25 | } 26 | 27 | 28 | 29 | // DISCUSSION 30 | 31 | { 32 | class Person private(var name: String, var age: Int): 33 | override def toString = s"$name is $age years old" 34 | 35 | object Person: 36 | // three ways to build a Person 37 | def apply(): Person = new Person("", 0) 38 | def apply(name: String): Person = new Person(name, 0) 39 | def apply(name: String, age: Int): Person = new Person(name, age) 40 | 41 | println(Person()) // is 0 years old 42 | println(Person("Bert")) // Bert is 0 years old 43 | println(Person("Ernie", 22)) // Ernie is 22 years old 44 | } 45 | 46 | 47 | { 48 | class Person private(var name: String, var age: Int): 49 | override def toString = s"$name is $age years old" 50 | 51 | object Person: 52 | def apply(t: (String, Int)): Person = new Person(t(0), t(1)) 53 | def apply(ts: (String, Int)*): Seq[Person] = 54 | for t <- ts yield new Person(t(0), t(1)) 55 | 56 | // create a person from a tuple 57 | val john = Person(("John", 30)) 58 | 59 | // create multiple people using a variable number of tuples 60 | val peeps = Person( 61 | ("Kenny", 33), 62 | ("Julia", 31) 63 | ) 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /DM-Traits-Adding-Behaviors/TraitsAddingBehaviors.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli TraitsAddingBehaviors.sc 5 | 6 | trait HasTail: 7 | def startTail() = println("Tail is started") 8 | def stopTail() = println("Tail is stopped") 9 | 10 | trait CanSpeak: 11 | def speak(): Unit 12 | 13 | class Dog extends HasTail, CanSpeak: 14 | def speak() = println("Woof") 15 | 16 | class Cat extends HasTail, CanSpeak: 17 | override def startTail() = println("Yeah, I’m not doing that") 18 | override def stopTail() = println("Never started") 19 | def speak() = println("Meow") 20 | 21 | val d = Dog() 22 | d.startTail() // Tail is started 23 | d.stopTail() // Tail is stopped 24 | d.speak() // Woof 25 | 26 | val c = Cat() 27 | c.startTail() // Yeah, I’m not doing that 28 | c.stopTail() // Never started 29 | c.speak() // Meow 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DM-Traits-Using-As-Interfaces/TraitsAsInterfaces.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli TraitsAsInterfaces.sc 5 | 6 | 7 | trait HasTail: 8 | def startTail(): Unit 9 | def stopTail(): Unit 10 | 11 | trait CanSpeak: 12 | def speak(): Unit 13 | 14 | class Dog extends HasTail, CanSpeak: 15 | def startTail() = println("Tail is wagging") 16 | def stopTail() = println("Tail is stopped") 17 | def speak() = println("Woof") 18 | 19 | val d = Dog() 20 | d.speak() // Woof 21 | d.startTail() // Tail is wagging 22 | d.stopTail() // Tail is stopped 23 | 24 | 25 | 26 | // THE BENEFIT OF USING TRAITS AS INTERFACES 27 | 28 | def saySomething(speaker: CanSpeak) = speaker.speak() 29 | 30 | class Cat extends CanSpeak: 31 | def speak() = println("Meow") 32 | 33 | saySomething(Dog()) // Woof 34 | saySomething(Cat()) // Meow 35 | 36 | def getSpeaker(s: String): CanSpeak = ??? 37 | 38 | -------------------------------------------------------------------------------- /DM-Union-Types/UnionTypes.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli UnionTypes.sc 5 | 6 | 7 | // Perl version of what’s “true” 8 | def isTrue(a: Int | String | Boolean): Boolean = a match 9 | case 0 | "0" | "" | false => false 10 | case _ => true 11 | 12 | println(isTrue(0)) 13 | println(isTrue("0")) 14 | println(isTrue("")) 15 | println(isTrue(false)) 16 | 17 | 18 | 19 | // OTHER USES 20 | 21 | def aFunction(): Int | String = 22 | // create a random integer 23 | val i = scala.util.Random.nextInt(100) 24 | // return it as an Int or a String 25 | if (i < 50) then i else s"string: $i" 26 | 27 | val x = aFunction() 28 | val y: Int | String = aFunction() 29 | 30 | println(x) 31 | println(y) 32 | 33 | // these show the data types of each object 34 | println(x.getClass) 35 | println(y.getClass) 36 | 37 | 38 | var a : Int | String = 1 // 'a' can be an Int or String; right now it’s Int 39 | 40 | a = "hello" // now it’s String! 41 | println(a.getClass) 42 | 43 | a = 2 // wait, it’s Int again 44 | println(a.getClass) 45 | 46 | a = "world" // it’s a String again 47 | // a = 2.2 // COMPILER ERROR: Type Mismatch Error 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Domain-Modeling/DomainModeling.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli DomainModeling.sc 5 | 6 | 7 | // there are no examples in this lesson 8 | -------------------------------------------------------------------------------- /EOP/EOP.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli EOP.sc 5 | 6 | val a = 1 7 | val b = 2 8 | val c = if a < b then a else b 9 | println(c) 10 | 11 | 12 | def min(a: Int, b: Int): Int = 13 | if a < b then a else b 14 | println(min(1, 2)) 15 | println(min(2, 1)) 16 | 17 | val x = min(1, 1_000) 18 | println(x) 19 | 20 | 21 | -------------------------------------------------------------------------------- /Examples-Command-Line-IO/CmdLine.sc: -------------------------------------------------------------------------------- 1 | 2 | // notice in this code that i don’t set the Scala 3 | // version, so scala-cli should use its default. 4 | 5 | import scala.io.StdIn.readLine 6 | print("What’s your name? ") 7 | val name = readLine() 8 | println(s"You said your name is $name") 9 | -------------------------------------------------------------------------------- /Examples-Command-Line-IO/NameAndAge.sc: -------------------------------------------------------------------------------- 1 | // notice in this code that i don’t set the Scala 2 | // version, so scala-cli should use its default. 3 | 4 | import scala.io.StdIn.readLine 5 | 6 | print("What’s your name? ") 7 | val name = readLine() 8 | 9 | print("What’s your age (in years)? ") 10 | val ageString = readLine() 11 | val age = ageString.toInt 12 | 13 | println(s"Your name is $name and your age is $age") 14 | 15 | -------------------------------------------------------------------------------- /Examples-HTTP/HttpGet.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | //> using lib "com.softwaremill.sttp.client3::core::3.7.2" 3 | 4 | // run me with 'scala-cli HttpGet.scala' 5 | 6 | import sttp.client3.* 7 | 8 | @main def doGet = 9 | val backend = HttpURLConnectionBackend() 10 | val response = basicRequest 11 | .get(uri"http://httpbin.org/get") 12 | .send(backend) 13 | println(response) 14 | 15 | -------------------------------------------------------------------------------- /Examples-HTTP/HttpPost.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | //> using lib "com.softwaremill.sttp.client3::core::3.7.2" 3 | 4 | // run me with 'scala-cli HttpPost.scala' 5 | 6 | import sttp.client3.* 7 | 8 | @main 9 | def doPost() = 10 | val backend = HttpURLConnectionBackend() 11 | val response = basicRequest 12 | .body("Hello, world!") 13 | .post(uri"https://httpbin.org/post?hello=world") 14 | .send(backend) 15 | println(response) 16 | 17 | 18 | -------------------------------------------------------------------------------- /Examples-Swing/Swing.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run me with 'scala-cli Swing.scala' 4 | 5 | import java.awt.{BorderLayout, Dimension} 6 | import javax.swing.{JFrame, JScrollPane, JTextArea, WindowConstants} 7 | 8 | @main def SwingExample = 9 | val textArea = JTextArea("Hello, Swing world") 10 | val scrollPane = JScrollPane(textArea) 11 | 12 | val frame = JFrame("Hello, Swing") 13 | frame.getContentPane.add(scrollPane, BorderLayout.CENTER) 14 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) 15 | frame.setSize(new Dimension(600, 400)) 16 | frame.setLocationRelativeTo(null) 17 | frame.setVisible(true) 18 | 19 | 20 | -------------------------------------------------------------------------------- /Examples-Timer/timer.sc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S scala-cli shebang 2 | //> using scala "3" 3 | 4 | // my assumptions: 5 | // * this code is in a file named 'timer.sc' 6 | // * the file is made executable with a command like 'chmod +x timer.sc' 7 | // * you have 'scala-cli' installed 8 | // 9 | // usage: 10 | // timer.sc minutes-before-alarm 11 | // timer.sc 10 12 | // timer.sc 20 -10 13 | // ('gain-control' should be something like -10 or -20) 14 | 15 | 16 | // import what we need from the Java Sound library 17 | // ------------------------------------------------------------ 18 | import javax.sound.sampled.* 19 | 20 | 21 | // if you don’t get the right number of command-line args, quit 22 | // ------------------------------------------------------------ 23 | if args.length < 1 then showUsageAndExit() 24 | 25 | 26 | // initialize the values from the user input. 27 | // note that these can fail because i don’t verify that they 28 | // are Int values. 29 | // ------------------------------------------------------------ 30 | val minutesToWait = args(0).toInt 31 | val gainControl = if args.length == 2 then args(1).toInt else -30 32 | 33 | 34 | // and the action begins ... 35 | // ------------------------------------------------------------ 36 | println(s"Timer started. Wait time is $minutesToWait minutes.\n") 37 | 38 | 39 | // wait the desired time, sleeping one minute in between checks 40 | // ------------------------------------------------------------ 41 | for i <- 1 to minutesToWait do 42 | Thread.sleep(60_000) 43 | println(s"time remaining: ${minutesToWait-i} ...") 44 | 45 | 46 | // the 'for' loop ended, so play the sound twice. my sound lasts 47 | // about 7 seconds, so i sleep that long in between plays. 48 | // ------------------------------------------------------------- 49 | for i <- 1 to 2 do 50 | playSoundfile("./gong.wav") 51 | Thread.sleep(7_000) 52 | 53 | 54 | // my two functions are shown below here 55 | // ------------------------------------------------------------ 56 | 57 | def showUsageAndExit() = 58 | Console.err.println("Usage: timer.sc minutes-before-alarm ") 59 | Console.err.println("Ex: timer.sc 10") 60 | Console.err.println("Ex: timer.sc 10 -20") 61 | Console.err.println(" 'gain-control' should be something like -10 or -20") 62 | System.exit(1) 63 | 64 | /** 65 | * This is some “Java Audio” specific code. Note that I don’t do any 66 | * error-checking, so if the sound file doesn’t exist, this code will blow up. 67 | */ 68 | @throws(classOf[java.io.FileNotFoundException]) 69 | def playSoundfile(f: String): Unit = 70 | val audioInputStream = AudioSystem.getAudioInputStream(java.io.File(f)) 71 | val clip = AudioSystem.getClip 72 | clip.open(audioInputStream) 73 | val floatGainControl = clip.getControl(FloatControl.Type.MASTER_GAIN).asInstanceOf[FloatControl] 74 | floatGainControl.setValue(gainControl) //reduce volume by x decibels (like -10f or -20f) 75 | clip.start 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Examples-TryCatchFinally/TryCatchFinally.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run with: 4 | // scala-cli TryCatchFinally.scala 5 | 6 | import scala.util.{Try, Success, Failure} 7 | import scala.io.{BufferedSource, Source} 8 | 9 | def readTextFile(filename: String): Try[String] = 10 | var source: BufferedSource = null 11 | try 12 | source = Source.fromFile(filename) 13 | val lines = for line <- source yield line 14 | Success(lines.mkString) // this converts 'lines' to a String 15 | catch 16 | case t: Throwable => Failure(t) 17 | finally 18 | if source != null then source.close() 19 | 20 | @main 21 | def tryExample = 22 | // [1] attempt to read the file 23 | val maybeContents = readTextFile("/etc/passwd") 24 | // [2] handle the result you got 25 | maybeContents match 26 | case Success(content) => println(content) 27 | case Failure(exception) => System.err.println(exception.getMessage) 28 | -------------------------------------------------------------------------------- /Explicit-Data-Type/ExplicitDataTypes.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ExplicitDataTypes.sc 5 | 6 | 7 | // implicit data types 8 | val name = "Fred" // String 9 | val count = 1 // Int (an integer) 10 | println(name) 11 | println(count) 12 | 13 | 14 | // explicitly declare the data type 15 | val john: String = "John Doe" 16 | val answer: Int = 42 17 | 18 | println(john) 19 | println(answer) 20 | 21 | 22 | -------------------------------------------------------------------------------- /Extras/ReadCsvFile.scala: -------------------------------------------------------------------------------- 1 | // run with: 2 | // scala-cli ReadCsvFile.scala 3 | 4 | // Purpose: Open a CSV file, split the rows into columns, 5 | // then print every field of the 2nd column. 6 | @main def readCsvFile = 7 | val bufferedSource = io.Source.fromFile("/Users/al/Desktop/Customers.csv") 8 | for line <- bufferedSource.getLines do 9 | val cols = line.split(",").map(_.trim) 10 | print(s"${cols(1)}, ") 11 | bufferedSource.close 12 | 13 | -------------------------------------------------------------------------------- /Functions-Creating-main-Method/Hello.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Hello.scala 5 | 6 | // create as many functions as you need 7 | def double(i: Int): Int = i * 2 8 | 9 | @main 10 | def hello() = 11 | println("Hello, world") 12 | val x = double(2) 13 | println(s"2 * 2 = $x") 14 | -------------------------------------------------------------------------------- /Functions-Creating-main-Method/HelloParameters.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli HelloParameters.scala -- YourName 5 | 6 | // i won’t use these functions, but i want to show that 7 | // you can define as many as you need here: 8 | def add(i: Int, j: Int): Int = i + j 9 | def double(i: Int): Int = i * 2 10 | 11 | // in Scala 3 you can also create “top level” variables like this: 12 | val x = double(2) 13 | 14 | @main 15 | def hello(name: String) = 16 | println(s"Hello, $name") 17 | println(s"2 * 2 = $x") 18 | 19 | -------------------------------------------------------------------------------- /Functions-Defaults-For-Function-Parameters/FunctionsDefaultsForFunctionParameters.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli FunctionsDefaultsForFunctionParameters.sc 5 | 6 | 7 | def printHello(name: String = "Alvin"): Unit = 8 | println(s"Hello, $name") 9 | 10 | printHello() // Hello, Alvin 11 | printHello("Joe") // Hello, Joe 12 | 13 | 14 | // A more useful example 15 | def getUrlData( 16 | url: String, 17 | connectionTimeout: Int = 5_000, 18 | readTimeout: Int = 5_000 19 | ): String = 20 | println(s"cTimeout = $connectionTimeout, rTimeout = $readTimeout") 21 | // your real code would be here 22 | "Here’s the data!" 23 | 24 | getUrlData("https...") // cTimeout = 5000, rTimeout = 5000 25 | getUrlData("https...", 2_500) // cTimeout = 2500, rTimeout = 5000 26 | getUrlData("https...", 10_000, 10_000) // cTimeout = 10000, rTimeout = 10000 27 | 28 | 29 | -------------------------------------------------------------------------------- /Functions-Functional-Error-Handling-2/FunctionalErrorHandling.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli FunctionalErrorHandling.sc 5 | 6 | 7 | // Try/Success/Failure 8 | // you must first import these types: 9 | import scala.util.{Try, Success, Failure} 10 | 11 | { 12 | def makeInt(s: String): Try[Int] = Try(s.toInt) 13 | 14 | makeInt("1") // Success(1) 15 | makeInt("one") // Failure(java.lang.NumberFormatException...) 16 | 17 | val aString = "100" 18 | makeInt(aString) match 19 | case Success(i) => println(s"Success: i = $i") 20 | case Failure(s) => println(s"Failed: msg = $s") 21 | } 22 | 23 | 24 | // EITHER/LEFT/RIGHT 25 | 26 | { 27 | def makeInt(s: String): Either[String, Int] = 28 | try 29 | Right(s.toInt) 30 | catch 31 | // for this example i convert the exception to a string 32 | case e: NumberFormatException => Left(e.getMessage) 33 | } 34 | 35 | { 36 | def makeInt(s: String): Either[Exception, Int] = 37 | try 38 | Right(s.toInt) 39 | catch 40 | // return the exception 41 | case e: NumberFormatException => Left(e) 42 | 43 | val aString = "100" 44 | makeInt(aString) match 45 | case Right(i) => println(s"Success: i = $i") 46 | case Left(e) => println(s"Failed, exception = $e") 47 | } 48 | 49 | 50 | // SHORTER VERSIONS OF THOSE FUNCTIONS 51 | 52 | import scala.util.{Try,Success,Failure} 53 | import scala.util.control.Exception.* 54 | 55 | { 56 | def makeInt(s: String): Option[Int] = 57 | allCatch.opt(s.toInt) 58 | } 59 | 60 | { 61 | def makeInt(s: String): Either[Throwable, Int] = 62 | allCatch.either(s.toInt) 63 | } 64 | 65 | { 66 | def makeInt(s: String): Try[Int] = 67 | allCatch.toTry(Try(s.toInt)) 68 | } 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Functions-Handling-Variable-Number-Parameters/FunctionsVarargs.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli FunctionsVarargs.sc 5 | 6 | 7 | // one parameter 8 | def printOne(i: Int) = println(i) 9 | 10 | 11 | // a varargs parameter 12 | def printZeroOrMore(ints: Int*) = ints.foreach(println) 13 | printZeroOrMore() 14 | printZeroOrMore(1) 15 | printZeroOrMore(1, 2) 16 | printZeroOrMore(1, 2, 3) 17 | 18 | 19 | // varargs rules 20 | def printStuff(string: String, ints: Int*) = 21 | println(s"s = $string") 22 | ints.foreach(println) 23 | 24 | printStuff("yo") 25 | printStuff("yo", 1) 26 | printStuff("yo", 1, 2) 27 | printStuff("yo", 1, 2, 3) // as many ints as desired 28 | 29 | 30 | // these functions won’t compile 31 | // def badFunction1(i: Int*, j: Int) = ??? 32 | // def badFunction2(i: Int*, j: Int*) = ??? 33 | 34 | 35 | -------------------------------------------------------------------------------- /Functions-Named-Parameters/FunctionsNamedParameters.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli FunctionsNamedParameters.sc 5 | 6 | 7 | def truncate(string: String, length: Int): String = 8 | string.take(length) 9 | 10 | val a = truncate( 11 | string = "freedom", 12 | length = 4 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /Functions-Options-and-Functional-Error-Handling/FunctionsOptions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli FunctionsOptions.sc 5 | 6 | 7 | "1".toInt // works 8 | // "one".toInt // throws an exception 9 | 10 | 11 | // A “String to Int” method 12 | { 13 | def makeInt(s: String): Int = 14 | try 15 | s.toInt 16 | catch 17 | case e: NumberFormatException => 0 18 | 19 | makeInt("0") 20 | makeInt("") 21 | makeInt("zero") 22 | } 23 | 24 | 25 | // The correct solution 26 | { 27 | def makeInt(s: String): Option[Int] = 28 | try 29 | Some(s.toInt) 30 | catch 31 | case e: NumberFormatException => None 32 | 33 | makeInt("1") // Some(1) 34 | makeInt("one") // None 35 | 36 | // change this string to see the different results: 37 | val aString = "" 38 | makeInt(aString) match 39 | case Some(i) => println(s"Conversion worked. i = $i") 40 | case None => println("The conversion failed.") 41 | } 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Functions/Functions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Functions.sc 5 | 6 | 7 | def double(i: Int): Int = 2 * i 8 | val x = double(2) // x is an Int with the value 4 9 | println(x) 10 | println(double(3)) // prints the number 6 11 | 12 | 13 | // Multiple input parameters 14 | def add(i: Int, j: Int): Int = i + j 15 | def add(i: Int, j: Int, k: Int): Int = i + j + k 16 | 17 | def printIntWithMessage(msg: String, int: Int): Unit = 18 | println(s"$msg $int") 19 | 20 | 21 | // Multiline functions 22 | def removeTrailingS(s: String): String = 23 | if s.length == 0 then 24 | s 25 | else if s.last == 's' then 26 | s.dropRight(1) 27 | else 28 | s 29 | 30 | removeTrailingS("") // "" 31 | removeTrailingS("Big") // "Big" 32 | removeTrailingS("Belly") // "Belly" 33 | removeTrailingS("Burgers") // "Burger" (the 's' is removed) 34 | 35 | 36 | // An “Advanced Scala” note 37 | { 38 | def add(i: Int)(j: Int): Int = i + j 39 | val a = add(1)(2) // 'a' will be 3 40 | } 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Importing-Code-With-import/Imports.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Imports.sc 5 | 6 | 7 | import scala.io.Source 8 | 9 | // read and print the lines in the /etc/passwd file: 10 | for 11 | line <- Source.fromFile("/etc/passwd").getLines 12 | do 13 | println(line) 14 | 15 | 16 | // you can use 'import' statements anywhere, they 17 | // aren’t limited to being at the top of a file: 18 | import java.io.* 19 | 20 | // after the 'import' you can use the java.io classes, 21 | // like File, IOException and FileNotFoundException. 22 | 23 | 24 | -------------------------------------------------------------------------------- /Learn-Scala-3-The-Fast-Way-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alvinj/LearnScala3TheFastWayBook1/26c975d3cb9eadb125d2ead3422a1c1e44cc180e/Learn-Scala-3-The-Fast-Way-small.jpg -------------------------------------------------------------------------------- /Math-Expressions/MathExpressions.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli MathExpressions.sc 5 | 6 | val a = 1 7 | val b = a + 10 // 11 8 | val c = b * 2 // 22 9 | val d = c - 2 // 20 10 | val e = d / 2 // 10 11 | val f = e % 3 // 1 (modulus operator) 12 | 13 | 14 | var x = 1 // note that 'x' is now a 'var' 15 | x = x + 10 // 11 16 | x = x * 2 // 22 17 | x = x - 2 // 20 18 | x = x / 2 // 10 19 | x = x % 3 // 1 (modulus operator) 20 | 21 | 22 | var y = 1 23 | y += 1 // y == 2 24 | y -= 1 // y == 1 25 | 26 | 27 | var z = 10.0 // a Double 28 | z += 1.5 // 11.5 29 | z -= 3.0 // 8.5 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Numeric-Data-Types/NumericDataTypes.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli NumericDataTypes.sc 5 | 6 | val x = 42 7 | val y = 42.0 8 | 9 | 10 | val a: Byte = 1 11 | val b: Long = 1 12 | val c: Short = 1 13 | val d: Float = 1.0 14 | 15 | // you can also declare Int and Double this way, 16 | // though it isn’t necessary: 17 | val e: Int = 1 18 | val f: Double = 1.0 19 | 20 | 21 | val g = 1_000 // Int 22 | val h = 1_000_000 // Int 23 | val i = 1_000_000L // Long (created with the 'L' after the number) 24 | val j = 1_234.56 // Double 25 | 26 | 27 | val k = BigInt(1_234_567_890_123_456L) 28 | val l = BigDecimal(123_456_789.012) 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Scala 3 The Fast Way! (Book 1) 2 | 3 | These examples go along with my book: 4 | 5 | - [Learn Scala 3 The Fast Way! (Book 1: The Adventure Begins)](https://alvinalexander.com/scala/learn-scala-3-the-fast-way-book/) 6 | 7 | ![Learn Scala 3 The Fast Way! (Book 1)](Learn-Scala-3-The-Fast-Way-small.jpg) 8 | 9 | All the best, 10 | Alvin Alexander 11 | [alvinalexander.com](https://alvinalexander.com) 12 | -------------------------------------------------------------------------------- /Scala-REPL/repl.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli repl.sc 5 | 6 | 7 | // initial examples 8 | val x = 1 9 | val y = 2 10 | val z = x + y 11 | 12 | println(s"z = $z") 13 | 14 | 15 | // more examples 16 | val a = 2 17 | val b = 4 18 | val c = a * b 19 | val d = c / 2 20 | val e = d - 1 21 | d == 3 22 | d == 7 23 | 24 | val s = "Hello, world" 25 | println(s"String Length = ${s.length}") 26 | 27 | -------------------------------------------------------------------------------- /Strings-Common-Methods/StringMethods.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli StringMethods.sc 5 | 6 | val a = "hello, world" 7 | println(a.length) // 12 8 | println(a.capitalize) // "Hello, world" 9 | println(a.toUpperCase) // "HELLO, WORLD" 10 | println(a.indexOf("e")) // 1 11 | println(a.substring(0, 2)) // "he" 12 | println(a.substring(0, 3)) // "hel" 13 | println(a.substring(1, 3)) // "el" 14 | 15 | 16 | val b = a.capitalize // b: "Hello, world" 17 | val c = a.toUpperCase // c: "HELLO, WORLD" 18 | 19 | println(b) 20 | println(c) 21 | 22 | 23 | val s = "hello" 24 | println(s(0)) 25 | 26 | for c <- s do println(c) 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Strings-Interpolators/StringInterpolators.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli StringInterpolators.sc 5 | 6 | val firstName = "Alvin" 7 | val lastName = "Alexander" 8 | println(s"$firstName $lastName") 9 | 10 | 11 | println(s"Two plus two equals ${2 + 2}") 12 | println(s"Two times two equals ${2 * 2}") 13 | 14 | 15 | val x = s"Two plus two equals ${2 + 2}" 16 | println(x) 17 | 18 | 19 | val time = "04:52:51:541" 20 | val logLevel = "INFO" 21 | val classname = "Bar" 22 | val msg = "this is an info message from class Bar" 23 | println(f"$time | $logLevel%-5s | $classname | $msg") 24 | 25 | -------------------------------------------------------------------------------- /Strings-Multiline/StringsMultiline.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli StringsMultiline.sc 5 | 6 | 7 | val address1 = """ 8 | Alvin Alexander 9 | 123 Main Street 10 | Talkeetna, AK 99676 11 | """ 12 | println(address1) 13 | 14 | 15 | // i added a 'trim' method call to the end of the string 16 | // here so you can experiment with that 17 | val address2 = """ 18 | |Alvin Alexander 19 | |123 Main Street 20 | |Talkeetna, AK 99676 21 | """.stripMargin.trim 22 | println(address2) 23 | 24 | 25 | val address3 = """ 26 | #Alvin Alexander 27 | #123 Main Street 28 | #Talkeetna, AK 99676 29 | """.stripMargin('#') 30 | println(address3) 31 | 32 | val name = "Alvin Alexander" 33 | val street = "123 Main Street" 34 | val city = "Talkeetna" 35 | val state = "AK" 36 | val zip = "99676" 37 | val address4 = s""" 38 | |$name 39 | |$street 40 | |$city, $state $zip 41 | """.stripMargin 42 | println(address4) 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Tests/P1.sc: -------------------------------------------------------------------------------- 1 | args.foreach(println) 2 | 3 | -------------------------------------------------------------------------------- /Tests/PrintAll.sc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S scala-cli shebang 2 | args.foreach(println) 3 | 4 | -------------------------------------------------------------------------------- /TryCatchFinally/TryCatchFinally.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli TryCatchFinally.sc 5 | 6 | 7 | // this example is not in the book. 8 | // it shows how to catch a NumberFormatException 9 | // when you’re trying to convert a String to an 10 | // Int: 11 | 12 | val a = "one" 13 | 14 | try 15 | val i = a.toInt 16 | println(s"i = $i") 17 | catch 18 | case e: NumberFormatException => 19 | println(e) 20 | finally 21 | println("Came to the 'finally' clause") 22 | 23 | 24 | -------------------------------------------------------------------------------- /TryCatchFinally2/TryCatchFinally2.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli TryCatchFinally2.sc 5 | 6 | 7 | import scala.util.{Try, Success, Failure} 8 | import scala.io.{BufferedSource, Source} 9 | 10 | def readTextFile(filename: String): Try[String] = 11 | var source: BufferedSource = null 12 | try 13 | source = Source.fromFile(filename) 14 | val lines = for line <- source yield line 15 | Success(lines.mkString) 16 | catch 17 | case t: Throwable => Failure(t) 18 | finally 19 | if source != null then source.close 20 | 21 | val maybeContents = readTextFile("/etc/passwd") 22 | maybeContents match 23 | case Success(contents) => println(contents) 24 | case Failure(exception) => System.err.println(exception.getMessage) 25 | -------------------------------------------------------------------------------- /Tuples/Tuples.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli Tuples.sc 5 | 6 | val a = (1, "yo") 7 | println(a) 8 | 9 | val b = (1, "1", '1', 1.1) 10 | println(b) 11 | 12 | 13 | val t = (42, "fish") 14 | println(t(0)) 15 | println(t(1)) 16 | println(t.size) 17 | -------------------------------------------------------------------------------- /Using-Scala-CLI/Hello.scala: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | @main def hello = println("Hello") 4 | 5 | -------------------------------------------------------------------------------- /Using-Scala-CLI/HelloWorld.sc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S scala-cli shebang 2 | //> using scala "3" 3 | 4 | println("Hello, world") 5 | 6 | -------------------------------------------------------------------------------- /Using-Scala-CLI/MyScript.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | args.foreach(println) 4 | 5 | -------------------------------------------------------------------------------- /Using-Scala-CLI/PrintAll.sc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S scala-cli shebang 2 | //> using scala "3" 3 | 4 | args.foreach(println) 5 | 6 | -------------------------------------------------------------------------------- /if-then-else/IfThenElse.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli IfThenElse.sc 5 | 6 | val a = 1 7 | val b = 2 8 | val c = 3 9 | val d = 4 10 | 11 | if a == b then 12 | println("a equals b") 13 | else if a == c then 14 | println("a equals c:") 15 | else if a == d then 16 | println("a equals d:") 17 | else 18 | println("hmm, something else ...") 19 | end if 20 | 21 | 22 | -------------------------------------------------------------------------------- /println/Println.sc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S scala-cli shebang 2 | 3 | //> using scala "3" 4 | 5 | // run this code with this command: 6 | // $ scala-cli Println.sc 7 | // $ scala-cli Println.sc -- foo bar 8 | 9 | println("Hello, world") 10 | System.err.println("An error message") 11 | 12 | // print any command-line arguments that are given to this script. 13 | // 'args' is a special, implicit variable created for you by 14 | // Scala CLI. 15 | args.foreach(println) 16 | 17 | -------------------------------------------------------------------------------- /val-fields/ValFields.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli ValFields.sc 5 | 6 | val firstName = "Alvin" 7 | println(firstName) 8 | 9 | val lastName = "Alexander" 10 | val fullName = firstName + " " + lastName 11 | println(fullName) 12 | 13 | 14 | // attempt to reassign a val 15 | val x = 1 16 | // x = 2 // this would be an error 17 | 18 | 19 | // experiments 20 | val a = 1 21 | val b = (a + 2) * 2 22 | // b = 7 // this is an intentional error 23 | val c = "hello" 24 | 25 | -------------------------------------------------------------------------------- /var-fields/VarFields.sc: -------------------------------------------------------------------------------- 1 | //> using scala "3" 2 | 3 | // run this code with this command: 4 | // $ scala-cli VarFields.sc 5 | 6 | // assign a value to 'name' 7 | var name = "Reginald Kenneth Dwight" 8 | 9 | // some time later, give 'name' a new value 10 | name = "Elton John" 11 | println(name) 12 | 13 | 14 | // name = 1 // compiler error 15 | 16 | 17 | // more examples 18 | var x = 1 19 | x = 2 20 | x = 3 21 | println(x) 22 | 23 | --------------------------------------------------------------------------------