人们对动态语言有什么吸引力?[关闭]


81

似乎每个人最近都在使用动态的,未编译的潮流。我主要只使用编译的静态类型语言(C,Java,.Net)工作。我对动态语言的经验是诸如ASP(Vb脚本),JavaScript和PHP之类的东西。在考虑动态语言时,使用这些技术给我留下了不好的印象。直到运行时,编译器通常会捕获诸如拼写错误的变量名以及为变量分配错误类型的值之类的东西。即使那样,您可能也不会注意到错误,因为它只是创建了一个新变量,并分配了一些默认值。我也从未见过intellisense在动态语言中能很好地工作,因为变量没有任何显式类型。

我想知道的是,人们对动态语言有何吸引力?就动态语言允许您完成的事情或在编译语言中很难做到的事情而言,主要优势是什么?在我看来,我们早就决定了,诸如未编译的ASP页面引发运行时异常之类的事情是一个坏主意。为什么会有这种类型的代码复活?至少在我看来,为什么Ruby on Rails看起来真的不像十年前用ASP无法完成的任何事情?


9
Kinda很难过(奇怪)看到很少的防御动态语言。
davidtbernal

11
由于这是在下面所有动态讨厌的事物上保持平衡的唯一方法,因此我将在这里回答:动态语言使您可以更快地编写代码,而没有两种解决方法。我不必担心我的任何变量的类型,也不必启动大型的IDE来编写代码。因此,由于类型系统的繁琐性使您告诉编译器应有的一切,因此使用静态类型系统执行耗时较长的快速任务会更好。
RCIX

2
C#程序员狭小近视是怎么回事?
Azeem.Butt


5
出现问题的拼写错误的变量名来自隐式变量声明,而不是静态/动态。需要显式变量声明的动态语言(例如Smalltalk)不会出现此问题。
Frank Shearar 2010年

Answers:


101

我认为原因是人们习惯了具有非常有限且缺乏表现力的类型系统的静态类型语言。这些是Java,C ++,Pascal等语言,它们不再朝着更具表现力的类型系统和更好的类型推断的方向发展(例如在Haskell中,甚至在某种程度上甚至是SQL),有些人喜欢保持所有“类型”信息都在他们的头脑中(以及在他们的测试中),并且完全消除了静态类型检查。

这到底能买到什么,目前尚不清楚。关于类型检查的观念很多,我最常遇到的是这两个。

谬误:动态语言不太冗长。误解是类型信息等于类型注释。这是完全不正确的。我们都知道类型注释很烦人。机器应该能够弄清楚这些东西。实际上,在现代编译器中也是如此。这是两行Haskell中的静态类型的QuickSort(来自haskell.org):

qsort []     = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)

这是LISP中的动态类型的QuickSort(来自swisspig.net):

(defun quicksort (lis) (if (null lis) nil
  (let* ((x (car lis)) (r (cdr lis)) (fn (lambda (a) (< a x))))
    (append (quicksort (remove-if-not fn r)) (list x)
      (quicksort (remove-if fn r))))))

Haskell示例伪造了静态类型的假设,因此冗长。LISP示例伪造了冗长的假设,因此是静态类型的。在打字和冗长之间的任何方向都没有暗示。您可以放心地将其排除在外。

谬论:静态类型的语言必须进行编译,而不是解释。再次,不是真的。许多静态类型的语言都有解释器。有Scala解释器,Haskell的GHCi和Hugs解释器,当然,SQL是静态类型的,而且解释的时间比我活着还长。

您知道,也许充满活力的人群只是希望自由而不必对自己在做什么进行认真思考。该软件可能不正确或功能强大,但不一定必须如此。

就我个人而言,我认为那些放弃类型安全以购买一些暂时性自由的人既不应该享有自由,也不应该享有类型安全。


26
为自由而放弃安全类型都不值得。.噢,是的..优秀接近职位
baash05

6
lisp本身就很冗长,它与动态键入无关...在python中尝试。def qsort(l):返回qsort([x对于l [1:]中x的x,如果x <l [0]])+ l [0] + qsort([x对于l [1:]中x的x,如果x> = l [0]]),如果还有其他情况
fortran,2009年

13
这就是重点。它与动态或静态类型无关。
Apocalisp

9
我认为您的例子很糟糕。赞扬动态语言的人们不太可能选择Haskell的Lisp。他们可能会选择Java或C#之上的Python或Ruby。
科里D

8
有论点认为,冗长性和类型性之间存在联系。如您所见,任何此类巧合纯属偶然。非典型正是我选择这些语言的原因。Haskell比其他大多数类型都具有更强的类型,因此它可以很好地代表静态类型的语言。LISP是一种典型的动态语言,所有其他语言都必须模仿但绝不能重复。
Apocalisp

70

不要忘记,您需要在单元测试中编写10倍的代码覆盖率以替换编译器的工作:D

我去过那里,使用动态语言来做,但我绝对没有优势。


4
很高兴我不是唯一的一个。让我晚上睡得更好。
erikkallen

这确实是静态优于动态类型的最大优点。我无法告诉我有多少次我错过了C ++中的类型安全的typedef,只是为了使编译器能够找到更多的bug。(去编译器,去吧!给我带来更多错误!:-)
Dimitri C. 2010年

