8

我现在的主要语言是 D,我正在学习 Python,因为它是我正在学习的课程所必需的。虽然我理解为什么动态语言对于在没有类型推断或模板的情况下使用静态语言进行编程的人们来说是一股新鲜空气(恕我直言,模板在很大程度上是编译时的鸭子类型),但我很好奇动态语言有什么好处即使你有这些。

底线是,如果我要学习 Python,我想以一种真正改变我对编程的想法的方式来学习它,而不是仅仅用 Python 编写 D。我没有使用过动态语言,因为我是一个相当新手的程序员,无法欣赏它们应该提供的灵活性,并且现在想学习充分利用它们。什么可以在动态类型的解释语言中轻松/优雅地完成,而这在静态语言中是尴尬或不可能的,即使使用模板、多态性、静态类型推断,也许还有运行时反射?

4

13 回答 13

15

从理论上讲,动态语言不能做任何事情,而静态语言不能。聪明的人在制作非常好的动态语言方面付出了很多努力,导致目前人们认为动态语言领先而静态语言需要迎头赶上。

随着时间的推移,这将转向另一个方向。各种静态语言已经有:

  • 泛型,通过在传递对象时让它选择正确的类型来减少静态类型的愚蠢,从而使程序员不必自己强制转换

  • 类型推断,这样就不必浪费时间编写应该显而易见的东西了

  • 闭包,除其他外,它有助于将机制与意图分开,让您将复杂的算法与大多数现有成分结合在一起。

  • 隐式转换,它可以让您模拟“猴子修补”而没有通常涉及的风险。

  • 代码加载和对编译器的轻松编程访问,因此用户和第三方可以编写您的程序。谨慎使用!

  • 更有利于在其中创建领域特定语言的语法。

...毫无疑问还有更多。动态运动催生了静态语言设计的一些有趣发展,我们都从竞争中受益。我只希望更多这些功能成为主流。

有一个地方我没有看到主要的动态语言被替换,那就是浏览器中的 Javascript。现有市场有太多需要替代,所以重点似乎是让 Javascript 本身变得更好。

于 2009-01-30T00:23:01.423 回答
3

这是史蒂夫·耶格(Steve Yegge)的主题。

Guido van Rossum 在他对 Scala 的看法中也与那次谈话有关。

于 2009-01-29T23:54:36.100 回答
2

“我很好奇动态语言有什么好处,即使你拥有这些。”

与 D 编程语言相比:

  • Python 是一种更紧凑的语言。它允许您表达与 D 一样多的内容,但它使用更少的不同概念来实现它——少即是多

  • Python 有一个强大的标准库——包括电池

我不知道 D 是否有交互式提示,但在 Python 中,像ipython这样的交互式 shell是开发过程的一个组成部分。

于 2009-01-30T01:00:21.100 回答
2

Python 中的示例:

def lengths(sequence):
    try:
        return sum(len(item) for item in sequence)
    except TypeError:
        return "Wolf among the sheep!"

>>> lengths(["a", "b", "c", (1, 2, 3)])
6
>>> lengths( ("1", "2", 3) )
'Wolf among the sheep!'

你认为这花了我多长时间,以及多少编译-运行-调试周期?

如果您认为我的示例微不足道,我可以回答说动态语言使许多编程任务变得微不足道。

于 2009-01-30T19:45:27.053 回答
1

在动态语言中,您可以以您知道正确的方式使用值。在静态类型语言中,您只能以编译器知道正确的方式使用值。你需要你提到的所有东西来重新获得被类型系统带走的灵活性(我不是在抨击静态类型系统,灵活性经常被带走是有充分理由的)。如果您想以语言设计者没有预料到的方式使用值(例如,将不同类型的值放入哈希表中),那么您不必在动态语言中处理这种复杂性。

所以并不是说你不能在静态类型语言中做这些事情(如果你有运行时反射),它只是更复杂。

于 2009-01-29T23:59:50.893 回答
1

我实际上为此写了一篇博客文章: linky。但是那个帖子基本上可以这样总结:

您会惊讶于不必在编译时命名您的变量是什么类型是多么令人费解的事情。因此,python 往往是一种非常高效的语言。

