代码之家  ›  专栏  ›  技术社区  ›  tsimon

scala 2.8收藏库是“历史上最长的自杀笔记”的案例吗?[关闭]

  •  834
  • tsimon  · 技术社区  · 6 年前

    我刚开始看 Scala collections library re-implementation 即将到来的 二点八 释放。那些熟悉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
    

    对于如此简单的功能,这是一个令人望而生畏的签名,我发现自己很难理解它。 不是我认为斯卡拉有可能成为下一个爪哇 (OR/C/C++/C)——我不相信它的创建者瞄准了那个市场——但是我认为Scala成为下一个Ruby或Python(即获得一个重要的商业用户基础)当然是可行的。

    • 这会推迟人们去斯卡拉吗?
    • 这会让斯卡拉在商业界名声不好吗? 学术游戏 只有专注的博士生才能理解?是 CTO 软件主管会害怕吗?
    • 图书馆是否重新设计了一个明智的想法?
    • 如果你在商业上使用scala,你担心吗?你打算立即采用2.8还是等着看会发生什么?

    Steve Yegge once attacked Scala (我错误地认为)他认为这是一个过于复杂的类型系统。我担心有人会有一天的农耕日 FUD 使用这个API(类似于Josh Bloch如何害怕 JCP 不要向Java添加闭包。

    注意 - 我应该清楚,虽然我相信 Joshua Bloch 在拒绝BGGA关闭提议方面具有影响力,我不认为这是因为他诚实地认为该提议代表了一个错误。


    不管我妻子和同事告诉我什么,我都不认为我是个白痴:我有一个很好的数学学位 University of Oxford 我已经商业化编程了将近12年 Scala 一年左右(也在商业上)。

    注意,发炎主题标题是 quotation made about the manifesto of a UK political party 20世纪80年代初 . 这个问题是主观的,但它是一个真实的问题,我已经提出了,我想对这个问题发表一些看法。

    18 回复  |  直到 9 年前
        1
  •  858
  •   slashnick Epirocks    12 年前

    我希望这不是“自杀笔记”,但我明白你的意思。你同时发现了什么是斯卡拉的力量和问题:它 可扩展性 . 这使我们能够在库中实现最主要的功能。在其他一些语言中,序列 map collect 它是内置的,没有人必须看到编译器为了使它们顺利工作而必须经历的所有的循环。在scala中,它都在一个库中,因此是开放的。

    实际上 地图 它的复杂类型支持这一点是相当高级的。考虑一下:

    scala> import collection.immutable.BitSet
    import collection.immutable.BitSet
    
    scala> val bits = BitSet(1, 2, 3)
    bits: scala.collection.immutable.BitSet = BitSet(1, 2, 3)
    
    scala> val shifted = bits map { _ + 1 }
    shifted: scala.collection.immutable.BitSet = BitSet(2, 3, 4)
    
    scala> val displayed = bits map { _.toString + "!" }
    displayed: scala.collection.immutable.Set[java.lang.String] = Set(1!, 2!, 3!)
    

    看看你怎么总是得到最好的类型?如果你映射 Int S to int 你又得到了一个 BitSet 但是如果你在地图上 int S to String S,你得到一个将军 Set .映射结果的静态类型和运行时表示形式都取决于传递给它的函数的结果类型。即使集合是空的,也可以这样做,所以函数永远不会被应用!据我所知,没有其他具有同等功能的收集框架。然而,从用户的角度来看,事情是这样的 想象上的 工作。

    我们所面临的问题是,所有使这种情况发生的聪明技术都会泄漏到类型签名中,而类型签名变得巨大而可怕。但在默认情况下,可能不应显示用户的完整类型签名 地图 ?如果她抬头看看呢 地图 在里面 位集合 她得到:

    map(f: Int => Int): BitSet     (click here for more general type)
    

    在这种情况下,文档不会说谎,因为从用户的角度来看,确实map具有 (Int => Int) => BitSet . 但是 地图 还有一个更通用的类型,可以通过单击另一个链接来检查。

    我们还没有在工具中实现这样的功能。但我相信我们需要这样做,以避免吓跑人们,并提供更多有用的信息。有了这样的工具,希望智能框架和库不会变成自杀笔记。

        2
  •  215
  •   Jörg W Mittag    9 年前

    我既没有博士学位,也没有其他任何学位,既没有理科硕士学位,也没有数学学位,甚至没有其他任何领域的学位。我没有使用scala或其他类似语言的经验。我甚至没有远程可比类型系统的经验。事实上,我唯一拥有的语言不仅仅是一种肤浅的知识,甚至 一个类型系统是帕斯卡,并不完全以其复杂的类型系统而闻名。(尽管它 有范围类型,这是阿法克几乎没有其他语言,但这在这里并不真正相关。)我知道的其他三种语言是基本语言,smalltalk和ruby,它们都没有类型系统。

    然而,我完全可以理解 map 你发布的功能。在我看来,签名和 地图 用我见过的所有其他语言。不同的是,这个版本更通用。它看起来更像一个C++ STL的东西,比方说,Haskell。特别是,它只要求参数是 IterableLike 并且只要求存在一个隐式转换函数,该函数可以构建 某物 从结果值集合中。是的,这很复杂,但它实际上只是通用编程的一般范式的一种表达:不要假定任何实际上不需要的东西。

    在这种情况下, 地图 实际上不是 需要 集合将是一个列表,或正在排序或可排序,或类似的任何内容。唯一的事情就是 地图 关心的是,它可以一个接一个地访问集合中的所有元素,但没有特定的顺序。它不需要知道结果集合是什么,只需要知道如何构建它。所以,这就是它的类型签名所需要的。

    所以,而不是

    map :: (a → b) → [a] → [b]
    

    哪个是传统的类型签名 地图 ,一般不需要具体的 List 而是一个 迭代的 数据结构

    map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j
    

    然后通过只要求存在一个函数 转换 用户想要的任何数据结构的结果:

    map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c
    

    我承认语法有点笨拙,但语义是相同的。基本上,它从

    def map[B](f: (A) ⇒ B): List[B]
    

    哪个是传统的签名 地图 .(注意,由于scala的面向对象特性,输入列表参数是如何消失的,因为它现在是单个调度OO系统中每个方法都具有的隐式接收参数。)然后,它从具体的 更一般的 迭代的

    def map[B](f: (A) ⇒ B): IterableLike[B]
    

    现在,它取代了 迭代的 具有以下函数的结果集合: 生产 嗯,真的什么都可以。

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

    我真的认为那不是 那个 很难理解。实际上,您只需要几个智能工具:

    1. 你需要大致知道 地图 是。如果你给 只有 我承认,没有方法名的类型签名很难弄清楚到底发生了什么。但既然你已经 知道 什么 地图 应该这样做,并且您知道它的类型签名应该是什么,您可以快速扫描签名并关注异常,例如“为什么这样做” 地图 以两个函数为参数,而不是一个?”
    2. 你需要能够 阅读 类型签名。但是,即使您以前从未见过scala,这也应该很容易,因为它实际上只是您已经从其他语言了解的类型语法的混合体:vb.net使用方括号表示参数多态性,使用箭头表示返回类型,使用冒号分隔名称和类型,这实际上是规范。
    3. 您需要大致了解通用编程是关于什么的。(不是) 那个 很难搞清楚,因为基本上都是用名字来表达的:它实际上只是以一种通用的方式进行编程)。

    这三个都不应该给任何专业的甚至是业余的程序员带来严重的头痛。 地图 在过去50年中设计的几乎所有语言都是标准函数,不同语言具有不同语法的事实对于那些设计了HTML和CSS的网站的人来说是显而易见的,如果没有来自St教会的一些恼人的C++迷,你就不能订阅一个远程编程相关的邮件列表。.stepanov解释了通用编程的优点。

    是的,斯卡拉 复杂的。是的,scala拥有人类所知的最复杂的类型系统之一,可以与haskell、miranda、clean或cyclone等语言竞争甚至超越。但是如果复杂性是一个反对编程语言成功的理由,C++早就死了,我们都将是编写方案。scala很可能不会成功有很多原因,但是程序员在坐在键盘前不必费心打开大脑这一事实可能不是主要原因。

        3
  •  166
  •   Kenji Baheux    14 年前

    同样的事情在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;
    }
    
        4
  •  69
  •   Daniel C. Sobral    15 年前

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

    我的意思是…大多数程序员不关心这种类型签名,因为 他们再也见不到了 !他们不看文件。

    只要他们看到代码是如何工作的一些例子,并且代码在产生结果时没有使他们失败,他们就会 期待 ,他们永远不会查看文档。如果失败,他们将查看文档并期望看到 使用实例 在顶部。

    考虑到这些,我认为:

    1. 任何人(像大多数人一样)遇到过这种类型签名,如果他们预先对它进行了处理,他们将永远模仿scala,如果他们喜欢scala,他们将把它视为scala力量的象征。

    2. 如果文档没有得到增强以提供使用示例并清楚地解释方法的用途和使用方法,那么它可能会稍微降低对scala的采用。

    3. 从长远来看,这无关紧要。那个斯卡拉 可以 这样做会使为scala编写的库更强大,使用更安全。这些库和框架将吸引程序员使用强大的工具。

    4. 喜欢简单和直接的程序员将继续使用PHP或类似的语言。

    唉,Java程序员非常喜欢电动工具,所以,在回答这个问题时,我刚刚修改了我对主流Scala采用的期望。毫无疑问,scala将成为主流语言。不是C主流,但可能是Perl主流或PHP主流。

    说到Java,你曾经取代过类加载器吗?你有没有研究过这涉及到什么?如果你看看框架作者写的地方,Java可能会很吓人。只是大多数人不这样做。同样的事情也适用于斯卡拉,伊莫霍,但早期的收养者有一种倾向,看他们遇到的每一块岩石下面,看是否有什么东西隐藏在那里。

        5
  •  54
  •   Imran    15 年前

    这会推迟人们去斯卡拉吗?

    是的,但它也会阻止人们被推迟。自从scala获得了对更高类型的支持以来,我认为缺少使用更高类型的集合是一个主要的弱点。它使API文档更加复杂,但它确实使使用更加自然。

    这是否会让斯卡拉在商业界名声扫地,成为一个只有专注的博士生才能理解的学术游戏?CTO和软件主管会被吓跑吗?

    有些人可能会。我不认为很多“专业”开发人员可以访问scala,部分原因是scala的复杂性,部分原因是许多开发人员不愿意学习。雇用这些开发人员的首席技术官将被吓跑。

    图书馆是否重新设计了一个明智的想法?

    当然。它使集合更适合语言和类型系统的其他部分,即使它仍然有一些粗糙的边缘。

    如果你在商业上使用scala,你担心吗?你打算立即采用2.8还是等着看会发生什么?

    我不是在商业上使用它。我可能要等到2.8.x系列中至少有几次版本的版本,然后再尝试引入它,以便清除bug。我还将拭目以待EPFL在改进开发过程中有多大的成功。我所看到的似乎充满希望,但我为一家保守的公司工作。

    “scala对主流开发人员来说太复杂了吗?”…

    大多数开发人员,无论是主流还是其他,都在维护或扩展现有系统。这意味着他们使用的大部分是由很久以前的决定决定决定的。还有很多人在写COBOL。

    明天的主流开发人员将维护和扩展今天正在构建的应用程序。其中许多应用程序不是由主流开发人员构建的。明天的主流开发人员将使用今天最成功的新应用程序开发人员使用的语言。

        6
  •  46
  •   Derek Mahar    15 年前

    scala社区能够帮助缓解对scala新手的恐惧的一个方法是专注于实践和以身作则的教学——很多例子都是从小开始逐渐变大的。以下是采用这种方法的几个站点:

    在这些站点上花费了一段时间后,人们很快意识到,尽管scala及其库可能难以设计和实现,但使用起来并不那么困难,特别是在常见的情况下。

        7
  •  41
  •   Matt Curtis    15 年前

    我在美国一所廉价的“大众市场”大学获得了本科学位,所以我会说我处于用户智能(或者至少是教育程度)的中间:我刚刚涉足了scala几个月,并且已经开发了两三个非平凡的应用程序。

    特别是现在Intellij已经发布了他们的优秀的IDE,imho是目前最好的scala插件,scala的开发相对来说是无痛的:

    • 我发现我可以使用斯卡拉作为“没有分号的Java”,也就是说,我写类似的代码,我将在爪哇做什么,并受益于句法简洁,如通过类型推理所获得的。异常处理,当我这样做的时候,更方便。没有getter/setter样板文件,类定义就不那么冗长了。

    • 有时,我设法写一行来完成相当于多行的Java。在适用的情况下,功能方法链,如地图、折叠、收集、过滤等,是有趣的组成和优雅的观赏。

    • 我很少能从scala更强大的特性中获益:闭包和部分(或curried)函数、模式匹配…有点像。

    作为一个新手,我继续努力学习简洁和惯用的语法。不带参数的方法调用不需要括号,除非需要括号;match语句中的事例需要一个粗箭头( => 但是也有一些地方需要一个细箭头( -> )许多方法都有简短但相当神秘的名称,比如 /: \: -如果我翻开足够多的手册页,我可以完成我的工作,但是我的一些代码最终看起来像Perl或行噪声。具有讽刺意味的是,最流行的句法速记方式之一在实际操作中已经不见了:我总是被这样一个事实所咬 Int 没有定义 ++ 方法。

    这只是我的观点:我觉得斯卡拉具有C++的强大性,与C++的复杂性和可读性相结合。语言的语法复杂性也使得API文档难以阅读。

    斯卡拉非常 深思熟虑 在很多方面都很出色。我怀疑许多学者会喜欢用它来编程。然而,它也充满了智慧和魅力,它比Java具有更高的学习曲线,而且更难阅读。如果我扫描一下FRA,看看有多少开发人员仍在与Java的更精细点进行斗争, 我无法想象斯卡拉会成为主流语言 . 没有一家公司能够证明,当他们以前只需要1周的Java课程时,就可以将开发者发送3周的Scala课程。

        8
  •  32
  •   davetron5000    15 年前

    我认为这种方法的主要问题是 (implicit bf : CanBuildFrom[Repr, B, That]) 没有任何解释。尽管我知道什么是隐式参数,但没有任何东西表明这对调用有何影响。在scaladoc中搜索只会让我更加困惑(很少有类与 CanBuildFrom 甚至有文档)。

    我认为一个简单的“在 bf 为类型的对象提供生成器 B 返回类型 That “会有所帮助,但当你真正想做的是地图时,这是一个令人兴奋的概念。 A 对… 是的。事实上,我不确定那是对的,因为我不知道是什么类型的。 Repr 方法和文件 Traversable 当然根本不知道。

    所以,我有两个选择,两个都不愉快:

    • 假设它只适用于旧地图的工作方式,以及地图在大多数其他语言中的工作方式。
    • 再深入研究一下源代码

    我知道斯卡拉基本上是在揭示这些东西是如何工作的,最终这是一种方式来做什么牛轭湖描述。但这会分散签名的注意力。

        9
  •  22
  •   tmatuschek    10 年前

    我是一个scala初学者,老实说,我不认为类型签名有问题。参数是要映射的函数,隐式参数是生成器返回正确集合的参数。清晰易读。

    事实上,整件事都很优雅。生成器类型参数允许编译器选择正确的返回类型,而隐式参数机制则向类用户隐藏该额外参数。我试过这个:

    Map(1 -> "a", 2 -> "b").map((t) => (t._2) -> (t._1)) // returns Map("a" -> 1, "b" -> 2)
    Map(1 -> "a", 2 -> "b").map((t) =>  t._2)            // returns List("a", "b")
    

    这就是多态性。

    现在,当然,这不是一个主流模式,它会吓跑许多人。但是,它也会吸引许多重视它的表现力和优雅的人。

        10
  •  20
  •   Tony Morris    15 年前

    不幸的是,你给地图的签名是一个错误的地图,确实有合法的批评。

    第一个批评是,通过颠覆地图的签名,我们得到了一些更普遍的东西。认为这是默认的美德是一个常见的错误。它不是。映射函数被很好地定义为一个协变函数fx->(x->y)->fy,并遵循组合和同一性的两个定律。任何其他归因于“地图”的东西都是一种嘲弄。

    给定的签名是其他东西,但它不是映射。我怀疑它试图做的是一个专门的、稍微修改过的“遍历”签名版本,这是迭代器模式的本质。签字如下:

    traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
    

    我将把它转换成scala:

    def traverse[A, B](f: A => F[B], a: T[A])(implicit t: Traversable[T], ap: Applicative[F]): F[T[B]
    

    当然失败了——还不够全面!另外,它也略有不同(请注意,通过“标识”函数运行“遍历”可以获得地图)。但是,我怀疑,如果库作者更清楚地了解有良好文档记录的库常规化(具有上述效果的应用程序设计),那么我们不会看到此错误。

    其次,map函数在scala中是一种特殊情况,因为它用于理解。不幸的是,这意味着一个装备更好的图书馆设计师不能忽视这个错误,同时也不能牺牲理解的句法糖分。换句话说,如果scala库的设计者要销毁一个方法,那么这很容易被忽略,但请不要映射!

    我希望有人对这件事发表意见,因为事实上,解决斯卡拉坚持犯下的错误会变得更加困难,显然是因为我强烈反对的原因。也就是说,解决“普通程序员不负责任的反对意见(即太难了!)”的方法。不是“安抚他们让他们更容易”,而是提供指针和帮助,让他们成为更好的程序员。我和斯卡拉的目标在这个问题上是有争议的,但回到你的观点上来。

    你可能是在说你的观点,预测“普通程序员”的具体反应。也就是说,那些会声称“但这太复杂了”的人。或者一些这样的。这些是您所指的Yegges或Bloch。我对反智主义/实用主义运动的这些人的反应相当严厉,我已经预料到了一连串的反应,所以我将忽略它。

    我真的希望scala库能够改进,或者至少可以安全地将错误隐藏在角落里。Java是一种“试图做任何有用的事情”的语言是如此的昂贵,以至于它常常不值得,因为绝大多数的错误是无法避免的。我恳求斯卡拉不要走同一条路。

        11
  •  15
  •   James Strachan    15 年前

    我完全同意这个问题和马丁的回答:)。即使在爪哇,用泛型来阅读JavaDoc比由于额外的噪音要困难得多。这在scala中更为复杂,其中隐式参数被用作问题的示例代码(而隐式参数在集合变形方面非常有用)。

    我不认为这是语言本身的问题——我认为这更像是工具问题。虽然我同意J_¶RG W Mittag所说的,但我认为看scaladoc(或者你的IDE中的一种类型的文档),它应该需要尽可能少的脑力来探索一种方法是什么,它需要什么和返回什么。为了得到它,不需要在一张纸上拼凑一点代数。)

    当然,IDES需要一种很好的方法来显示任何变量/表达式/类型的所有方法(就像马丁的例子一样,它可以内联所有泛型,所以它很好,也很容易搜索)。我也喜欢马丁在默认情况下隐藏暗示的想法。

    以scaladoc为例…

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

    当在scaladoc中查看这个时,我希望在默认情况下隐藏通用块[b,that]以及隐式参数(如果用鼠标悬停一个小图标,可能会显示这些参数),作为额外的东西来阅读它,这通常并不相关。想象一下如果这看起来像…

    def map(f: A => B): That
    

    很好,很清楚,很明显。你可能会想知道“那”是什么,如果你用鼠标或点击它,它可以展开[b,那个]文本突出显示“那”。

    也许有一个小图标可以用于[]声明和(隐式的…)块,这样就可以清楚地看到语句中有一些折叠的部分了?它很难使用令牌,但我将使用。现在…

    def map.(f: A => B).: That
    

    因此,默认情况下,类型系统的“噪声”对人们需要查看的主要内容(方法名、参数类型及其返回类型)隐藏了80%——如果你真的那么在意的话,它几乎没有可扩展的细节链接。

    大多数人都在阅读scaladoc,以了解他们可以对类型调用什么方法,以及可以传递什么参数。我们有点用太多的细节让用户超载了。

    这是另一个例子…

    def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1]
    

    现在,如果我们隐藏了泛型声明,就更容易阅读了

    def orElse(that: PartialFunction[A1, B1]): PartialFunction[A1, B1]
    

    然后,如果人们悬停在上面,比如说,a1,我们可以显示a1的声明为a1<:a。泛型中的协变和逆变类型也会添加大量的噪声,我认为这些噪声可以以更容易搜索的方式呈现给用户。

        12
  •  11
  •   Peter Mortensen    15 年前

    我不知道该怎么跟你说,但是我有剑桥大学的博士学位,而且我用的是2.8,很好。

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

    所以,我是一个“新用户”,我没有被推迟——事实上它像Java给了我足够的信心去忽略我不理解的比特。

    (然而,我之所以看斯卡拉,部分原因是想看看是否要在工作中推动它,我现在还不打算这样做。让文档不那么吓人当然会有所帮助,但让我吃惊的是它仍然在变化和发展(公平地说,最让我吃惊的是它是多么的棒,但变化却在近一秒之内发生)。所以我想我想说的是,我宁愿把有限的资源投入到最终的状态中去——我认为他们不希望这么快就受到欢迎。)

        13
  •  10
  •   Jeff G    11 年前

    根本不认识斯卡拉,但几周前我还看不懂《Clojure》。现在我能读到其中的大部分,但写不出任何超越最简单的东西。 实例 . 我想斯卡拉也没什么不同。你需要一本好的书或课程,这取决于你如何学习。只是在读 地图 上面的声明,我知道了 也许吧 1/3。

    我认为更大的问题不是这些语言的语法,而是采用和内化 范式 使它们在日常生产代码中可用。对我来说,Java并不是一个巨大的跳跃,它不是来自C的巨大飞跃,它不是帕斯卡的跳跃,也不是基本的…但是用功能语言如Clojure编码 (对我来说)一个巨大的飞跃。我猜想在Scala中,你可以用Java风格或Scala风格来编码。但在Culjule中,你会创造出一个混乱的状态,试图让你的命令习惯远离Java。

        14
  •  7
  •   Ken Bloom    15 年前

    scala有很多疯狂的特性(特别是涉及到隐式参数的特性),看起来非常复杂和学术化,但设计的目的是使事物易于使用。最有用的是句法上的糖分(比如 [A <% B] 这意味着,A类型的对象隐式地转换为B类型的对象)并对它们所做的操作进行有文档记录的解释。但大多数时候,作为这些库的客户机,您可以忽略隐式参数,并相信它们会做正确的事情。

        15
  •  6
  •   Shelby Moore III    7 年前

    这会推迟人们去斯卡拉吗?

    我不认为这是影响Scala的流行程度的主要因素,因为Scala有很多的力量,它的语法对于Haskell、OcAML、SML、Lisp等Java/C++/PHP程序员来说并不陌生。

    但我确实认为斯卡拉的人气将比今天的Java要低,因为我也认为下一个主流语言必须被简化,我看到的唯一的方式是纯不变的,即声明式的HTML,但是图灵完成。然而,我有偏见,因为我正在开发这样一种语言,但我只是在排除了几个月的研究后,斯卡拉不能满足我需要。

    这是否会让斯卡拉在商业界名声扫地,成为一个只有专注的博士生才能理解的学术游戏?CTO和软件主管会被吓跑吗?

    我不认为斯卡拉的名声会受到哈斯克尔情结的影响。但我认为有些人会推迟学习它,因为对于大多数程序员来说,我还没有看到迫使他们使用scala的用例,他们会拖延学习。也许高度可伸缩的服务器端是最引人注目的用例。

    而且,对于主流市场来说,第一次学习scala并不是“新鲜空气的呼吸”,在这里人们可以立即编写程序,比如首先使用html或python。斯卡拉倾向于在你身上成长,在你从一开始就了解到所有你绊倒的细节之后。然而,如果我从一开始就阅读scala中的编程,我对学习曲线的经验和看法可能会有所不同。

    图书馆是否重新设计了一个明智的想法?

    一定地。

    如果你在商业上使用scala,你担心吗?你打算立即采用2.8还是等着看会发生什么?

    我使用scala作为新语言的初始平台。如果我在商业上使用scala,我可能不会在scala的集合库上构建代码。我将创建自己的基于类别理论的库,因为有一次我发现scalaz的类型签名比scala的集合库更加冗长和笨拙。这个问题的一部分可能是scala实现类型类的方式,这也是我创建自己语言的一个次要原因。


    我决定写下这个答案,因为我想强迫自己去研究和比较斯卡拉的收集类设计和我为我的语言所做的设计。不妨分享一下我的思考过程。

    2.8scala集合使用构建器抽象是一个合理的设计原则。我想探讨下面的两个设计权衡。

    1. 只写代码:写完这部分后,我读了 Carl Smotricz's comment 这与我所期望的权衡是一致的。詹姆斯·斯特拉坎和达夫特隆5000的评论一致认为,这一点的意义(甚至不是这样)和内隐的机制不容易直观地理解。见下面第二期中我对monoid的使用,我认为这更为明确。DerekMahar的评论是关于编写scala的,但是关于阅读其他非“常见情况”的scala呢?

      我读到的关于scala的一个批评是,写它比读别人写的代码容易。由于各种原因(例如,许多编写函数的方法、自动闭包、DSL单元等),我发现这偶尔也是正确的,但如果这是主要因素,我还不确定。在这里,隐式函数参数的使用有正负之分。另一方面,它减少了冗长的内容并自动选择生成器对象。在Odersky example 从位集,即set[int]到set[string]的转换是隐式的。不熟悉的代码阅读器可能不容易知道集合的类型,除非他们能够很好地解释当前包范围内可能存在的所有潜在的不可见隐式构建器候选项。当然,经验丰富的程序员和代码编写者会知道位集仅限于int,因此映射到字符串必须转换为不同的集合类型。但是哪种收藏类型呢?没有明确指定。

    2. 特设收藏设计:写完这篇文章后,我读到 Tony Morris's comment 我意识到我的观点几乎是一样的。也许我更详细的阐述会使这一点更清楚。

      在“与类型战斗的比特腐烂”或“摩尔”中,给出了两个用例。它们是位集对int元素和映射对tuple元素的限制,并作为一般元素映射函数a=>b必须能够构建可选目标集合类型的原因提供。然而,阿法克从范畴理论的角度来看,这是有缺陷的。为了在类别理论中保持一致,从而避免出现角点情况,这些集合类型是函子,其中每个变形a=>b必须在相同的函子类别、list[a]=>list[b]、bitset[a]=>bitset[b]中的对象之间映射。例如,一个选项是一个函数,它可以被视为一个some(object)和none的集合。没有从选项的none或list的nil到其他没有“空”状态的函数的常规映射。

      这里有一个折衷的设计选择。在我的新语言集合库的设计中,我选择了使所有内容都成为函数,这意味着如果我实现了一个位集,它需要支持所有元素类型,在使用非整数类型参数时使用非位字段内部表示,并且该功能已经在它从scala继承的集合中。在我的设计中,map只需要映射它的值,它可以提供一个单独的非函数方法来映射它的(key,value)对元组。一个优点是,每个函数通常也是一个应用程序,也许也是一个单胞函数。因此,元素类型之间的所有函数,例如a=>b=>c=>d=>…,都会自动提升到提升的应用类型之间的函数,例如list[a]=>list[b]=>list[c]=>list[d]=>…。对于从一个函数映射到另一个集合类,我提供了一个采用monoid的映射重载,例如nil、none、0、“”、array()等。因此,builder抽象函数是monoid的append方法,它作为必需的输入参数显式提供,因此没有不可见的隐式转换。(切线:这个输入参数还可以附加到非空的monoids,scala的地图设计不能这样做。)这样的转换是同一迭代过程中的一个地图和一个折叠。此外,我还提供了一个类别意义上的可遍历“带效果的应用程序”mcbride&patterson,它还允许在一次迭代中从任何可遍历传递到任何应用程序,其中大多数集合类都是。另外,state monad是一个应用程序,因此是任何可遍历的完全通用的生成器抽象。

      因此,从范畴论的角度来看,scala集合是“特设”的,范畴论是更高层次的外延语义学的本质。尽管scala的隐式构建器一开始看起来比函数模型+monoid构建器+可遍历的->应用更“广义”,但它们并没有被证明与任何类别一致,因此我们不知道它们在最一般的意义上遵循什么规则,也不知道它们将被赋予什么样的角情况,它们可能不遵守任何类别。血淋淋模型增加更多的变量使事情变得更一般,这是不正确的,这是范畴理论的一个巨大好处,它提供了在提升到更高层次语义的同时保持普遍性的规则。集合是一个类别。

      我在某个地方读到过,我认为这是Odersky,作为库设计的另一个理由,它是纯函数式的编程在不使用尾部递归的地方具有有限的递归和速度的成本。到目前为止,在我遇到的每种情况下,都不难使用尾部递归。


    此外,我在头脑中还带着一个不完整的想法,即scala的某些权衡是由于试图同时成为一种可变和不变的语言,而不像haskell或我正在开发的语言。这与托尼·莫里斯关于理解的评论是一致的。在我的语言中,没有循环和可变结构。我的语言将位于scala之上(目前为止),并且要归功于它,如果scala没有通用的类型系统和可变性,这是不可能的。不过,这可能不是真的,因为我认为Odersky&moors(“用类型来战斗比特腐烂”)不正确地说scala是唯一一种更高级的OOP语言,因为我(通过Bob Harper)验证了标准ML拥有它们。同样,SML的类型系统也可能是相当灵活的(自20世纪80年代以来),这可能不容易理解,因为语法与Java(斯卡拉)和C++/PHP没有太多相似之处。无论如何,这不是对scala的批评,而是试图对权衡进行不完整的分析,我希望这与问题有密切关系。scala和sml不会因为haskell的无能而受苦。 diamond multiple inheritance 这一点很关键,我理解为什么哈斯克尔前奏曲中的许多函数会针对不同的类型重复出现。

        16
  •  5
  •   Julian Dehne    11 年前

    这里似乎有必要说明一个学位:政治学学士学位和计算机科学学士学位。

    切中要害:

    这会推迟人们去斯卡拉吗?

    scala很难实现,因为它的底层编程范式很难实现。函数式编程吓坏了很多人。在PHP中构建闭包是可能的,但人们很少这样做。所以,不,不是这个签名,而是其他所有的签名都会让人感到厌烦,如果他们没有特定的教育,使他们重视底层范式的力量。

    如果有这种教育,每个人都能做到。去年我和一群学生在斯卡拉做了一台国际象棋电脑!他们有问题,但最后还是做得很好。

    如果你在商业上使用scala,你担心吗?你打算立即采用2.8还是等着看会发生什么?

    我不会担心的。

        17
  •  4
  •   Matt    14 年前

    我也有牛津大学的数学学位!我花了一段时间才弄到新收藏的东西。但现在我很喜欢。事实上,在2.7中输入“map”是第一个困扰我的大问题(可能是因为我做的第一件事是集合类中的一个子类)。

    阅读Martin关于新的2.8集合的论文确实有助于解释隐含的使用,但是文档本身确实需要更好地解释不同类型的隐含在核心API的方法签名中的作用。

    我主要关心的是:2.8什么时候发布?这个bug报告什么时候会停止出现?斯卡拉团队是否被咬得比他们能用2.8咀嚼的还多/试图一次改变太多?

    我真的很想看到2.8在添加任何新的东西之前已经稳定下来作为发布的优先事项,并且想知道(在旁观的时候)是否可以对scala编译器的开发路线图的管理方式进行一些改进。

        18
  •  -1
  •   Sujen    14 年前

    使用站点中的错误消息如何?

    当用例出现时,需要将现有类型与适合DSL的自定义类型集成起来,这又会怎样呢?一个人必须在关联、优先、内隐转换、内隐参数、更高级的类型和可能存在的类型等方面接受良好的教育。

    这是很好地知道,大部分是简单的,但它不一定是足够的。如果要设计一个大面积的图书馆,至少必须有一个人知道这些东西。