废话。如果您正在测试方法,并且正在测试调用该方法的方法,则可以知道参数传递很好。根据定义,经过良好测试的代码将不会从静态类型中获得任何额外的收益。
Garth Kidd'2

4
@Garth:奇怪的定义。没有多少人会同意。OTOH,大多数人会同意编译器的类型检查器实现很多(有时非常复杂)测试。
康拉德·鲁道夫

3
@yar,如果您不测试代码,则容易受到逻辑错误的影响。现在,我已经在Python中工作了十年。我认为我在生产中从未遇到过TypeError。不过,我有很多逻辑错误。结论:我不需要太多静态类型检查,但是我确实需要单元测试。
加思·基德

40

在阅读他人的回答时,动态语言似乎或多或少地包含三个参数:

1)代码不太冗长。我认为这无效。某些动态语言不如某些静态语言那么冗长。但是F#是静态类型的,但是那里的静态类型并没有添加太多(如果有的话)代码。尽管它是隐式键入的,但这是另一回事。

2)“我最喜欢的动态语言X具有我最喜欢的功能特征Y,因此动态性更好”。不要将功能性和动态性混为一谈(我不明白为什么要这么说)。

3)在动态语言中,您可以立即看到结果。新闻:您也可以在Visual Studio(自2005年起)中使用C#做到这一点。只需设置一个断点,在调试器中运行程序,然后在调试时修改程序即可。我一直这样做,并且效果很好。

我本人是静态类型的坚定拥护者,其主要原因之一是:可维护性。我有一个包含两万行JavaScript的系统,由于(不存在的)编译器不会告诉我变量重命名弄乱了什么,所以我想做的任何重构都将花费半天左右的时间。那就是我自己写的代码,IMO的结构也很不错。我不想让别人负责编写等效的动态系统。

我想我会为此而被否决,但我会抓住机会。


quote:在动态语言中,您可以立即看到结果。新闻:您也可以在Visual Studio(自2005年起)中使用C#来实现。只需设置一个断点,在调试器中运行程序,然后在调试时修改程序即可。我一直这样做,并且效果很好。从第一天(1995年?)开始就在Delphi中,可能在那之前在Turbo Pascal中(我不记得确切)。
No'am Newman

6
1万行JavaScript?我认为那太多了,大约9,000行,而且我喜欢脚本语言……
奥兹。

@ No'am:我知道。您也可以在Visual C ++ 6中做到这一点(实际上,对我来说,要等到VS2k5出现后才切换到C#才是要点)。如果有的话,这只会增加重点。@Oz:您怎么知道我的JS必须做多少工作?
erikkallen

我认为喜欢看到自己的更改的人会立即生效,就像使用纯文本编辑器一样,而不是使用VS。给每个人自己。您可能会考虑使用类似JSLint的东西。
dlamblin

2
重构好点。我真的开始喜欢Ruby来进行快速原型制作和编写小脚本,但是如果没有静态输入,我永远不会尝试在多个开发人员之间维护大型产品。
LoveMeSomeCode 2010年

19

VBScript很烂,除非您将其与另一种VB风格进行比较。PHP是可以的,只要您记住它是一种过长的模板语言即可。现代Javascript很棒。真。吨的乐趣。只是远离所有标记为“ DHTML”的脚本。

我从未使用不允许运行时错误的语言。恕我直言,这在很大程度上是一条红线:编译器不会捕获所有错别字,也不会验证意图。当您需要显式类型时,显式键入非常有用,但是在大多数情况下,不需要。在此处搜索generics有关是否使用无符号类型是否是索引变量的一个不错选择的问题-在很多情况下,这些东西会妨碍您的工作,并且使人们在有时间的时候不停地旋转。

但是,我还没有真正回答您的问题。动态语言为何具有吸引力?因为过了一会儿,编写代码变得乏味,而您只想实现算法。您已经坐好了,用笔解决了所有问题,图解了潜在的问题场景并证明了它们可以解决的,剩下要做的唯一事情就是编写二十行实现代码和两百行样板代码以进行编译。然后,您意识到所使用的类型系统并不能反映您的实际工作,但是其他人对您可能会做的事情却过于抽象正在做的事情却过于,而您很早以前就放弃了编程,以至于对其进行细微的调整。强迫性的,甚至会使虚构的侦探阿德里安·蒙克(Adrian Monk)感到羞耻。

这时候,你的去得到贴满开始在动态语言寻找严重。


有趣的东西...我会看看Ruby是否说服了我。PHP还没有,但是我觉得很多是因为对OO的东西是事后才想到的。
丹·罗森斯塔克

3
“二十行的实现...和两百行的样板使其可以编译”:我不同意这一说法。当然,在Java时代确实如此,但是C#3和Scala大大减少了所需的样板数量。
cdmckay

5
Java时代结束了吗?打碎啤酒,准备庆祝哦...等等... C ++。
Shog9

2
“ VBScript很烂,除非您将它与另一种VB风格进行比较”,是吗?您是说VBScript是Visual Basic的最佳变种吗?我一定是低估了你。
MusiGenesis

19

我是一名全职的.Net程序员,深深扎根于静态C#的阵痛。但是,我喜欢现代JavaScript。

