有人声称Scala的类型系统是图灵完整的.我的问题是:
这有正式的证据吗?
如何在Scala类型系统中进行简单的计算?
这对Scala有什么好处 - 语言?这是否使Scala在某种程度上比没有图灵完整类型系统的语言更"强大"?
我想这通常适用于语言和类型系统.
我觉得Scala社区对编写"简洁","酷","scala惯用","单行" - 如果可能的代码有一点点的痴迷.接下来是对Java /命令/丑陋代码的比较.
虽然这(有时)导致易于理解的代码,但它也导致99%的开发人员的代码效率低下.这就是Java/C++不容易被击败的地方.
考虑这个简单的问题:给定一个整数列表,删除最大的元素.订购不需要保留.
这是我的解决方案版本(它可能不是最好的,但它是普通的非摇滚明星开发者会做的).
def removeMaxCool(xs: List[Int]) = {
val maxIndex = xs.indexOf(xs.max);
xs.take(maxIndex) ::: xs.drop(maxIndex+1)
}
Run Code Online (Sandbox Code Playgroud)
这是Scala惯用,简洁,并使用一些很好的列表功能.这也是非常低效的.它遍历列表至少3或4次.
这是我完全不那么类似Java的解决方案.这也是一个合理的Java开发人员(或Scala新手)会写的.
def removeMaxFast(xs: List[Int]) = {
var res = ArrayBuffer[Int]()
var max = xs.head
var first = true;
for (x <- xs) {
if (first) {
first = false;
} else {
if (x > max) {
res.append(max)
max = x
} else {
res.append(x)
}
}
}
res.toList
}
Run Code Online (Sandbox Code Playgroud)
完全非Scala惯用,非功能性,非简洁,但它非常有效.它只遍历列表一次!
因此,如果99%的Java开发人员编写的代码比99%的Scala开发人员更有效,那么这对于更好的Scala采用来说是一个巨大的障碍.有没有办法摆脱这个陷阱?
我正在寻找实用的建议,以避免这种"效率低下的陷阱",同时保持实施清晰简洁.
澄清:这个问题来自现实生活场景:我必须编写一个复杂的算法.首先我在Scala中编写它,然后我"必须"用Java重写它.Java实现的时间是原来的两倍,并不是很清楚,但同时它的速度是原来的两倍.重写Scala代码以提高效率可能需要一些时间并且对scala内部效率有更深入的理解(对于映射与折叠等)
许多示例Scala代码包含名为"xs"的字符串和集合.为什么选择xs?
例子:
var xs = List(1,2,3)
val xs = "abc"
Run Code Online (Sandbox Code Playgroud) 调试功能代码肯定比调试命令式代码更棘手.请参阅此处,此处和此处的讨论."功能"调试应该支持检查函数/闭包/ monad的返回值.是否有任何调试器/ IDE具有(计划拥有)检查中间返回值的能力?
例如,要在Scala中调试此行,我应该能够在返回之前逐步执行4次函数调用并检查返回的值 r
val r=(ls filter (_>1) sort (_<_) zipWithIndex) filter {v=>(v._2)%2==0} map{_._1}
Run Code Online (Sandbox Code Playgroud) 为什么类型推断失败?
scala> val xs = List(1, 2, 3, 3)
xs: List[Int] = List(1, 2, 3, 3)
scala> xs.toSet map(_*2)
<console>:9: error: missing parameter type for expanded function ((x$1) => x$1.$times(2))
xs.toSet map(_*2)
Run Code Online (Sandbox Code Playgroud)
但是,如果xs.toSet
已分配,则编译.
scala> xs.toSet
res42: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> res42 map (_*2)
res43: scala.collection.immutable.Set[Int] = Set(2, 4, 6)
Run Code Online (Sandbox Code Playgroud)
此外,走另一条路,转换为Set
从List
,并映射List
规定.
scala> Set(5, 6, 7)
res44: scala.collection.immutable.Set[Int] = Set(5, 6, 7)
scala> res44.toList map(_*2)
res45: List[Int] = List(10, 12, 14)
Run Code Online (Sandbox Code Playgroud) 我可以在Scala REPL中停止执行无限循环吗?键入此并尝试在不退出REPL的情况下停止它.
while(true){}
Run Code Online (Sandbox Code Playgroud)
我认为像Ctrl-C这样的东西会起作用.
当我从命令行运行类似下面的内容时,会发生什么?
> scala hello.scala
Run Code Online (Sandbox Code Playgroud)
是否有生成,执行,然后丢弃的hello.class?或者Scala在这种情况下表现得像某个解释器?我只是想,当然,我不能对Java做同样的事情:
> java hello.java
Run Code Online (Sandbox Code Playgroud) 根据scaladoc,sliding()返回..."迭代器产生大小的可迭代集合size
,除非最后和唯一的元素将被截断,如果元素少于size
."
对我来说,直观地说,如果可用,滑动(n)将返回n个元素的滑动窗口.对于当前的实现,我需要执行额外的检查以确保我没有获得1或2个元素的列表.
scala> val xs = List(1, 2)
xs: List[Int] = List(1, 2)
scala> xs.sliding(3).toList
res2: List[List[Int]] = List(List(1, 2))
Run Code Online (Sandbox Code Playgroud)
我希望这里有一个空列表.为什么用这种方式实现sliding()呢?
我试图通过数据采集器上的spark-shell使用spark-cassandra-connector,但是我无法连接到我的集群.似乎版本不匹配,因为类路径包含来自其他地方的更古老的番石榴版本,即使我在启动时指定了正确的版本.我怀疑这可能是由默认情况下放入类路径的所有Hadoop依赖项引起的.
反正有没有火花壳只使用适当版本的番石榴,而没有摆脱所有与Hadoop相关的数据包包括罐子?
相关数据:
启动spark-shell,显示它具有适当版本的Guava: $ spark-shell --packages com.datastax.spark:spark-cassandra-connector_2.10:1.5.0-M3
:: loading settings :: url = jar:file:/usr/lib/spark/lib/spark-assembly-1.5.2-hadoop2.7.1.jar!/org/apache/ivy/core/settings/ivysettings.xml
com.datastax.spark#spark-cassandra-connector_2.10 added as a dependency
:: resolving dependencies :: org.apache.spark#spark-submit-parent;1.0
confs: [default]
found com.datastax.spark#spark-cassandra-connector_2.10;1.5.0-M3 in central
found org.apache.cassandra#cassandra-clientutil;2.2.2 in central
found com.datastax.cassandra#cassandra-driver-core;3.0.0-alpha4 in central
found io.netty#netty-handler;4.0.27.Final in central
found io.netty#netty-buffer;4.0.27.Final in central
found io.netty#netty-common;4.0.27.Final in central
found io.netty#netty-transport;4.0.27.Final in central
found io.netty#netty-codec;4.0.27.Final in central
found com.codahale.metrics#metrics-core;3.0.2 in central
found org.slf4j#slf4j-api;1.7.5 in central
found org.apache.commons#commons-lang3;3.3.2 in central
found com.google.guava#guava;16.0.1 in central
found org.joda#joda-convert;1.2 in central
found …
Run Code Online (Sandbox Code Playgroud) apache-spark spark-cassandra-connector google-cloud-dataproc
我需要使用一个类型(任何类型)作为隐式的标记作为类型参数,以区别于另一个隐式.这很奇怪,但这可能是另一个问题.
由于我可以使用任何类型,我在考虑使用最便宜的内存占用和初始化时间.在这种情况下,它可能不会对性能造成太大影响,但问题很有趣:哪一个是Scala最便宜的类型?
在Java中,答案很明显java.lang.Object
.但是Scala有一些"有趣"的类型:Any
,AnyVal
类型和底部类型,可能会围绕它们进行优化.该Nothing
类型无法实例化,因此从此比较中排除.