// WrapCounter counts up to a max value based on a bit size classWrapCounter(counterBits: Int) {
val max: Long = (1 << counterBits) - 1 var counter = 0L
definc(): Long = { counter = counter + 1 if (counter > max) { counter = 0 } counter } println(s"counter created with max value $max") }
Instance
1 2
val x = newWrapCounter(2) x.inc()
Fields
val: immutable
var: mutable
Methods
Declaration
1 2 3 4 5 6
// These are normal functions. defplus1funct(x: Int): Int = x + 1 // These are functions as vals. // The first one explicitly specifies the return type. val plus1val: Int => Int = x => x + 1// val plus1val: (Int => Int) = { x => x + 1 } val times2val = (x: Int) => x * 2
Overloading Functions
1 2 3 4 5
deftimes2(x: Int): Int = 2 * x deftimes2(x: String): Int = 2 * x.toInt
times2(5) times2("7")
Recursive and Nested Functions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/** Prints a triangle made of "X"s * This is another style of comment */ defasciiTriangle(rows: Int) {
// This is cute: multiplying "X" makes a string with many copies of "X" defprintRow(columns: Int): Unit = println("X" * columns)
if(rows > 0) { printRow(rows) asciiTriangle(rows - 1) // Here is the recursive call } }
// printRow(1) // This would not work, since we're calling printRow outside its scope asciiTriangle(6)
Collection
List
1 2 3 4 5 6 7 8 9
val list1 = List(1, 2, 3) val list2 = 1 :: 2 :: 3 :: Nil
val third = list1(2) val list3 = list1 ++ list2 // Appends val m = list2.length val s = list2.size val headOfList = list1.head // Gets the first element val restOfList = list1.tail // Get a new list with first element removed
if (done) { // The braces are not required when **all** branches are one liners println("we are done") } elseif (numberOfKittens < kittensPerHouse) { println("more kittens!") numberOfKittens += 1 } else { done = true } // "if" conditional returns a value, given by the last line of the selected branch
for statement
1 2 3 4
for (i <- 0 to 7) { print(i + " ") } // 0 - 7 for (i <- 0 until 7) { print(i + " ") } // 0 - 6 for (i <- 0 to 10 by 2) { print(i + " ") } // 0 - 10 by 2 for (value <- randomList) { print(i + " ") } // from list
Packages
package
1 2
package mytools classTool1{ ... }
import
1 2 3
import mytools.Tool1 import chisel3._ // all classes an methods from chisel3 import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester} // specific classes
Object Oriented
Variables are objects.
Constants in the sense of Scala’sval declarative are also objects.
Even literal values are objects.
Even functions themselves are objects. More on this later.
Objects are instances of classes.
In fact, in just about every way that matters in Scala, the object in Objected Oriented will be called an instance.
In defining classes, the programmer specifies:
The data (val, var) associated with the class.
The operations, called methods or functions, that instances of the class can perform.
Classes can extend other classes.
The class being extended is the superclass; the extendee is the subclass.
In this case, the subclass inherits the data and methods from the superclass.
There are many useful but controlled ways in which a class may extend or override inherited properties.
Classes may inherit from traits. Think of traits as lightweight classes that allow specific, limited ways of inheriting from more than one superclass.
(Singleton) Objects are a special kind of Scala class.
They are not objects as above. Remember, we’re calling those instances.