一般来说,我认为动态语言可以让您表达自己的意图比静态类型的语言可以更简洁地,因为在很多情况下显而易见的时候,您花费较少的时间和空间来定义要表达的内容的基本要素。

我认为动态语言也有多种。我不想回到用VBScript编写经典ASP页面的过程。为了有用,我认为动态语言需要在其核心处支持某种集合,列表或关联构造,以便可以表达对象(或对象的传递),并允许您构建更复杂的构造。(也许我们都应该使用LISP编写代码……这是个玩笑……)

我认为在.Net圈子中,动态语言会受到不良的说唱,因为它们与VBScript和/或JavaScript相关联。由于Kibbee所说的许多原因,VBScript只是一场噩梦,任何人都记得使用CLng在VBScript中强制类型,以确保获得足够的位数来容纳32位整数。另外,我认为JavaScript仍被视为下拉菜单的浏览器语言,对所有浏览器而言,编写方式都不同。在这种情况下,问题不是语言,而是各种浏览器对象模型。有趣的是,C#越成熟,它看起来就越动态。我喜欢Lambda表达式,匿名对象和类型推断。每天感觉都更像JavaScript。


1
我希望有人可以向JavaScript添加文件处理,套接字和GUI库,然后构建一个编译器...在桌面上使用JS ....
UnkwnTech


另外,始终可以使用jscript编写Windows gui应用程序。好吧,反正很长一段时间。有关更多信息,请参见“ windows hta”。您会在浏览器中无法获得的hta中运行一些额外的api。仪表板小部件具有强大的功能。在iPhone的webapps是很多更强大的比大多数人给他们的功劳。苹果已经为移动浏览器中的JS浏览器提供了许多强大的API。
布列塔尼


+1表示意图。尽管有一天您的代码可能会转换为静态lang,但动态(尤其是Python)非常适合一次性使用和原型制作。
new123456 2011年

18

这是两行Haskell(来自haskell.org)中的静态类型的QuickSort:

qsort []     = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)

这是LISP中的动态类型的QuickSort(来自swisspig.net):

(defun quicksort (lis) (if (null lis) nil
  (let* ((x (car lis)) (r (cdr lis)) (fn (lambda (a) (< a x))))
    (append (quicksort (remove-if-not fn r)) (list x)
      (quicksort (remove-if fn r))))))

我认为您在选择语言时会偏颇。众所周知,Lisp太重了。Python与Haskell更为接近。

if len(L) <= 1: return L
return qsort([lt for lt in L[1:] if lt < L[0]]) + [L[0]] + qsort([ge for ge in L[1:] if ge >= L[0]])

此处的Python代码


25
那不是反驳,而是支持的论点。它表明一种语言的类型系统(或缺少语言类型系统)告诉我们的语言是冗长还是简洁。
Apocalisp

2
我同意Apocalisp的观点,冗长不依赖于动态或静态语言。我什至会说静态/动态类型对语言的冗长性几乎没有影响。所以是的,这不是静态的打字营地破坏了反击。
BefittingTheorem

或perl!sort(@array);
詹姆斯·安德森

Apocalisp的整体比较是胡扯。首先,quicksort(由Tony Hoare在原始论文中定义)是一种就地算法,专门设计为使用最少的额外空间,但是Apocalisp使用了Haskell社区的混蛋异地版本,这渐进地浪费了更多内存并运行了数百次比真正的快速排序慢。Haskell难以表达一种真正的快速排序算法,因为它依赖于突变(!)。查看这些Haskell尝试,然后就Haskell所谓的简短程度
JD

其次,您不能基于已针对一种语言专门混用的算法的两种实现方式,对详细程度做出任何有力的说明。查看APL或J或K或Mathematica或任何其他简洁(=现代)动态类型的语言。它们应该比任何静态类型的语言都要简洁。类型推断缩小了差距,但仍然应该有差距。
JD

15

对我来说,动态语言的优势在于,由于较少的代码和功能技术(例如Ruby的代码块和Python的列表理解),代码变得更具可读性

但是后来我有点想念编译时检查(确实发生了打字错误)和IDE自动完成的情况。总体而言,较少的代码和可读性为我带来了回报。

另一个优点是该语言通常具有解释性/非编译性。更改一些代码,然后立即查看结果。在开发过程中确实节省了时间。

最后但并非最不重要的一点是,我喜欢这样一个事实,您可以启动控制台并尝试一些不确定的事情,例如从未使用过的类或方法,并查看其行为。控制台有很多用途,我只供您弄清楚。


我所知道的至少一个Python IDE(即IDLE,恰好是Python解释器的常规构建附带的一个)确实具有自动完成功能,尽管声明的变量仅在解释器窗口中具有它。
JAB

可读吗?您看过quicksort示例吗?我不知道那里发生了什么。您可以争辩说它写得不好,表明您可以写出多快但不可读的东西。
IAdapter

1
@ 01:使用该语言的通用构造。如果您确实了解该语言的基础知识,则该语言相当可读。
EstebanKüber09年

