path | title |
---|---|
/learnings/scala |
Learnings: Scala |
- Scala
- interactive REPL
- Variables:
- syntax
- Function
- Generics
- Arrays
- operator silliness
- Nil
- mutable CSS immutable data structures
- Class
- main method in Scala
- Pattern Matching
- Implicits
- Tuples
- and the JVM
- literal types
- Currying
- With Maven
- GENERICS
- packages / importing code
- casts
- testing
- TODO: to figure out
- Book Recommendations
var capital = Map("US" -> "Washington", "France" -> "Paris")
val x: HashMap[Int, String] = new HashMap[Int, String]()
Or
val x = new HashMap[Int, String]()
$ Scala
$ Scala demo.scala
- Val - const
- var - let ("ready for writing")
- semicolons optional (but rules about "semicolon inferience")
- any method call can be used in "operator mode": j append myNewThing j appendTwo (myNewThing, secondThing) * can leave off parens on empty method calls * == checks for value equality, eq checks for references equality
val msg3: String = "Hello yet again, world!"
Val msg3 = "hello again"
reach for immutability first
def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}
Notes: * variable: Type * implicit returns (most situations????) * can leave off return type if it's super obvious, also braces if it's one line
def thingy( arg1: String, arg2: Int ): String = {
}
Arg1 => statement
(Arg1: String) => statement
_ can be parameter(s) "blank". you can use this to build up partially applied functions
val r = ( a : Int ) => { "out" }
val r : ( Int ) => String = ( a ) => { "out" }
Vsriables csptured as references, thus readwrite in Swift pariance (but if outer reference reassigned variable in block still points to data)
Csn use name of variable as keyword parameters
If statement takes one arg, and calls function that also only takes one arg, can do
Arts.foreach(statement)
can leave off parens if =< 1 parameter
Array[String]
MyArray(0) = "Yo" <--- not [],
Technically Scala's Areay type overrides 'apply' to achieve this!
Mutable
Operator acts in the object to its left, unless the method name ends with :
Thus 10 / 5 = 2 but 10 /: 5 = 0.5
With a capital N
Just in different namespaces. so could write code like so
Import Scala.collection.mutable
Import Scala.collections.immutable
Val a = Mutable.Map()
class Thing(fName : String, lName: String) {
}
Note that parameters passed in this way are NOT fields
class Thing(fName : String, lName: String) {
val firstName = fName
}
Default access level is public (can use keyword private)
Can not have static members If need static members this is "object". Read as "singleton object" . class + (singleton) object = "companion object " (must be in same source file)
Method parameters are const
The Scala compiler will compile any code you place in the main body of the class in the primary constructor
Auxiliary constructors created by def this(.....) [access primary constructor by this(parameters defined to class declaration)]
object Summer {
def main(args: Array[String]) = {
}
}
"Uniform access method" <-- accessing methods should look like fields, and vs versa.
So could call with syntax that look like direct member access, but can refactor this later to be methods.
(Technically Scala is generating methods for you and calling them, but doesn't matter)
class Thing(@BeanProperty val fName: String)
val
does not create us a setter, because immutable.
implicit class MyStringAdditions(val s: String) {
def happyMethod = ...
}
but need to put this in another class or in a package.
They're called traits
Class mything extends String, MyTrait
OR
class mything extends String with MyTrait
can define methods, keep state
traits gave a type hierarchy too: can define sub classes of a trait and override methods of supertrait or call supertrait implementairon of method
Not just at class definition time, but if you decide some instance of this thing needs to have some trait mixed in "just this once" you CAN.
class DatabaseConnector( string dbURL ) {
lazy var dbConnection = createDBConnection()
def createDBConnections(): DBConnection = {
//...
connection
}
}
Features:
- parameters to constructor are val -> fields.
- auto implements
toString
,hashCode
,equals
for properies (deep comparisons too) - auto creates copy method <-- useful "give me an object like this object, but with one or two fields having different values"
Anti features:
- can not be subclassed
like better switch/case statements : can also use for nil checks
(Mostly) compares whole objects: thus the case object makes sense as the equals operator is auto populated with values from fields).
val t1: (Int, String) = ( 1, "two" )
JVM boot up avoided by daemon fsc you pass file names to compile to it.
Triple quotes. white space can be trimmed off by using stripMargin ability
s
:s"Hello ${woldVar}"
: string interpolation.
Use strip margin and this syntax
var foo = """line one
|line two""".stripMargin
'Thing
#iteration
for (file <- filesHere)
for (file <- filesHere if file.getName.endsWith(".scala"))
Nested <- means you'll have one loop happen then the next
Built in currying!!!
def doThings( firstName : String )( secondName : String ) : String = {
"${firstName} ${secondName}"
}
doThings("Ryan")("Wilcox")
this matters for DSL creation
def doThings( firstName : String) ( dynamicConstructor : ( string ) => bool ) = {
...
}
doThings("Ryan") { => "Wilcox " }
- value types: numeric equality
- reference types:
equals
- boxed or auto boxed numbers:
equals
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<launchers>
<launcher>
<id>sample</id>
<mainClass>com.wilcox.DockerEnvMain</mainClass>
</launcher>
</launchers>
<args>
<!-- work-around for https://issues.scala-lang.org/browse/SI-8358 -->
<arg>-nobootcp</arg>
</args>
</configuration>
</plugin>
</plugins>
<properties>
<scalaVersion>2.12.0</scalaVersion>
<scalaBinaryVersion>2.12</scalaBinaryVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scalaVersion}</version>
</dependency>
$ mvn scala:console
- type erased at runtime, like Java
- declarations using [], not <>
Similar rules to Java, except import blah.* -> import blah._
can appear anywhere in program Can be VARIABLES, not just static class path
myEmployee.asInstanceOf[Person]
coupled with
myEmployee.isInstanceOf(Employee)
both methods on Any
, the global superclass of Scala objects
like Java could throw ClassCastException
consider using a pattern match with a type parameter instead.
Couple different ways to do this in Scala, best(?) way seems to be using implicit classes and having those define new asThinger
, asArk
, asString
methods for the destination class.
(Q: so as
is the prefix, not to
???)
https://www.javacodegeeks.com/2014/07/explicit-implicit-conversion.html
with shapeless you can use / implement cast
method, which gives you more power.
- ScalaTest
- flatSpec : it should "have a height equal to the passed value" in { val ele = elem('x', 2, 3) ele.height should be (3) }
LOOKS AWESOME!! also FeatureSpec that implemts given / when / then syntax
- new statement with {} does ?????!!!
- generics story
- more functional stuff ??
val compatibilityResult: (Boolean, String) = checkCompatibility(vertexConstraint, head.constraints)