Seven languages in seven weeks (notes on Scala)
Scala
unifying functional and object-oriented programming
A functional language has these characteristics:
• Functional programs are made up of functions.
• A function always returns a value.
• A function, given the same inputs, will return the same values.
• Functional programs avoid changing state or mutating data. Once you’ve set a value, you have to leave it alone.
Strictly speaking, Scala is not a pure functional programming language, just like C++ is not a pure object-oriented language.
Functional Programming and Concurrency
... Functional programming languages can solve these problems by eliminating mutable state from the equation. Scala does not force you to completely eliminate mutable state, but it does give you the tools to code things in a purely functional style.
(with some small exceptions) everything is an object in Scala: Integers and Strings are all objects. Scala is strongly typed (strong, static typing)
(Statically typed languages enforce polymorphism based on the structure of the types. Is it a duck by the genetic blueprint (static), or is it a duck because it quacks or walks like one? Statically typed languages benefit because compilers and tools know more about your code to trap errors, highlight code, and refactor. The cost is having to do more work and living with some restrictions.)
scala> val a = 1
a: Int = 1
scala> val b = 2
b: Int = 2
scala> if ( b < a) {| println("true")| } else {| println("false")| }
false
no need to specify a type; Scala can infer the type, and bind types at compile time. ("val a:Int = 1" is fine, too)
"val" is immutable; "var" is not
"Nil" is an empty list. Neither "Nil" or "0" is a Boolean. (In Ruby, 0 evaluated to true; in C, 0 was false)
Loops:
def whileLoop {var i = 1while(i <= 3) {println(i)i += 1}
}
whileLoop
def forLoop {println( "for loop using Java-style iteration" )for(i <- 0 until args.length) {println(args(i))}
}forLoop
def rubyStyleForLoop {println( "for loop using Ruby-style iteration" )args.foreach { arg => println(arg)}
}rubyStyleForLoop
Range:
Like Ruby, Scala supports first-class ranges
scala> val range = 0 until 10
range: Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> range.start
res2: Int = 0
scala> range.end
res3: Int = 10
scala> range.step
res4: Int = 1
scala> (0 to 10) by 5
res6: Range = Range(0, 5, 10)
scala> (0 to 10) by 6
res7: Range = Range(0, 6)
scala> (0 until 10 by 5)
res0: Range = Range(0, 5)
scala> val range = (10 until 0) by -1
range: Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
scala> val range = 'a' to 'e'
range: RandomAccessSeq.Projection[Char] = RandomAccessSeq.Projection(a, b, c, d, e)
Tuple:
scala> val person = ("Elvis", "Presley")
person: (java.lang.String, java.lang.String) = (Elvis,Presley)
scala> person._1
res9: java.lang.String = Elvis
scala> val (x, y) = (1, 2)
x: Int = 1
y: Int = 2
Class
scala> class Person(firstName: String, lastName: String)
defined class Person
scala> val gump = new Person("Forrest", "Gump")
gump: Person = Person@7c6d75b6
Constructor:
class Person(firstName: String) {println("Outer constructor")def this(firstName: String, lastName: String) {this(firstName)println("Inner constructor")}def talk() = println("Hi")
}
val bob = new Person("Bob")
val bobTate = new Person("Bob", "Tate")
batate$ scala code/scala/constructor.scala
Outer constructor
Outer constructor
Inner constructor
When there’s something that can have only one instance, you’ll define it with the object keyword instead of the class keyword.
object TrueRing {def rule = println("To rule them all")
}
TrueRing.rule
The TrueRing definition works exactly like any class definition, but it creates a singleton object.
Inheritance:
class Person(val name: String) {def talk(message: String) = println(name + " says " + message)def id(): String = name
}class Employee(override val name: String, val number: Int) extends Person(name) {override def talk(message: String) {println(name + " with number " + number + " says " + message)}override def id():String = number.toString
} val employee = new Employee("Yoda", 4)
employee.talk("Extend or extend not. There is no try.")
Scala uses a concept called companion objects to mix class and instance methods on the same class. Where Ruby uses mixins and Java uses interfaces, Scala uses a structure like a mixin called a Trait .
Trait:
class Person(val name:String)trait Nice {def greet() = println("Howdily doodily.")
}class Character(override val name:String) extends Person(name) with Niceval flanders = new Character("Ned")
flanders.greet
Above is about OO, below is about Functional Programming.
Function declarations:
scala> def double(x:Int):Int = x * 2
double: (Int)Int
scala> double(4)
res0: Int = 8
scala> def double(x:Int):Int = {| x * 2| }
double: (Int)Int
scala> double(6)
res3: Int = 12
Mutable state is bad. When you declare variables, you should make them immutable whenever you can to avoid conflicting state. In Java, that means using the final keyword. In Scala, immutable means using val instead of var:
scala> var mutable = "I am mutable"
mutable: java.lang.String = I am mutable
scala> mutable = "Touch me, change me..."
mutable: java.lang.String = Touch me, change me...
scala> val immutable = "I am not mutable"
immutable: java.lang.String = I am not mutable
scala> immutable = "Can't touch this"
<console>:5: error: reassignment to valimmutable = "Can't touch this"^
It’s best to avoid var when you can for better concurrency. This basic design philosophy is the key element that differentiates functional programming from object-oriented programming: mutable state limits concurrency.
Scala’s primary collections are lists, sets, and maps.
scala> List(1, 2, 3)
res4: List[Int] = List(1, 2, 3)
scala> List("one", "two", 3)
res6: List[Any] = List(one, two, 3)
scala> List("one", "two", 3)(2)
res7: Any = 3
List access is a function, so you use () instead of [] . Scala’s index for list starts with 0, as it does with Java and Ruby.
Nil in Scala is an empty list:
scala> Nil
res33: Nil.type = List()
(omit Set, Map ...)
Foldleft:
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> val sum = (0 /: list) {(sum, i) => sum + i}
sum: Int = 6
/: is an operator with initialValue /: codeBlock
The syntax of the other version of foldLeft will seem strange to you. It uses a concept called currying. Functional languages use currying to transform a function with multiple parameters to several functions with their own parameter lists. Just understand that what’s going on under the covers is a composition of functions rather than a single function.
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> list.foldLeft(0)((sum, value) => sum + value)
res54: Int = 6
XML as a first-class programming construct:
scala> val movies =| <movies>| <movie genre="action">Pirates of the Caribbean</movie>| <movie genre="fairytale">Edward Scissorhands</movie>| </movies>
movies: scala.xml.Elem =
<movies><movie genre="action">Pirates of the Caribbean</movie><movie genre="fairytale">Edward Scissorhands</movie>
</movies>
scala> movies.text
res1: String =Pirates of the CaribbeanEdward Scissorhands
scala> val movieNodes = movies \ "movie"
movieNodes: scala.xml.NodeSeq =<movie genre="action">Pirates of the Caribbean</movie><movie genre="fairytale">Edward Scissorhands</movie>
scala> movieNodes(0)res3: scala.xml.Node = <movie genre="action">Pirates of the Caribbean</movie>
scala> movieNodes(0) \ "@genre"res4: scala.xml.NodeSeq = action
Pattern Matching and Guards:
def factorial(n: Int): Int = n match {case 0 => 1case x if x > 0 => factorial(n - 1) * n
}
println(factorial(3))
println(factorial(0))
Scala has first-class regular expressions. The .r method on a string can translate any string to a regular expression.
scala> val reg = """^(F|f)\w * """.r
reg: scala.util.matching.Regex = ^(F|f)\w *
scala> println(reg.findFirstIn("Fantastic"))
Some(Fantastic)
scala> println(reg.findFirstIn("not Fantastic"))
None
XML with matching:
val movies = <movies><movie>The Incredibles</movie><movie>WALL E</movie><short>Jack Jack Attack</short><short>Geri's Game</short>
</movies>(movies \ "_").foreach { movie =>movie match {case <movie>{movieName}</movie> => println(movieName)case <short>{shortName}</short> => println(shortName + " (short)") }
}
Concurrency
The primary constructs are actors and message passing. Actors have pools of threads and queues. When you send a message to an actor (using the ! operator), you place an object on its queue. The actor reads the message and takes action. Often, the actor uses a pattern matcher to detect the message and perform the appropriate message.
import scala.actors._
import scala.actors.Actor._case object Poke
case object Feedclass Kid() extends Actor {def act() {loop {react {case Poke => {println("Ow...")println("Quit it...")}case Feed => {println("Gurgle...")println("Burp...")}}}}
}val bart = new Kid().start
val lisa = new Kid().start
println("Ready to poke and feed...")
bart ! Poke
lisa ! Poke
bart ! Feed
lisa ! Feed
to do things asynchronously:
import scala.io._
import scala.actors._
import Actor._// START:loader
object PageLoader {def getPageSize(url : String) = Source.fromURL(url).mkString.length
}
// END:loaderval urls = List("http://www.amazon.com/", "http://www.twitter.com/","http://www.google.com/","http://www.cnn.com/" )// START:time
def timeMethod(method: () => Unit) = {val start = System.nanoTimemethod()val end = System.nanoTimeprintln("Method took " + (end - start)/1000000000.0 + " seconds.")
}
// END:time// START:sequential
def getPageSizeSequentially() = {for(url <- urls) {println("Size for " + url + ": " + PageLoader.getPageSize(url))}
}
// END:sequential// START:concurrent
def getPageSizeConcurrently() = {val caller = selffor(url <- urls) {actor { caller ! (url, PageLoader.getPageSize(url)) }}for(i <- 1 to urls.size) {receive {case (url, size) =>println("Size for " + url + ": " + size) }}
}
// END:concurrent// START:script
println("Sequential run:")
timeMethod { getPageSizeSequentially }println("Concurrent run")
timeMethod { getPageSizeConcurrently }
// END:script
The "receive" method is where the real work happens.
Core strengths:
1. Concurrency
2. Evolution of legacy Java
3. Domain-specific languages
4. XML
5. Bridging (functional programming and OO)
Weaknesses:
1. Static typing
2. Syntax
3. Mutability
Seven languages in seven weeks (notes on Scala)相关推荐
- scala不可变和可变_Scala使期货变得轻松
scala不可变和可变 by Martin Budi 马丁·布迪(Martin Budi) Scala使期货变得轻松 (Futures Made Easy with Scala) Future is ...
- 机器学习关键的几门课程_互联网上每门机器学习课程,均按您的评论排名
机器学习关键的几门课程 by David Venturi 大卫·文图里(David Venturi) 互联网上每门机器学习课程,均按您的评论排名 (Every single Machine Learn ...
- 凭什么说这门编程语言是下一代 Java?
问世于 1987 年的面向并发的编程语言 Erlang,比 Java 和 Ruby 等老牌语言都要出现得早,但是彼时的 Erlang 并不被业界广泛地熟知,因为在其发布的十年间,它只作为商业产品出售且 ...
- 电影旅行敲代码的To Do List
待写博客列表 Data Structure & Algorithm 题目 说明 完成 反馈集问题 https://ac.els-cdn.com/S0166218X00003395/1-s2.0 ...
- 【译文】程序语言简史
1801 - Joseph Marie Jacquard用打孔卡为一台织布机编写指令,在挂毯上织出了"hello, world"字样.当时的reddit网友对这项工作的反响并不热烈 ...
- 历届JOLT图书奖整理
原文地址 中文版–豆瓣链接 Jolt大奖素有"软件业界的奥斯卡"之美誉.苦于查不到历史记录,故作部分整理. 由于从2002年及之后,至2008年为止,书籍类奖项分为通用类和技术类进 ...
- IT类英文电子书存档页面
为什么80%的码农都做不了架构师?>>> http://www.salttiger.com/archives/ 目前我主要在以下两个网站收集编程类的电子书,在这上面找不到的书, ...
- Java8中Lambda表达式的10个例子
Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 Java代码 //Before Java 8: new Thread(new Runnable() ...
- 10个Java 8 Lambda表达式经典示例
Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表 达式,它将允许我们将行为传到函数里.在J ...
- 浅谈lambda表达式最通俗易懂的讲解
来自:开源中国(作者:青衣霓裳) 原文链接: https://my.oschina.net/u/4006148/blog/3078359 Java8发布已经有一段时间了,这次发布的改动比较大,很多人将 ...
最新文章
- 点击后,过段时间cell自动取消选中
- js实现一键复制到剪切板上_你的“剪切板”正在被网赚者控制
- address标签,为网页加入地址信息
- 实现一个登录:Mac+.NET 5+Identity+JWT+VS Code
- C++递归方法实现全排列
- 热点:阿里云推国内首个高级政务云平台
- Kettle详细使用教程
- mac的截图命令screencapture
- 彻底弄懂 Nginx location 匹配
- 蚂蚁区块链使用搭建方法
- 开发一款游戏引擎需要的知识与技术
- Newton 3 牛顿动力学插件 - 主体属性面板
- C# ERP开发框架
- 邮箱个性签名html模板,邮件个性签名大全_邮件的经典个性签名模板
- 通过命令行玩转Git,需要记住那些命令?
- CodeBlocks如何将英文环境改为中文
- 大学计算机实验6实验报告,东华大学计算机病毒课实验六宏病毒实验报告
- 红米k40刷鸿蒙系统,红米K40开孔仅2.8mm,全球最小或命名为无感孔,到底有多极致...
- 最受欢迎的健身软件推荐合集
- 使用easypoi导出excel实现动态列