1
可读性与动态类型无关。例如,Scala的lambda通常比Ruby的块短(并且可以说更具表现力),这与Haskell和Python的列表补全比较相同。存在REPL控制台,例如用于F#,Scala,Haskell。快速将已更改的代码加载到正在运行的应用程序是动态语言的优势。尽管有一些技术允许它用于静态语言(例如JavaRebel)。
Alexey

1
有趣的是,我发现代码较少可读。第一是因为我经常无法使用我的IDE来查找声明和嵌入式文档等。第二是因为语法非常紧凑,我忘记了这到底意味着什么!我还将FAR放在IDE自动补全的损失上。它不仅是天赐之物,而且我认为它绝对提高了可维护性。
spronkey 2010年

12

您反对动态语言的说法是完全正确的。但是,请考虑以下事项:

  1. 动态语言不需要编译:只需运行它们即可。在大多数情况下,您甚至可以在运行时重新加载文件而无需重新启动应用程序。
  2. 动态语言通常不太冗长,更易读:您是否曾经看过以静态语言实现的给定算法或程序,然后将其与Ruby或Python相提并论?通常,您正在考虑将代码行减少3倍。在动态语言中,不需要太多的脚手架代码,这意味着最终结果更具可读性,并且更加专注于手头的实际问题。
  3. 不用担心打字问题:使用动态语言进行编程时,通常的方法是不必担心输入:大多数情况下,正确的参数将传递给您的方法。有时,有人可能会使用另一种恰好也起作用的论点。当出现问题时,您的程序可能会停止,但是如果您做了一些测试,这种情况很少发生。

我也觉得刚开始离开安全的静态输入世界有点吓人,但是对我来说,优点远大于缺点,而且我从不回头。


23
1 ..完全垃圾。因为您看不到编译并不意味着它不会发生。它只是在您运行时发生。2 ..乱扔垃圾。结构良好并带有注释的代码易于在所有语言中使用。3大部分时间!您对哪个时代的大部分时间感到满意?很少哈!
baash05

7
@wvdschel:按照您的逻辑,我可以说不需要像C#和Java这样的编译语言进行编译,因为我要做的就是单击我IDE上的“播放”按钮,它们就可以运行。由于我没有注意到IDE正在为我编译,因此“没关系”。
cdmckay

2
@cdmckay:您是否可以连接到正在运行的C#/ Java程序并对其执行命令,在其运行时对其进行修改或查询。解释(许多动态语言是)语言允许运行时内省,而编译后的语言则不允许。
RHSeeger,2009年

4
@RHSeeger-嗯,是的,您可以使用Visual Studio进行所有操作。编辑并继续不限于动态语言。
格雷格·比奇

4
@ baash05,我想您已经完全错过了此答案的要点:1.意味着您可以按需正确运行代码,而无需等待编译器查看每个小更改的影响。2.无论您是否同意它的效果,都会有更少的代码编写和阅读,而无需争论这个事实。
Fire Crow,

8

我相信,从绝对意义上来说,对动态类型语言的“新发现的爱”与静态类型语言的好坏相比,与某些动态语言的普及程度没有多大关系。Ruby on Rails显然是引起动态语言复兴的大现象。使rails如此流行并从静态阵营中产生大量转换的原因主要是:非常简洁和DRY的代码和配置。与需要大量XML配置的Java Web框架相比,尤其如此。许多Java程序员(也包括精明的Java程序员)都进行了转换,甚至还传播了红宝石和其他动态语言。对我来说,三个独特的功能使像Ruby或Python这样的动态语言更加简洁:

  1. 极简主义语法-最大的优点是不需要类型注释,而且语言设计者从一开始就将语言设计得简洁
  2. 内联函数语法(或lambda)-编写内联函数并将其作为变量传递的能力使许多代码更加简短。对于列表/数组操作尤其如此。这种想法的根源显然是LISP。
  3. 元编程-元编程是使rails滴答作响的重要组成部分。它产生了一种新的代码重构方式,使您的库的客户端代码更加简洁。这也源自LISP。

所有这三个功能并非动态语言所独有,但在当今流行的静态语言:Java和C#中肯定不存在。您可能会说C#的委托人中有#2,但我会说它根本没有被广泛使用-例如列表操作。

至于更高级的静态语言... Haskell是一种很棒的语言,它具有#1和#2,尽管它没有#3,但是它的类型系统非常灵活,以至于您可能不会发现缺少元数据限制。我相信您可以在编译时使用语言扩展在OCaml中进行元编程。Scala是最近才添加的,非常有前途。.NET阵营的F#。但是,这些语言的用户很少,因此他们并没有真正为编程语言领域的这一变化做出贡献。实际上,我非常相信Ruby的流行,除了其他动态语言之外,还以积极的方式影响了Haskell,OCaml,Scala和F#等语言的流行。


5
-1:无能为力。包括OCaml在内的ML系列语言是专门为元编程而培育的。这就是ML代表元语言的原因。ML程序员继续革新编程语言领域。.NET和Java中的泛型来自ML。Microsoft的新Visual F#2010是ML的直接后代(它可以满足您的#1,#2和#3)。
JD

7

就我个人而言,我认为只是您使用的大多数“动态”语言恰好只是一般语言的不良示例。

更有效率在Python比C或Java,不只是因为你必须做的编辑-编译-链接-运行舞。我在Objective-C上变得越来越有效率,但是由于框架的原因,这可能更多。

