来自Ruby程序员的关于Scala的问题

27

我最近在业余时间学习一门新语言,Scala似乎很吸引人。以下是我的几个问题:

  1. 不会Java会对学习Scala造成挑战吗?这会成为一个很大的劣势吗?(即人们多常依赖Java-specific库?)

  2. 与Ruby相比,有多大的差异?(除了静态类型之外)它是否介绍了许多新术语,还是我将熟悉大部分语言机制?

  3. 你会推荐哪些资源?我看中了《Programming Scala》和《Beginning Scala》书籍。

  4. 虽然主观,但用Scala编程是否有趣? :P

谢谢

7个回答

36

Ruby 和 Scala 之间有许多共同点。因为我已经很久没写 Ruby 了,所以这不是详尽无遗的。

Ruby <==> Scala(大致相等!)

  • Mixins <==> Traits
  • Monkey Patching <==> Pimp My Library(隐式转换为带有额外方法的包装器)
  • Proc/Closure <==> Function/Function Literal
  • Duck Typing <==> Structural Types
  • Last Argument as a Proc <==> Curried Parameter List(请参阅 Traversable#flatMap)
  • Enumerable <==> Traversable
  • collect <==> map
  • inject <==> foldLeft/foldRight
  • Symbol.toProc <==> 占位符语法糖:people.map(_.name)
  • Dynamic Typing conciseness <==> Type Inference
  • Nil <==> null,虽然 Option 更可取。(不是 Nil,它是一个空列表!)
  • Everything is an expression <==> 同上
  • symbols/hashes as arguments <==> Named and Default Parameters
  • Singleton <==> object Foo {}
  • Everthing is an object <==> 所有东西都是类型或对象(包括函数)
  • No Primitives <==> 统一的类型系统,Any 是基本类型和对象的超类型。
  • Everything is a message <==> 操作符只是方法调用

你可能会错过的 Ruby 特性

  • method_missing
  • define_method 等

你应该学习的 Scala 特性

  • Pattern Matching
  • Immutable Classes,特别是 Case Classes
  • Implicit Views 和 Implicit Parameters
  • Types,Types,还有更多的 Types:Generics,Variance,Abstract Type Members
  • 对象和函数的统一,applyupdate 方法的特殊含义。

  • 1
    正则表达式:/Cats(.)/ <==> "Cats(.)".r - Thomas Jung
    10
    Scala 2.9将引入 scala.Dynamic,类似于 method_missing - retronym
    3
    该死的 Scala,你赢得了这个 Ruby 程序员的心! :) 我越深入了解,它就显得越加壮观。 - Damien Roche
    提取器...你不想忘记提取器! - Kevin Wright

    19

    以下是我的看法:

    • 不用担心不懂Java。

    • Scala 很多依赖于Java库,但这并不重要。你可能会在阅读示例时遇到一些困难,但不足以成为障碍。时间有限,你甚至不会注意到阅读Java API文档和Scala API文档之间的区别(除了最新scaladoc的完全不同的风格)。

      然而,通常假定熟悉JVM环境。如果我可以给出一个建议,那就是一开始避免使用Maven,并使用SBT作为构建工具。对于小型程序,这将是不必要的,但它将使Java语言世界中的许多棱角更容易处理。当你想要外部库时,了解SBT。使用它,你不必处理任何XML:你可以在Scala本身中编写构建规则。

    • 你可能会觉得类型概念和术语很难理解。Scala 不仅是静态类型的,而且它具有非学术语言中最强大的类型系统之一。我打赌这将是你最困难的来源。其他概念可能有不同的术语,但你很快就会发现与Ruby有相似之处。

      这并不是一个大的障碍,如果你想克服它。主要缺点是,你可能觉得任何在学习之后学习的其他静态类型语言都很笨拙和有限。

  • 你没有提到你看上的是哪本Scala编程书。这里有两本,还有一本《Scala编程》。后者是由语言创作者之一编写的,并被广泛认为是一本优秀的书,尽管可能稍微慢了一些。其中一本Scala编程书是由Twitter的一位名叫Alex Payne的人和前Object Mentor的Dean Wampler合著的。这也是一本非常好的书。《入门Scala》是由Lift的创始人David Pollack编写的,人们对此也有很多好评。实际上,我从未听说过任何人抱怨任何一本Scala书。

    其中一本这些书肯定会有所帮助。此外,Scala问题在Stack Overflow的支持非常好——我尽力确保如此! :-) 有scala-users邮件列表,可以在那里得到答案(只要人不太忙),还有Freenode上的#scala IRC频道,你也会得到良好的支持。有时人们可能不在场,但如果他们在场,他们会帮助你。

    最后,有博客。对于初学者来说,最好的博客可能是Daily Scala。你可以在Planet Scala找到很多其他的博客。其中,我自己的Algorithmically Challenged可能没有得到太多的赞誉,但我会回来的。:-)

  • Scala为我恢复了编程的乐趣。当然,我之前是在做Java,这个语言有点无聊,我的看法。我花那么多时间回答Stack Overflow上的问题,一个原因是我享受为提出的问题找出解决方案。


  • 8
    我要提醒一下,关于需要多少Java知识的问题,我不同意它根本不是问题这种说法。有些Java的内容与Scala直接相关,你需要了解。
    1. Java内存模型以及平台为并发提供的机制。我指的是同步、线程等内容。
    2. 基本类型(double、float等)和引用类型(即Object的子类)之间的差异。Scala提供了一些很好的机制来隐藏这个问题,但如果编写必须具有高性能的代码,了解它们的工作原理非常重要。
    这两点都是双向的:Java运行时提供了一些功能(我猜想Ruby没有),对您将会有很大的帮助:
    - 管理扩展(MBeans) - JConsole(用于监视内存、CPU、调试并发问题) - JVisualVM(用于运行时仪器化代码以调试内存和性能问题)
    这些第1点和第2点并不是无法克服的障碍,我认为这里提到的其他相似之处将会对您有很大的帮助。哦,Scala肯定非常有趣!

    7

    我没有 Ruby 的背景,但是我可能能帮到你。

    1. 我认为不了解 Java 不是缺点,但它可能会有所帮助。在我看来,Java 库被相对频繁地使用,但即使是受过训练的 Java 编码人员也不会全部知道它们,因此这里没有“缺点”。通过学习 Scala,您将学习 Java 库的一些部分,因为即使是 Scala 库也使用它们。

    2. --

    3. 我开始阅读《Programming Scala》,然后转而阅读 Scala 库的源代码。后者对理解语言非常有帮助。并且像往常一样:编写代码是必不可少的。只是阅读而不编写代码是没有用的,但我相信您已经知道了这一点。:-) 另一个有用的资源是博客,请参见https://stackoverflow.com/questions/1445003/what-scala-blogs-do-you-regularly-follow,以获取好的 Scala 博客的汇编。

    4. 是的!正如您所说,这非常主观。但对我来说,从 Java 背景出发,这很有趣。


    3
    这是很晚了,但我在某种程度上同意oxbow_lakes所说的。我最近从Python转向Scala,了解Java的工作方式——特别是Java对泛型类型的限制——帮助我理解Scala的某些方面。
    最值得注意的是:
    1. Java有一个非常糟糕的缺陷,称为“类型擦除”。不幸的是,这个问题也存在于JVM中。这对使用泛型类型进行编程特别有影响——在动态类型语言(如Ruby和Python)中根本不存在此问题,但在静态类型语言中非常重要。Scala在解决这个问题方面做得尽可能好,但由于这个问题的严重性,其中一些问题不可避免地会渗透到Scala中。此外,Scala中针对此问题的一些修复(例如清单)是最近才出现的,并且非常麻烦,真正需要了解底层正在发生的事情。请注意,这个问题起初可能不会影响您对Scala的理解,但当您开始编写使用泛型类型的真实程序时,您将遇到无法工作的情况,除非/直到您了解类型擦除所强制的限制。

    2. 早晚您也会遇到与另一个Java缺陷相关的问题,即将类型分成对象(类)和基本类型(ints、floats、booleans)——特别是基本类型不是对象系统的一部分这一事实。Scala实际上很好地隐藏了这一点,但了解Java在某些角落情况下的操作可能会有所帮助——特别是涉及泛型类型的情况,这主要是由于#1中描述的类型擦除问题。(在使用数组、哈希表和类似的基本类型的通用类型时,类型擦除还会导致重大性能损失;这是了解Java将非常有帮助的领域之一。)

    3. 缺陷 #3——在Java中,数组也被特别处理和非正交处理。Scala对此的隐藏不像对原始类型那样无缝,但比对类型擦除更好。隐藏机制有时会暴露出来(例如ArrayWrapper类型),这可能偶尔会导致问题——但实践中最大的问题毫不意外地又与泛型类型有关。

    4. Scala类参数以及Scala处理类构造函数的方式。在这种情况下,Java并没有问题。可以说,Scala也没有问题,但它处理类构造函数的方式相当不寻常,在实践中我很难理解它。我只能通过弄清楚相关的Scala代码如何转换为Java(或更正确地说,编译为Java),然后推理Java会执行什么来理解Scala的行为。由于我认为Ruby在这方面的工作方式与Java非常相似,因此我认为您不会遇到太多问题,尽管您可能需要进行相同的思维转换。

    5. 输入/输出。这实际上是一个库问题,而不是语言问题。在大多数情况下,Scala提供了自己的库,但Scala实际上没有I/O库,因此您几乎没有选择,只能直接使用Java的I/O库。对于Python或Ruby程序员来说,这种过渡有点痛苦,因为Java的I/O库庞大笨重,不太容易用于执行简单任务,例如迭代文件中的所有行。

    请注意,除了I/O之外,您还需要直接使用Java库来处理其他与操作系统或相关任务的交互,例如处理时间和日期或获取环境变量,但通常这并不太难理解。您可能需要使用的其他主要Java库包括:
    1. 子进程调用,也有点庞大
    2. 网络 - 但这总是有些麻烦
    3. 反射,即在运行时动态检查类的方法和/或字段,或根据名称动态调用方法,当名称在编译时未知时。这是一些比较深奥的东西,大多数人不需要处理。显然Scala 2.10将拥有自己的反射库,但目前您必须使用Java反射API,这意味着您需要了解Scala如何转换为Java的相关知识。(幸运的是,Scala编译器有一个-print选项,可以显示此转换的详细信息。)

    1

    关于第一点,不熟悉Java语言本身并不一定是问题。第三方库可以很好地集成到Scala中。但是,了解集合的差异可能会有所帮助(例如,Scala列表不是传统的Java列表,而API可能期望后者)。

    与Java平台相关的技能是可以转移的。也就是说,您仍然使用执行类加载、垃圾回收、JIT编译等操作的JVM。因此,具有这方面的经验是有用的。但是,这并非必需。

    请注意,Scala 2.8即将推出,并且与2.7相比存在一些不兼容的更改。因此,您购买的任何书籍等都应该知道这些差异。


    1

    这是另一个晚回答,最近我自己开始学习Scala,但我可以回答1、3和4:

    1)我将一个大型的、多方面的F#项目移植到Scala,没有使用任何Java或.NET库。因此,对于许多项目,可以完全坚持使用本地Scala。Java生态系统知识是一个加分项,但可以在学习Scala期间和之后逐渐获得。

    3)《Scala编程》不仅适合学习Scala,而且是少数几本真正易读的计算机书籍之一。它也很方便以后参考。

    4)我使用过接近十种不同的编程语言,从汇编语言到Prolog,但Scala和F#是我用过的最有趣的编程语言——差距很大。(Scala和F#非常相似,是两个不同生态系统中“趋同进化”的例子——JVM和.NET。)

    -Neil


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接