我刚刚开始研究即将发布的2.8版本中的Scala集合库重新实现。熟悉2.7版本的库的人会注意到,从使用角度来看,库的变化很小。例如

> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)

…两种版本都可以。这个图书馆非常有用:事实上它非常棒。然而,那些以前不熟悉Scala并四处摸索以了解该语言的人现在必须理解方法签名,如:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

对于这样简单的功能,这是一个令人望而生畏的签名,我发现自己很难理解。我并不认为Scala有可能成为下一个Java(或/C/C++/C#)-我不相信它的创造者是瞄准这个市场的-但我认为Scala成为下一代Ruby或Python(即获得大量商业用户)是可行的

这会让人们不去斯卡拉吗?这会不会让斯卡拉在商业界名声扫地,因为它是一种只有专业的博士生才能理解的学术游戏?首席技术官和软件负责人会被吓跑吗?图书馆重新设计是否明智?如果你在商业上使用Scala,你会担心吗?您是否计划立即采用2.8版本,还是等待结果?

Steve Yegge曾攻击Scala(在我看来是错误的),因为他认为Scala的类型系统过于复杂。我担心有人会用这个API来传播FUD(类似于Josh Bloch如何吓得JCP不敢向Java添加闭包)。

注意-我应该清楚,虽然我认为约书亚·布洛赫在拒绝BGGA关闭提案方面有影响力,但我不认为这是因为他诚实地认为该提案代表了错误。


尽管我的妻子和同事一直在告诉我,我并不认为自己是个白痴:我在牛津大学获得了很好的数学学位,我已经在商业编程近12年,在Scala编程大约一年(也是商业编程)。

请注意,煽动性主题标题引用了20世纪80年代初英国一个政党的宣言。这个问题是主观的,但这是一个真实的问题,我已经把它改成了CW,我想就此事发表一些意见。


当前回答

我根本不懂Scala,但几周前我还不会读Clojure。现在我能读到大部分,但除了最简单的例子之外,我还写不出任何东西。我想Scala也没什么不同。你需要一本好书或一门课程,这取决于你的学习方式。只是看了上面的地图声明,我大概得到了其中的1/3。

我认为,更大的问题不在于这些语言的语法,而在于采用和内化使它们在日常生产代码中可用的范例。对我来说,Java并不是C++的巨大飞跃,也不是C的巨大飞跃。Pascal和Basic等根本不是Java的飞跃。但用Clojure这样的函数式语言编写代码是一个巨大的飞跃(对我来说)。我想在Scala中,你可以用Java风格或Scala风格编写代码。但在Clojure中,您将创建一个相当混乱的环境,试图让您的命令习惯远离Java。

其他回答

嗯,我可以理解你的痛苦,但坦率地说,像你和我这样的人——或者几乎任何一个普通的StackOverflow用户——都不是规则。

我的意思是。。。大多数程序员都不会在意类型签名,因为他们永远不会看到它们!他们不阅读文档。

只要他们看到了代码如何工作的一些示例,并且代码不会使他们无法产生他们期望的结果,他们就永远不会查看文档。当失败时,他们将查看文档并期望在顶部看到用法示例。

考虑到这些,我认为:

任何人(像大多数人一样)遇到这种类型签名时,如果事先对Scala进行了处理,就会对其进行无限的嘲笑,如果他们喜欢Scala,就会认为它是Scala力量的象征。如果文档没有得到增强以提供使用示例,并清楚地解释方法的用途和使用方法,那么可能会有点影响Scala的采用。从长远来看,这无关紧要。Scala可以做这样的事情,这将使为Scala编写的库更加强大,使用起来更加安全。这些库和框架将吸引熟悉强大工具的程序员。喜欢简单和直接的程序员将继续使用PHP或类似的语言。

唉,Java程序员非常热衷于强大的工具,所以,在回答这个问题时,我刚刚修正了我对主流Scala采用的期望。我毫不怀疑Scala会成为主流语言。不是C主流,但可能是Perl主流或PHP主流。

说到Java,您曾经替换过类加载器吗?你有没有调查过这涉及到什么?如果你看看框架编写者所做的事情,Java可能会很可怕。只是大多数人都不知道。这同样适用于Scala,IMHO,但早期采用者倾向于在他们遇到的每一块岩石下寻找,看看是否有什么隐藏在那里。

C++中的相同内容:

template <template <class, class> class C,
          class T,
          class A,
          class T_return,
          class T_arg
              >
C<T_return, typename A::rebind<T_return>::other>
map(C<T, A> &c,T_return(*func)(T_arg) )
{
    C<T_return, typename A::rebind<T_return>::other> res;
    for ( C<T,A>::iterator it=c.begin() ; it != c.end(); it++ ){
        res.push_back(func(*it));
    }
    return res;
}

我不知道该怎么告诉你,但我有剑桥大学的博士学位,我用的是2.8。

更严重的是,我几乎没有花时间使用2.7(它不会与我正在使用的Java库互操作),一个多月前才开始使用Scala。我对Haskell有一些经验(不多),但只是忽略了你担心的东西,并寻找与我的Java经验相匹配的方法(我以Java为生)。

所以:我是一个“新用户”,我并没有被推迟——事实上,它的工作方式与Java类似,这给了我足够的信心,可以忽略我不理解的部分。

(然而,我之所以选择Scala,部分原因是想看看是否要在工作中推动它,我现在还不打算这么做。让文档变得不那么吓人肯定会有所帮助,但让我惊讶的是,它仍在不断变化和开发中(公平地说,最让我吃惊的是它是多么棒,但变化紧随其后)。所以我想我想说的是,我更希望把有限的资源投入到最终的状态中——我认为他们不会期望很快就会如此流行。)

我认为该方法的主要问题是(隐式bf:CanBuildFrom[Rrep,B,that])没有任何解释。尽管我知道什么是隐式参数,但没有任何信息表明这会如何影响调用。浏览scaladoc只会让我更加困惑(很少有与CanBuildFrom相关的类甚至有文档)。

我认为一个简单的“bf的作用域中必须有一个隐式对象,它为B类型的对象提供了一个构建器”会有所帮助,但当您真正想做的是将a映射到B时,这是一个令人兴奋的概念。事实上,我不确定这是对的,因为我不知道Repr类型是什么意思,而Traversable的文档也毫无头绪。

所以,我有两个选择,都不令人满意:

假设它只适用于旧地图的工作方式以及地图在大多数其他语言中的工作方式深入了解源代码

我认为Scala本质上是在揭示这些东西是如何工作的,最终这是提供了一种实现oxbow_lakes所描述的方法。但签名会分散注意力。

我根本不懂Scala,但几周前我还不会读Clojure。现在我能读到大部分,但除了最简单的例子之外,我还写不出任何东西。我想Scala也没什么不同。你需要一本好书或一门课程,这取决于你的学习方式。只是看了上面的地图声明,我大概得到了其中的1/3。

我认为,更大的问题不在于这些语言的语法,而在于采用和内化使它们在日常生产代码中可用的范例。对我来说,Java并不是C++的巨大飞跃,也不是C的巨大飞跃。Pascal和Basic等根本不是Java的飞跃。但用Clojure这样的函数式语言编写代码是一个巨大的飞跃(对我来说)。我想在Scala中,你可以用Java风格或Scala风格编写代码。但在Clojure中,您将创建一个相当混乱的环境,试图让您的命令习惯远离Java。