不用说,与PHP相比,我在任何一种语言中的生产率都更高。该死,我宁愿使用Scheme或Prolog进行编码,也不愿使用PHP。(但是最近我实际上在做Prolog上比其他任何事情都多,所以请加一点盐!)


6

我对动态语言的欣赏与它们的功能密切相关。Python的列表理解,Ruby的闭包和JavaScript的原型对象都是这些语言非常吸引人的方面。所有这些功能还具有一流的功能,这是我再也看不到的生活。

我不会以相同的方式对PHP和VB(脚本)进行分类。对我来说,那些主要是命令式语言,具有您建议的所有动态键入缺点。

当然,您不会获得相同级别的编译时检查(因为没有编译时),但是我希望静态语法检查工具会随着时间的发展而发展,至少可以部分解决该问题。


我从未听说过有人暗示他喜欢JavaScript原型对象。
erikkallen 2009年

6

针对动态语言指出的优势之一是仅能够更改代码并继续运行。无需重新编译。在VS.Net 2008中,调试时实际上可以更改代码并继续运行,而无需重新编译。随着编译器和IDE的发展,使用动态语言的优势和其他优势可能会消失。


您是对的,动态类型化语言没有内在的东西可以让您在正在运行的系统中更改代码。使用解释语言(不要与动态语言混淆)要容易得多,但是即使使用编译代码也可以实现。举一个例子,Oracle的PL / SQL是一种静态类型的编译语言,并且Oracle数十年来一直具有该功能,您可以在运行的系统中修改PL / SQL过程。
Apocalisp


动态语言可以调试器之外以及从您的应用程序内部执行此类操作。另外,在单元测试中对类进行猴子修补的可能性可以节省时间。
EstebanKüber09年

6

啊,当我发布类似问题时,我没有看到此主题

除了良好的功能之外,这里提到的其他有关动态语言的人们,我认为每个人都忘记了一个最基本的东西:元编程。

编写程序。

通常,以编译语言很难做到,例如,.Net。为了使其工作,您必须制作各种曼波舞,通常以运行慢大约100倍的代码结束。

大多数动态语言都有一种方法可以进行元编程,这使我始终如一—能够在内存中创建任何类型的代码并将其完美地集成到我的应用程序中。

例如,要在Lua中创建计算器,我要做的就是:

print( loadstring( "return " .. io.read() )() )

现在,尝试在.Net中执行此操作。


6
您经常创建计算器吗?我发现类型“我可以用20个字符创建hello world应用程序”的参数毫无价值。
erikkallen

您刚刚展示了您的想象力多么低。对m8编程很不好。GL。
majkinetor

无需变得个性化。我认为这一点是正确的。提出类型的参数非常容易(而且很常见),“看看您需要编写多少代码才能在C#中向控制台打印行,在lua中我只能说print(“ Hello,world”) '。但是,当项目增长到实际大小时,实际代码与样板的比率并不会保持这种状态。
erikkallen's

2
废话。这是一些在.NET上运行的静态类型的F#:Linq.QuotationEvaluator.Evaluate <@ 2 + 3 @>
JD 2010年

6

我喜欢动态(类型化,因为它似乎是线程的重点)语言的主要原因是,我在工作环境中使用的语言要远远优于我所使用的非动态语言。C,C ++,Java等……它们都是完成实际工作的可怕语言。我很想看到一种隐式类型的语言,它与许多动态类型的语言一样自然。

话虽这么说,但是某些类型的构造在动态类型语言中却是惊人的。例如,在Tcl中

 lindex $mylist end-2

您传递“ end-2”以指示所需索引的事实对于读者而言简明扼要且显而易见。我还没有看到实现这种效果的静态类型语言。


1
用什么方法比$ mylist.length-2好?在我看来,这种语法只会增加额外的关键字,而没有真正的好处,这意味着该语言更难学习。
erikkallen's

我会有点学问,并指出它不会在语言本身中添加任何关键字,而会将其添加到该命令中。话虽这么说,这是一个更清晰的问题。术语“终点”表示意图/含义,而不是如何到达终点。它说“最后一个要素”。
RHSeeger

1
如果我了解您的正确,那情况就更糟了。您必须为每个命令学习新的语法。在命令foo中使用关键字bar的含义是什么?
erikkallen's

@erikkallen:与学习标准库对任何其他语言的不同输入的含义相同。实际上,核心Tcl中的每个命令或多或少只是标准库的一部分。从理论上讲,没有不能删除和重新实现为纯Tcl代码的命令。话虽如此,输入和它们的含义在整个库中是相当一致的(即,end在所有命令中都表示相同的意思)
RHSeeger

5

我认为这种说法有点愚蠢:“编译器通常会捕获诸如拼写错误的变量名以及为变量分配错误类型的值之类的事情,直到运行时才发生”。 PHP开发人员,直到运行时,我才看不到错误键入变量的情况,但对我而言,BUT运行时是步骤2,在C ++中(链接和编译后),它是步骤3,在C ++中。
我的代码正在编译
更不用说在我的代码准备好运行时,从保存到保存需要花费几秒钟的时间,而在编译语言中,这可能要花几个小时。如果这听起来有点生气,我感到很抱歉,但是我有点讨厌人们将我视为二等程序员,因为我不必编译我的代码。


