似乎每个人最近都在跳跃着充满活力,没有编辑的潮流.我大多只使用编译的静态类型语言(C,Java,.Net).我对动态语言的体验是ASP(Vb Script),JavaScript和PHP.在考虑动态语言时,使用这些技术在我的嘴里留下了不好的味道.通常会被编译器捕获的事情(例如拼写错误的变量名称以及将错误类型的值分配给变量)直到运行时才会发生.即便如此,您可能也不会注意到错误,因为它只是创建一个新变量,并分配一些默认值.我也从未见过intellisense在动态语言中运行良好,因为变量没有任何明确的类型.
我想知道的是,人们对动态语言有何吸引力?动态语言允许您执行的操作无法完成或在编译语言中难以完成的主要优点是什么.在我看来,我们很久以前就决定,像未编译的asp页面抛出运行时异常这样的事情是个坏主意.为什么这类代码会重新出现?为什么至少在我看来,Ruby on Rails看起来并不像10年前你用ASP做过的任何东西?
我认为原因是人们习惯于静态类型的语言,这些语言具有非常有限且无法表达的类型系统.这些是Java,C++,Pascal等语言.而不是朝着更具表现力的类型系统和更好的类型推断的方向发展(例如在Haskell中,甚至在某种程度上甚至是SQL),有些人喜欢只保留所有"类型"信息都在他们的头脑中(以及他们的测试中),并完全取消静态类型检查.
这到底是什么让你不清楚.关于类型检查存在许多误解的概念,我最常见的是这两个概念.
谬误:动态语言不那么冗长.误解是类型信息等于类型注释.这完全是不真实的.我们都知道类型注释很烦人.机器应该能够找出那些东西.事实上,它在现代编译器中确实存在.这是一个静态类型的QuickSort,分为两行Haskell(来自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的静态类型和解释时间比我还活着的时间更长.
你知道,也许充满活力的人群只是希望自由不必仔细考虑他们正在做的事情.该软件可能不正确或不健壮,但可能并非如此.
就个人而言,我认为那些放弃类型安全以购买一点暂时自由的人,既不应该获得自由,也不应该打字安全.
不要忘记您需要在单元测试中编写10x代码覆盖率来替换编译器所做的事情:D
我去过那里,用动态语言完成,我看到绝对没有优势.
在阅读其他人的回答时,似乎动态语言或多或少有三个参数:
1)代码不那么冗长.我觉得这没有效果.一些动态语言比一些静态语言更简洁.但是F#是静态类型的,但是那里的静态类型并没有添加太多(如果有的话)代码.但它是隐式输入的,但这是另一回事.
2)"我最喜欢的动态语言X有我最喜欢的功能特性Y,因此动态更好".不要混淆功能和动态(我不明白为什么要这么说).
3)在动态语言中,您可以立即看到结果.新闻:您也可以在Visual Studio中使用C#(自2005年起).只需设置一个断点,在调试器中运行程序并在重新编译时修改程序.我一直都这样做,而且效果很好.
我自己,我是静态打字的坚定拥护者,主要原因之一是:可维护性.我有一个系统,里面有几行10k的JavaScript,我想要做的任何重构都需要半天,因为(不存在的)编译器不会告诉我变量重命名的内容.这就是我自己编写的代码,IMO结构合理.我不希望被任命为其他人写的等效动态系统.
我想我会为此大力投票,但我会抓住机会.
VBScript很糟糕,除非你把它与另一种VB比较.PHP是可以的,只要你记住它是一种过度生长的模板语言.现代Javascript很棒.真.很有趣.只要远离任何标记为"DHTML"的脚本.
我从未使用过不允许运行时错误的语言.恕我直言,这主要是一个红鲱鱼:编译器没有捕获所有拼写错误,也没有验证意图.当您需要显式类型时,显式键入很棒,但大多数情况下,您不需要.在这里搜索问题generics
或关于使用无符号类型是否是索引变量的一个好选择的问题 - 大多数时候,这些东西只是妨碍了,并且当他们有时间在他们的手上时让人们旋转.
但是,我还没有真正回答你的问题.为什么动态语言很吸引人?因为过了一段时间,编写代码变得迟钝,你只想实现算法.你已经坐下来用笔,图解的潜在问题场景进行了全部工作并证明它们是可解决的,剩下要做的就是编写二十行实现代码......以及两百行样板来编译.然后你意识到你使用的类型系统并没有反映出你实际在做什么,而是其他人对你可能在做什么的超抽象概念,而你很久以前就放弃了编程以进行knicknack调整,所以强迫性的,即使是虚构的侦探阿德里安·蒙克也会感到羞耻.
当你去涂抹时,开始认真研究动态语言.
我是一名全职的.Net程序员,完全陷入了静态类型的C#的阵痛中.但是,我喜欢现代JavaScript.
一般来说,我认为动态语言允许您比静态类型语言更简洁地表达您的意图,因为您花费更少的时间和空间来定义构建块在您尝试表达的内容时,在许多情况下它们是不言而喻的.
我认为也有多种动态语言.我不想再回到VBScript中编写经典的ASP页面了.为了有用,我认为动态语言需要在其核心支持某种集合,列表或关联构造,以便可以表达对象(或对象的传递),并允许您构建更复杂的构造.(也许我们都应该只在LISP中编码...这是一个笑话......)
我认为在.Net圈子中,动态语言会因为与VBScript和/或JavaScript相关而变得糟糕.由于Kibbee声明的许多原因,VBScript只是一个被召回的噩梦 - 任何人都记得使用CLng在VBScript中强制执行类型以确保你有足够的位用于32位整数.此外,我认为JavaScript仍然被视为下拉菜单的浏览器语言,它以不同的方式为所有浏览器编写.在这种情况下,问题不是语言,而是各种浏览器对象模型.有趣的是,C#越成熟,它开始看起来越动态.我喜欢Lambda表达式,匿名对象和类型推断.每天感觉更像是JavaScript.
这是一个静态类型的QuickSort,分为两行Haskell(来自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))))))
我认为你在这里用你选择的语言来偏见.众所周知,Lisp非常沉重.与Haskell更接近的是Python.
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代码来自这里
对我来说,动态语言的优势在于代码变得更加可读,因为更少的代码和功能技术,如Ruby的块和Python的列表理解.
但后来我有点想念编译时检查(错字确实发生)和IDE自动完成.总的来说,较少的代码和可读性为我带来了回报.
另一个优点是语言的通常解释/非编译性质.更改一些代码并立即查看结果.在开发过程中真的节省了时间.
最后但并非最不重要的是,我喜欢这样一个事实:你可以启动一个控制台并尝试一些你不确定的东西,比如你以前从未使用过的类或方法,看看它是如何表现的.控制台有很多用途,我只想留下让你弄清楚.
你反对动态语言的论据是完全有效的.但是,请考虑以下事项:
动态语言不需要编译:只需运行它们.您甚至可以在运行时重新加载文件,而无需在大多数情况下重新启动应用程序.
动态语言通常不那么冗长和可读性:你是否曾经看过用静态语言实现的给定算法或程序,然后将它与Ruby或Python等价物进行比较?一般来说,您正在考虑将代码行减少3倍.动态语言中不需要很多脚手架代码,这意味着最终结果更具可读性,更专注于手头的实际问题.
不要担心输入问题:在动态语言编程时的一般方法是不要担心键入:大多数时候,正确的参数将传递给您的方法.有一段时间,有人可能会使用一种恰好同样适用的不同类型的论点.当出现问题时,您的程序可能会停止,但如果您已经完成了一些测试,则很少发生这种情况.
我也发现一开始就远离静态打字的安全世界有点可怕,但对我而言,优势远远超过了缺点,而且我从未回头.
我认为动态类型语言的"新发现的爱"与静态类型语言在绝对意义上是否优于某些动态语言的普及程度有关.Ruby on Rails显然是一个引起动态语言复兴的重要现象.使得rails如此受欢迎并且从静态阵营中创建了如此多的转换器的主要原因是:非常简洁和干燥的代码和配置.与需要大量XML配置的Java Web框架相比,尤其如此.许多Java程序员 - 也是聪明的程序员 - 进行了转换,有些甚至传播了ruby和其他动态语言.对我来说,三个不同的功能允许像Ruby或Python这样的动态语言更简洁:
极简主义语法 - 最重要的是不需要类型注释,而且语言设计师从一开始就设计语言简洁
内联函数语法(或lambda) - 编写内联函数并将它们作为变量传递的能力使得多种代码更加简洁.特别是列表/数组操作也是如此.这个想法的根源显然是 - LISP.
元编程 - 元编程是使轨道变形的重要组成部分.它产生了一种重构代码的新方法,使您的库的客户端代码更加简洁.这也来自LISP.
所有这三个功能并不是动态语言所独有的,但它们当然不存在于当今流行的静态语言中:Java和C#.您可能认为C#在代理中有#2,但我认为它根本没有被广泛使用 - 例如列表操作.
至于更高级的静态语言...... Haskell是一种很棒的语言,它有#1和#2,虽然它没有#3,但它的类型系统非常灵活,你可能不会发现缺少meta限制.我相信你可以在编译时使用语言扩展在OCaml中进行元编程.Scala是最近添加的,非常有前景..NET阵营的F#.但是,这些语言的用户占少数,因此他们并没有真正为编程语言领域的这种变化做出贡献.事实上,除了其他动态语言之外,我非常相信Ruby的受欢迎程度会以积极的方式影响Haskell,OCaml,Scala和F#等语言的流行.
就个人而言,我认为你所使用的大多数"动态"语言恰好都是一般语言的不良例子.
我的方式更有效率在Python比C或Java,不只是因为你必须做的编辑-编译-链接-运行舞.我在Objective-C中的效率越来越高,但这可能更多是由于框架.
毋庸置疑,除了PHP之外,我在这些语言中的效率更高.好吧,我宁愿在Scheme或Prolog中编写代码而不是PHP代码.(但是最近我实际上做了更多的Prolog而不是其他任何东西,所以拿一点盐!)
我对动态语言的理解与它们的功能性密切相关.Python的列表推导,Ruby的闭包和JavaScript的原型对象都是这些语言非常吸引人的方面.所有这些都具有一流的功能 - 我再也看不到生活.
我不会以同样的方式对PHP和VB(脚本)进行分类.对我来说,这些主要是命令式语言,具有你建议的所有动态类型缺陷.
当然,您没有获得相同级别的编译时检查(因为没有编译时间),但我希望静态语法检查工具能够随着时间的推移而发展,以至少部分地解决该问题.
为动态语言指出的一个优点是能够更改代码并继续运行.无需重新编译.在VS.Net 2008中,在调试时,您实际上可以更改代码并继续运行,而无需重新编译.随着编译器和IDE的进步,使用动态语言的这一优势和其他优势是否有可能消失.
啊,当我发布类似问题时,我没有看到这个话题
除了这里提到的关于动态语言的其他人的好功能之外,我想每个人都会忘记一个,最基本的东西:元编程.
编程程序.
在编译语言中很难做到,一般来说,例如.Net.为了使它工作,你必须制作所有类型的mambo jumbo,它通常以运行速度大约100倍的代码结束.
大多数动态语言都有一种方法可以进行元编程,这是让我在那里的能力 - 能够在内存中创建任何类型的代码并将其完美地集成到我的应用程序中.
例如,要在Lua中创建计算器,我所要做的就是:
print( loadstring( "return " .. io.read() )() )
现在,尝试在.Net中这样做.
喜欢动态(键入,因为这似乎是线程的焦点)语言的主要原因是我使用的(在工作环境中)远远优于我使用的非动态语言.C,C++,Java等......它们都是用于完成实际工作的可怕语言.我希望看到一种隐式类型语言,这种语言在许多动态类型语言中编程是很自然的.
话虽这么说,但某些结构在动态类型语言中才是惊人的.例如,在Tcl中
lindex $mylist end-2
您传入"end-2"以指示您想要的索引这一事实对读者来说非常简洁明了.我还没有看到一种完成这种语言的静态类型语言.
我认为这种论点有点愚蠢:"通常会被编译器捕获的事情,例如拼写错误的变量名称,并将错误类型的值分配给变量,直到运行时才出现"是的,这是正确的PHP开发人员我直到运行时才看到输入错误的变量,BUT运行时是我的第2步,在C++中(这是我有经验的唯一编译语言)它是链接和编译后的第3步.
更不用说在我点击保存到我的代码准备运行之后需要几秒钟,而不像在编译语言中它需要几个小时.我很抱歉,如果这听起来有点生气,但我有点厌倦了人们把我视为二流程序员,因为我不需要编译我的代码.