另一方面,即使有好的单元测试,你也会对你允许自己犯的愚蠢错误感到惊讶。

于 2009-01-30T00:27:21.853 回答
1

使用对象时动态类型的一大优势是,当您希望多个类具有相同的接口时,您不再需要使用类层次结构——这或多或少称为鸭子类型。糟糕的继承很难在之后修复——这使得重构通常比在像 python 这样的语言中更难。

于 2009-01-30T03:49:42.193 回答
1

关键是,在动态语言中,您可以比在静态类型语言中更快地实现相同的功能。因此,生产率通常要高得多。

原则上,模板或多态之类的东西给了你很大的灵活性,但你必须编写大量代码才能使其工作。在动态语言中,这种灵活性几乎是免费的。

所以我认为你以错误的方式看待差异,生产力确实是这里的重点(就像垃圾收集提高生产力一样,但实际上并不能让你做新的事情)。

于 2009-01-30T12:02:25.913 回答
0

我要说闭包,但发现了这个线程......(不是我理解它在“静态”语言中的工作方式)

相关概念是作为第一类对象的函数高阶过程。(例如,将函数作为输入和/或返回函数作为输出的函数)

编辑:(对于这里的挑剔者)我会回应我在@David Locke 的帖子上发表的评论。动态解释的语言可以将现有的软件程序/项目与临时创建的小功能或类结合使用,以交互方式探索某些东西。最好的例子可能是函数图。如果我用函数编写了一个函数绘图对象graph(f,xmin,xmax),我可以用它来探索诸如 x 2或 sin(x) 之类的函数。我一直在 MATLAB 中这样做;它被解释并具有匿名函数@(x) x^2

于 2009-01-29T23:51:36.747 回答
0

使用动态语言,拥有命令行解释器要容易得多,因此您可以在命令行上测试事物,而不必担心编译步骤来查看它们是否有效。

于 2009-01-29T23:52:10.410 回答
0

我发现像 Perl 这样的动态语言以及在较小程度上 Python 允许我为我需要做的事情编写快速而肮脏的脚本。动态语言的运行周期要短得多,并且通常需要编写的代码比使用静态类型语言要少得多,这提高了我的工作效率。不幸的是,这是以可维护性为代价的,但这是我用动态语言而不是它们本身的语言编写程序的方式的错误。

于 2009-01-30T01:01:42.640 回答
0

看一下JavaScript中的这个e4x示例:

var sales = <sales vendor="John">
    <item type="peas" price="4" quantity="6"/>
    <item type="carrot" price="3" quantity="10"/>
    <item type="chips" price="5" quantity="3"/>
  </sales>;

alert( sales.item.(@type == "carrot").@quantity );
alert( sales.@vendor );
for each( var price in sales..@price ) {
  alert( price );
}

特别是,看看线:

alert( sales.item.(@type == "carrot").@quantity );

在典型的静态语言中,您不必编写 sales.item,因为直到运行时您才能知道该 item 是 sales 的属性。这不仅限于 e4x。在编写 SOAP 客户端或任何其他直到运行时才知道的底层类型时,您可以在连接时以类似的风格进行编程。在静态语言中,您通常需要运行一个以非常冗长的方式生成存根类或程序的工具。然后,如果 Web 服务发生变化,您需要重新生成存根。看一下java DOM代码:

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class Foo {

    public Document createDocument() {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement( "root" );

        Element author1 = root.addElement( "author" )
            .addAttribute( "name", "James" )
            .addAttribute( "location", "UK" )
            .addText( "James Strachan" );

        Element author2 = root.addElement( "author" )
            .addAttribute( "name", "Bob" )
            .addAttribute( "location", "US" )
            .addText( "Bob McWhirter" );

        return document;
    }
}

绝对比您的动态代码详细得多。而且,当然,它不是静态类型的。在运行之前,无法检查您是否将“作者”拼写为“作者”。所有这些冗长的内容本质上都是为了让您以静态风格捕捉本质上是动态的东西。

I think this is one of the strong points of dynamic languages.

于 2009-03-20T17:59:33.347 回答
-2

当效率和类型安全是优先事项时,倾向于使用编译语言。否则我想不出任何人不使用红宝石的理由:)

于 2009-01-30T01:01:51.643 回答