3
哦,我的,在实践中……好吧,也许我只是不称职,但是在PHP中,由于拼写错误而导致的问题是浪费大量时间。特别是当您继承了庞大的代码库而又不允许您打开严格的警告时。
Dan Rosenstark

1
您可以始终打开严格的error_reporting(),任何良好的IDE都可以防止99%的变量拼写错误。
UnkwnTech

更不用说一个人可以用任何语言拼写错误,但是发现这些错误更容易(可能更快),因为我的解释器在链接/编译时处于同一步骤,因此您的反驳再无用。
UnkwnTech

4
-1:编译参数使真正的参数分神,后者涉及键入,静态或动态。动态和静态语言都可以编译和解释。有关拼写和编译时间的投诉不在这些问题之内。
BefittingTheorem

几个小时?原始IBM PC上使用的是什么?
xcramps

3

该论据比这更复杂(阅读Yegge的文章“ Is Weak Typing Strong Enough”获得有趣的概述)。

动态语言也不必缺少错误检查-C#的类型推断可能是一个示例。同样,C和C ++具有糟糕的编译检查,并且它们是静态类型的。

动态语言的主要优点是:a)能力(不必一直使用)和b)博伊德迭代定律

后一个原因是巨大的。


3
类型推断与动态类型不同,因为在编译时仍需要明确地知道推断的类型。
Marcus Downing

4
-1:C#是静态类型的,不是动态类型的。
朱丽叶2009年

2

尽管我还不是Ruby的忠实拥护者,但我发现动态语言确实是非常棒且强大的工具。

没有类型检查和变量声明的想法并不是一个太大的问题。诚然,您必须等到运行时才能捕获这些错误,但是对于有经验的开发人员而言,这并不是真正的问题,当您犯错时,通常可以轻松地将其修复。

它还迫使新手更仔细地阅读他们正在写的内容。我知道学习PHP可以使我更加专注于实际输入的内容,即使使用编译语言,也可以改善我的编程。

优秀的IDE将为您提供足够的智能感知,让您知道变量是否已“声明”,并且它们还会尝试为您进行某种类型推断,以便您可以分辨出变量是什么。

我认为动态语言可以实现的功能真正使它们变得非常有趣。当然,您可以使用编译语言执行相同的操作,但是需要更多代码。像Python和PHP这样的语言使您可以在更少的时间内进行开发,并且在大多数情况下可以更快地获得功能代码库。

作为记录,我是.NET的专职开发人员,并且我喜欢编译语言。我只在业余时间使用动态语言来了解有关它们的更多信息,并成为一名更好的开发人员。


2
我发现任何使用“对于有经验的开发人员来说这都不是真正的问题”的论点通常有点危险。就像我说的那样,对于有经验的开发人员而言,C ++中的OOP /内存管理等并不是问题。为什么使用变量声明和基本类型检查之类的简单操作就需要如此谨慎和经验丰富?我更希望该语言可以帮助我编程,而不是让我犯下使用静态方法可以轻松避免的错误。而且我认为冗长程度与动态或静态键入无关,请查看Haskell或Scala。
BefittingTheorem,2009年

我同意,我也认为该论点有些危险。我的观点是,在编码时进行类型检查的问题还不错。在90%的情况下,您都会立即看到错误。对于隐式类型转换可能导致压力的10%的情况来说,这是一个问题,但是当您知道自己在做什么时,就不会让这种情况发生。JavaScipt是​​10%可能会很危险的一个很好的例子,但是我在开发它的整个过程中从未被它咬过。
丹·赫伯特

@Brian Heylin:那你一定要讨厌C!有很多方法可以射杀自己的脚,但是却经常被人们使用和喜爱。
EstebanKüber09年

2

我认为我们需要不同的语言,这取决于我们要实现的目标或要解决的问题。如果我们想要一个应用程序可以通过互联网从数据库中创建,检索,更新和删除记录,那么与使用静态类型的语言从头开始编写ROR代码(使用脚手架)相比,我们最好不要这样做。使用动态语言可以使您摆脱思考的烦恼

  • 哪个变量具有哪种类型
  • 如何根据需要动态增长字符串
  • 如何编写代码,以便如果我更改一个变量的类型,则不必重写与之交互的所有函数

解决更接近业务需求的问题,例如

  • 数据正在数据库中保存/更新等,如何使用它来驱动网站流量

无论如何,松散类型语言的一个优点是,如果它的行为与预期的一样,我们就不必在意它是什么类型。这就是我们在动态类型语言中进行鸭式输入的原因。这是一个很棒的功能,我可以根据需要使用相同的变量名来存储不同类型的数据。同样,静态类型的语言迫使您像机器一样思考(编译器如何与代码交互,等等),而动态类型的语言(尤其是ruby / ror)则迫使机器像人一样思考。

这些是我用来证明我的工作和动态语言经验的一些论点!


1
您的第1点和第3点是相同的,并且IMO是偏爱静态类型的原因。如果将类型更改为不兼容的内容怎么办?如果将变量从int更改为字符串,则可能是有原因的。如果没有,则只需重新构建项目,直到所有构建错误都消除。通常不会花那么长时间,有时在过程中您会发现一个真正的问题,您很高兴编译器向您指出。第2点无效,除C外,所有语言(我想,至少我遇到的所有语言)都会自动执行字符串增长
。– erikkallen

我同意,根据应用程序的不同,您可能有理由偏爱另一种语言,而速度较快的静态语言可能会带来更好的性能。但是我说的是,如果您必须制作一个与其他网站一样的应用程序,那么使用动态语言比静态语言更快地交付功能可能会更好。同样,假设您需要以x.func =“ yes”和x.func _ =“ no”的方式使用变量x。你不在乎它是哪种类型,只要它像鸭子一样游泳,它就是鸭子。这就是为什么动态类型也称为鸭子类型的原因。还剩0个!
奥马尔

1

我认为两种风格都有其长处。在我看来,这种“或”思维对我们的社区来说是一种残废。我曾在从上到下静态类型化的体系结构中工作,这很好。我最喜欢的体系结构是用于UI级别的动态类型和用于功能级别的静态类型。这也鼓励了将UI和功能分开的语言障碍。

成为愤世嫉俗的人,可能只是因为动态语言使开发人员变得更懒惰,并且使他们对计算的基础知识了解得更少了。这是好事还是坏事取决于读者:)


1

FWIW,在大多数应用程序上编译不需要花费数小时。我已经处理了200-500k行之间的应用程序,这些程序需要几分钟的时间来编译。当然不是几个小时。

我自己更喜欢编译语言。我觉得调试工具(根据我的经验,可能并非对所有情况都适用)更好,而IDE工具则更好。

我喜欢将Visual Studio附加到正在运行的进程。其他IDE可以做到吗?也许吧,但我不知道他们。我最近一直在做一些PHP开发工作,老实说这还不是很糟糕。但是,我非常喜欢C#和VS IDE。我觉得我工作得更快,调试问题也更快。

因此,也许对我来说,这比动态/静态语言问题更重要。

最后一句话...如果您使用本地服务器进行开发,则保存比编译快,但是通常我无法访问本地计算机上的所有内容。数据库和文件共享位于其他位置。FTP到Web服务器比较容易,然后运行我的PHP代码只是为了发现错误,并且必须修复并重新进行FTP。


1
我会说编译时间实际上取决于所使用的语言。在.Net中,如此大小的项目可能只需要花费几分钟即可进行编译。如果完成了C,那么我可能会花一些时间来编译所有内容。
Kibbee

好吧,我会给你的。但是,当您考虑它时,您会想到用C编写多少个项目,而用大量的编译时间来编写PHP是可行的?我认为在某种程度上解释型语言不是工作的正确工具,反之亦然。我非常热衷于为工作选择合适的工具,并使用您最擅长的工具。我看不出有理由尝试让一种语言做所有事情都可以轻松完成的事情。没有理由重新学习您所知道的。
bdwakefield's

顺便说一句,有一个VS jcxsoftware.com/vs.php的php插件,我还没有尝试过,因为它不是免费的,但所知,它与Zend一样好(5.5糟透了6) VS的好处
UnkwnTech

您只是想知道没人使用动态语言的最大原因之一。没有人构建过花哨的200万行代码IDE,几乎可以在其中任何一个代码上为您做任何事情,所以每个人都在抱怨“它们的类型不安全,因此很容易出错”
RCIX,2009年

我不在乎类型安全的废话。那并没有让我感到困扰。我最大的抱怨是,从物理上讲,它花费的时间更长,而且往往很难发现问题。对我而言,我认为发展风格与我喜欢的工作方式背道而驰。
bdwakefield

1

在一定背景下的生产力。但这只是我所知道的一种环境,与我所知道或曾经看到的其他环境相比。

与ASP.Net(/ MVC),RoR或Wicket相比,带有Seaside的Squeak / Pharo上的Smalltalk是效率更高,效率更高的Web平台,适用于复杂的应用程序。直到您需要与其中一个具有库但不包含smalltalk的库进行交互。

拼写错误的变量名称在IDE中为红色,IntelliSense可以工作,但不那么具体。网页上的运行时错误不是问题,而是一项功能,只需单击一下即可调出调试器,然后单击我的IDE,修复调试器中的错误,然后保存并继续。对于简单的错误,此周期的往返时间少于20秒。



1

因为我认为必须声明框的类型是愚蠢的。类型取决于实体,而不是容器。当框的类型直接影响到内存中的位的解释方式时,就可以使用静态类型。

如果您查看GoF中的设计模式,您将意识到其中的很大一部分只是为了与语言的静态特性作斗争,而没有理由将它们存在于动态语言中。

另外,我已经厌倦了不得不编写MyFancyObjectInterface f = new MyFancyObject()之类的东西。干燥原理有人吗?


1

让自己代替一个全新的程序员来选择一种语言作为开始,他们不关心动态,静态,lambda,这种,那种等等。您会选择哪种语言?

C#

using System;
class MyProgram
{
    public static void Main(string[] args)
    {
        foreach (string s in args)
        {
            Console.WriteLine(s);
        }
    }
}

卢阿:

function printStuff(args)
    for key,value in pairs(args) do
       print value .. " "
    end
end
strings = {
    "hello",
    "world",
    "from lua"
}
printStuff(strings)

3
真的,这不是争论。我们不是全新的程序员;非全新程序员之间的争论最为激烈。
peSHIr

这只是程序员可能偏爱动态语言的原因之一。他们通常比其他人更容易理解,因此吸引了更多的新程序员。
RCIX

1

这全部归结为适合于特定目标的部分内容以及常见的个人偏好。(例如,这将是一个庞大的代码库,需要更多的人维护,而不是可以在一起进行合理的聚会?您想要类型检查。)

私人方面是权衡一些检查和其他步骤以提高开发和测试速度(同时可能会放弃某些CPU性能)。有些人正在为此而解放,并提高了性能,有些人则与此相反,是的,它的确也取决于您语言的特殊风格。我的意思是,这里没有人说过Java可以促进快速简洁的开发,或者PHP是一种可靠的语言,您几乎不会发现拼写错误。


1

我喜欢静态和动态语言。自2002年左右以来,我参与的每个项目都是一个带有嵌入式Python解释程序的C / C ++应用程序。这使我两全其美:

  1. 对于应用程序的给定版本,组成应用程序的组件和框架是不可变的。它们还必须非常稳定,因此必须经过良好测试。静态类型的语言是构建这些部件的正确选择。
  2. 组件的连接,组件DLL的加载,插图,大多数GUI等...可以有很大的不同(例如,为客户端定制应用程序),而无需更改任何框架或组件代码。动态语言是完美的选择。

我发现使用静态类型的语言来构建系统和使用动态类型的语言来配置系统可以为我提供灵活性,稳定性和生产率。

回答“对动态语言的热爱是什么?”的问题。对我来说,它是在运行时以任何可以想象的方式完全重新连接系统的功能。我将脚本语言视为“运行节目”,因此正在执行的应用程序可以执行您想要的任何事情。


1

我一般对动态语言没有太多经验,但是我绝对喜欢一种动态语言,JavaScript(又名ECMAScript)。

好吧,等等,这里的讨论是什么?动态编译?还是动态打字?JavaScript涵盖了这两个方面,所以我想我将同时讨论这两个方面:

动态编译

首先,编译动态语言,只是将编译推迟到以后。Java和.NET实际上被编译了两次。一次是使用它们各自的中间语言,然后是动态地使用机器代码。

但是,推迟编译后,您可以更快地看到结果。那是优势之一。我确实喜欢简单地保存文件,并很快看到我的程序在运行。

另一个优点是您可以在运行时编写和编译代码。我不知道这在静态编译的代码中是否可行。我想一定是这样,因为编译JavaScript的最终都是机器代码,并且是静态编译的。但是在动态语言中,这是一件微不足道的事情。代码可以编写和运行。(而且我非常确定.NET可以做到这一点,但是.NET编译到的CIL总是动态地动态编译的,在C#中并不是那么简单)

动态类型

我认为动态类型比静态类型更具表现力。请注意,我非正式地使用“表达”一词来表示动态类型可以说的少而多。这是一些JavaScript代码:

var Person = {};

你知道人现在是什么吗?这是一本通用词典。我可以做这个:

Person [“ First_Name”] =“ John”;
Person [“ Last_Name”] =“ Smith”;

但这也是一个对象。我可以像这样引用任何“键”:

人名

并添加我认为必要的任何方法:

Person.changeFirstName = function(newName){
  this.First_Name = newName;
};

当然,如果newName不是字符串,可能会出现问题。即使有,它也不会立即被捕获,但是您可以检查一下自己。为了安全起见,要交换表达能力和灵活性。我不介意自己添加代码来检查类型等,而且我还没有遇到类型错误,这给我带来很多麻烦(而且我知道这并没有说太多。这可能是时间问题: ))。但是,我非常喜欢这种动态适应的能力。


1

关于同一主题的不错的博客文章:Python使我紧张

方法签名实际上在Python中是无用的。在Java中,静态类型使方法签名成为一个配方:这是使该方法起作用所需的全部内容。在Python中不是这样。在这里,方法签名只会告诉您一件事:要使它起作用,需要多少个参数。有时候,如果您开始****,那么它甚至都不会这样做。



0

弱类型语言使您可以灵活地管理数据。

去年春天,我在几个类中使用了VHDL,我喜欢它们表示位/字节的方法,并且喜欢尝试将6位总线分配给9位总线时编译器如何捕获错误。我试图在C ++中重新创建它,但我在公平地努力使类型与现有类型一起使用时一直很努力。我认为,Steve Yegge在描述强类型系统所涉及的问题方面做得非常好。

关于冗长性:我发现Java和C#在大型语言中非常冗长(让我们“挑剔”一下小的算法来“证明”一点)。而且,是的,我都写过。C ++也在同一领域中挣扎。VHDL在这里屈服。

简约似乎是动态语言的优点(我以Perl和F#为例)。


将9位总线分配给6位总线的等效方法是尝试将int分配给short或类似的东西。这是C#(我认为是Java)中的错误,任何C或C ++编译器都应该能够发出有关此错误的警告。
erikkallen's

-1。Weakly typed language != Dynamically typed language
Joe D 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.