人们对dynamic语言有什么吸引力?
最近似乎每个人都在跳跃式的,非编制的潮stream。 我大多只使用编译的静态types语言(C,Java,.Net)。 我对dynamic语言的体验是像ASP(VB脚本),JavaScript和PHP的东西。 在思考dynamic语言的时候,使用这些技术在我的口中留下了不好的口味。 通常会被编译器捕获的东西,例如拼写错误的variables名称,以及将错误types的值赋给variables,直到运行时才会出现。 即使如此,你可能不会注意到一个错误,因为它只是创build一个新的variables,并分配一些默认值。 我从来没有见过intellisense在dynamic语言中工作得很好,因为variables没有任何明确的types。
我想知道的是,人们对dynamic语言有什么吸引力? 在dynamic语言允许你做的事情方面,主要的优势是什么,不能做到,或者在编译语言中很难做到。 在我看来,我们很久以前就决定,像未编译的asp页面抛出运行时exception是一个坏主意。 为什么这种types的代码重新出现? 至less在我看来,Ruby on Rails实际上不像10年前的ASP所做的任何事情?
我认为原因在于人们习惯于静态types的语言,这些语言的types系统非常有限而且压抑。 这些语言如Java,C ++,Pascal等等,而不是朝着更具performance力的types系统和更好的types推断的方向发展(例如Haskell,甚至在某种程度上,甚至SQL),有些人喜欢只保留所有的“types”信息(在他们的testing中),并且完全消除静态types检查。
这到底是什么东西买不清楚。 对于types检查有许多误解,我最常遇到的就是这两个。
谬论:dynamic语言不太冗长。 误解是types信息等于types注释。 这完全是不真实的。 我们都知道,types注释很烦人。 机器应该能够把那东西弄出来。 事实上,它在现代编译器中也是如此。 这里有两行Haskell(来自haskell.org )的一个静态types的QuickSort :
qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
这里是一个dynamictypes的LISP中的QuickSort (来自swisspig.net ):
(defun quicksort (lis) (if (null lis) nil (let* ((x (car lis)) (r (cdr lis)) (fn (lambda (a) (< ax)))) (append (quicksort (remove-if-not fn r)) (list x) (quicksort (remove-if fn r))))))
Haskell的例子伪造了静态types的假设,因此是冗长的 。 LISP的例子伪造了假设详细的,因此是静态types的 。 在打字和冗长之间没有任何方向的含义。 你可以放心地把它放在心上。
谬论:静态types的语言必须被编译,而不是被解释。 再次,不是真的。 许多静态types的语言都有解释器。 有Scala解释器,Haskell的GHCi和Hugs解释器,当然,SQL的静态types和解释时间都比我还活着。
你知道,也许dynamic的人群只是想要自由,不必小心翼翼地思考他们在做什么。 该软件可能不正确或健壮,但也许不一定是。
就个人而言,我认为那些放弃安全types购买一点临时自由的人,不应该享有自由,也不应该享有types安全。
不要忘记,你需要在unit testing中编写10倍的代码覆盖率来replace你的编译器所做的事情:D
我一直在那里,用dynamic语言做到这一点,我看到绝对没有优势。
在阅读其他人的回答时,dynamic语言似乎有三个或多或less的参数:
1)代码不太冗长。 我不觉得这个有效。 一些dynamic语言不如一些静态语言冗长。 但是F#是静态types的,但是静态types没有添加任何代码。 这是隐式input,但是,这是一个不同的事情。
2)“我最喜欢的dynamic语言X有我最喜欢的function特性Y,所以dynamic更好”。 不要混用function性和dynamic性(我不明白为什么要这么说)。
3)在dynamic语言中,你可以立即看到你的结果。 新闻:您也可以使用Visual Studio中的C#(从2005年开始)这样做。 只需设置一个断点,在debugging器中运行程序,并在debbuging中修改程序。 我一直这样做,它完美的作品。
我自己,我是一个强大的倡导静态打字,主要原因之一:可维护性。 我有一个系统中有几个10K的JavaScript代码, 任何我想要做的重构将花费半天的时间,因为(不存在的)编译器不会告诉我这个variables重命名搞砸了。 这就是我自己写的代码,国际海事组织结构也很好。 我不希望被任命负责别人写的等效dynamic系统。
我想我会为此大量低估,但我会抓住机会。
VBScript糟透了,除非你把它与VB的另一种风格相比较。 PHP是好的,只要你记住,这是一个过度发展的模板语言。 现代的Javascript是伟大的。 真。 好玩的。 只要远离任何标有“DHTML”的脚本即可。
我从来没有使用过不允许运行时错误的语言。 恕我直言,这在很大程度上是一个红鲱鱼:编译器不抓住所有的错别字,也不会validation意图。 当你需要明确的types时,明确的input是很好的,但是大多数情况下,你不需要。 在这里search关于generics
的问题,或者关于是否使用无符号types是索引variables的好select的问题 – 很多时候,这些东西只是阻碍了它们,并且在有时间的时候让它们旋转手中。
但是,我还没有真正回答你的问题。 为什么dynamic语言有吸引力? 因为过了一段时间,编写代码变得迟钝,你只是想实现algorithm。 你已经坐下来,用笔写出了所有的问题,并且certificate了它们是可以解决的,唯一剩下要做的就是编码20行代码……并且编译200行代码,以便编译。 然后你意识到,你所使用的types系统并不能反映你实际在做什么,而是其他人对你可能在做什么的超抽象的想法,而你早就放弃了对knicknack一生的调整强迫性的,即使是虚构的侦探阿德里安·蒙克也会感到羞耻。
那就是当你开始认真对待dynamic语言的时候。
我是一个全职的.Net程序员,在静态types化C#的阵痛中深陷其中。 不过,我喜欢现代的JavaScript。
一般来说,我认为dynamic语言允许你比静态types语言更简洁地expression你的意图,因为你花费更less的时间和空间去定义什么是你想要expression的东西,而在很多情况下它们是不言而喻的。
我认为也有多种dynamic语言。 我不想回到用VBScript编写经典的ASP页面。 为了有用,我认为dynamic语言需要支持某种集合,列表或关联构造的核心,以便可以表示对象(或对象的传递),并允许构build更复杂的构造。 (也许我们应该只是在LISP中编码…这是一个笑话…)
我认为在.NET环境中,dynamic语言会因为与VBScript和/或JavaScript相关联而受到不好的说服。 VBScript仅仅是Kibbee所说的许多原因的一个噩梦 – 任何人都记得用CLng强制inputVBScript,以确保你获得了足够的32位整数。 另外,我认为JavaScript仍然被视为下拉菜单的浏览器语言,对于所有浏览器而言都是以不同的方式编写的。 在这种情况下,问题不是语言,而是各种浏览器对象模型。 有趣的是,越多的C#成熟,它开始看起来越dynamic。 我喜欢Lambdaexpression式,匿名对象和types推断。 每天都更像是JavaScript。
这里有两行Haskell(来自haskell.org)的一个静态types的QuickSort:
qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
这里是一个dynamictypes的LISP中的QuickSort(来自swisspig.net):
(defun quicksort (lis) (if (null lis) nil (let* ((x (car lis)) (r (cdr lis)) (fn (lambda (a) (< ax)))) (append (quicksort (remove-if-not fn r)) (list x) (quicksort (remove-if fn r))))))
我认为你在这里用你select的语言偏向东西。 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代码从这里
对我来说,dynamic语言的优势在于代码变得更可读,这是由于较less的代码和像Ruby的块和Python的列表理解这样的function性技术。
但后来我错过了编译时检查(错字发生)和IDE自动完成。 总的来说,较less的代码和可读性为我付出了代价。
另一个优点是语言的通常解释/非编译性质。 改变一些代码,立即看到结果。 这在开发过程中确实节省时间。
最后但并非最不重要的一点,我喜欢这样一个事实:你可以启动一个控制台 ,尝试一些你不确定的事情,比如你以前从未使用过的类或方法,看看它的行为。 控制台有很多用途,我只是留给你弄清楚。
你对dynamic语言的论点是完全有效的。 但是,请考虑以下几点:
- dynamic语言不需要编译 :只需运行它们。 您甚至可以在运行时重新加载文件,而无需在大多数情况下重新启动应用程序。
- dynamic语言通常不那么冗长和更具可读性 :您是否曾经查看过使用静态语言实现的给定algorithm或程序,然后将其与Ruby或Python等价物进行比较? 一般来说,您将代码行数减less了3倍。在dynamic语言中,大量脚手架代码是不必要的,这意味着最终结果更具可读性,更关注实际的问题。
- 不要担心input问题 :用dynamic语言编程时的一般方法是不要担心键入问题:大多数情况下,正确的参数将传递给您的方法。 有一段时间,有人可能会使用一种不同的论点,恰好也是如此。 当事情出错的时候,你的程序可能会停止,但是如果你做了一些testing,这种情况很less发生。
起初,我也觉得离开静态键入的安全世界有些可怕,但对我来说,优势远远超过了缺点,我从来没有回头。
我相信,对于dynamic语言来说,“新发现的爱”与静态types语言在绝对意义上是好还是坏有关,而不是某些dynamic语言的普及程度的提高。 Ruby on Rails显然是导致dynamic语言再度兴起的一大现象。 使铁轨如此受欢迎,并创造了如此之多的从静态营转换的东西主要是: 非常简洁和干燥的代码和configuration。 与需要大量XMLconfiguration的Java Web框架相比,情况尤其如此。 许多Java程序员 – 聪明的 – 也转换过来了,有些甚至传布了ruby和其他dynamic语言。 对我来说,三个不同的特性允许像Ruby或Python这样的dynamic语言更加简洁:
- 最简单的语法 – 最大的一个是不需要types注释,而且语言devise者从一开始就devise语言是简洁的
- 内联函数语法(或lambda) – 编写内联函数并将其作为variables传递的function使得多种代码更加简洁。 特别对于列表/数组操作而言,这是正确的。 这个想法的根源显然是 – LISP。
- 元编程 – 元编程是导致轨道跳动的重要组成部分。 它引发了一种重构代码的新方法,允许库的客户端代码更加简洁。 这也源于LISP。
所有这三个特性都不是dynamic语言所独有的,但是它们当然不会出现在当今stream行的静态语言中:Java和C#。 你可能会认为C#在代表中有#2,但是我认为它并没有被广泛使用,比如列表操作。
至于更先进的静态语言… Haskell是一个美妙的语言,它有#1和#2,虽然它没有#3,它的types系统是如此灵活,你可能不会find缺乏元限制。 我相信你可以在编译时使用语言扩展在OCaml中进行元编程。 斯卡拉是一个非常新的,是非常有前途的。 F#为.NET阵营。 但是,这些语言的用户是less数,所以他们并没有真正为编程语言的这种变化做出贡献。 事实上,我非常相信,除了其他dynamic语言之外,Ruby的stream行还以积极的方式影响了Haskell,OCaml,Scala和F#等语言的stream行。
就个人而言,我认为只是大部分你使用的“dynamic”语言恰好是一般语言的糟糕例子。
在Python中,我比Python或Java中的效率更高,而不仅仅是因为你必须执行编辑 – 编译 – 链接 – 运行的舞蹈。 我在Objective-C中获得了更高的生产力,但这可能更多归功于框架。
不用说,我比任何这些语言都更有成效。 地狱,我宁愿计划或Prolog比PHP编码。 (但是最近我实际上已经做了更多的Prolog而不是其他任何东西,所以拿一点盐来吧!)
我对dynamic语言的欣赏与它们的function有很大关系。 Python的列表parsing,Ruby的闭包以及JavaScript的原型对象都是这些语言非常有吸引力的一个方面。 所有这些function都具有一stream的function – 我再也看不到这种生活了。
我不会用同样的方式对PHP和VB(脚本)进行分类。 对我来说,那些大多是命令式语言,所有你提出的dynamic键入的缺点。
当然,你没有得到相同级别的编译时间检查(因为没有编译时间),但是我希望静态语法检查工具随着时间的推移而演变,至less部分地解决这个问题。
dynamic语言指出的优点之一就是能够更改代码并继续运行。 不需要重新编译。 在VS.Net 2008中,在debugging时,实际上可以更改代码,并继续运行,而无需重新编译。 随着编译器和IDE的进步,使用dynamic语言的这种优势和其他优势是否会消失?
啊,当我发表类似的问题时,我没有看到这个话题
除了这里提到的关于dynamic语言的其他人的优秀特性之外,我想每个人都会忘记一个最基本的东西:元编程。
编程该程序。
一般来说,在编译语言中做相当难,例如.Net。 为了使它工作,你必须使所有types的曼波巨无霸,它通常以约100倍慢的代码结束。
大多数dynamic语言都有一种方法来进行元编程,这是让我在那里 – 在内存中创build任何types的代码的能力,并完全整合到我的应用程序。
比如要在Lua里创build计算器,我所要做的就是:
print( loadstring( "return " .. io.read() )() )
现在,尝试在.Net中这样做。
我喜欢dynamic(键入,因为这似乎是线程的焦点)语言的主要原因是,我用过的(在工作环境中)远远优于我使用的非dynamic语言。 C,C ++,Java等等,它们都是可怕的语言来完成实际的工作。我很想看到一种隐式types的语言,在很多dynamictypes的语言中编程是很自然的。
这就是说,在dynamictypes语言中有一些令人惊讶的构造。 例如,在Tcl中
lindex $mylist end-2
事实上,你通过“结束2”来表明你想要的索引是非常简洁明了的读者。 我还没有看到完成这样的静态types的语言。
我认为这种说法有点愚蠢:“通常会被编译器捕获的东西,比如拼错的variables名称,以及将一个错误types的值赋值给一个variables,直到运行时才会出现”是的, PHP开发人员直到运行时,我才看到错误types的variables,但是运行时对于我来说是第二步,在C ++(这是唯一编译的语言,我有任何经验),它是第三步,链接和编译之后。
更不用说,在我的代码准备好运行的时候,我需要花费几秒钟的时间,而不像编译语言那样花费几个小时。 对不起,如果这听起来有点生气,但我有些厌倦了人们把我当成二stream程序员,因为我不必编译我的代码。
The argument is more complex than this (read Yegge's article "Is Weak Typing Strong Enough" for an interesting overview).
Dynamic languages don't necessarily lack error checking either – C#'s type inference is possibly one example. In the same way, C and C++ have terrible compile checks and they are statically typed.
The main advantages of dynamic languages are a) capability (which doesn't necessarily have to be used all the time) and b) Boyd's Law of Iteration .
The latter reason is massive.
Although I'm not a big fan of Ruby yet, I find dynamic languages to be really wonderful and powerful tools.
The idea that there is no type checking and variable declaration is not too big an issue really. Admittedly, you can't catch these errors until run time, but for experienced developers this is not really an issue, and when you do make mistakes, they're usually easily fixed.
It also forces novices to read what they're writing more carefully. I know learning PHP taught me to be more attentive to what I was actually typing, which has improved my programming even in compiled languages.
Good IDEs will give enough intellisense for you to know whether a variable has been "declared" and they also try to do some type inference for you so that you can tell what a variable is.
The power of what can be done with dynamic languages is really what makes them so much fun to work with in my opinion. Sure, you could do the same things in a compiled language, but it would take more code. Languages like Python and PHP let you develop in less time and get a functional codebase faster most of the time.
And for the record, I'm a full-time .NET developer, and I love compiled languages. I only use dynamic languages in my free time to learn more about them and better myself as a developer..
I think that we need the different types of languages depending on what we are trying to achieve, or solve with them. If we want an application that creates, retrieves, updates and deletes records from the database over the internet, we are better off doing it with one line of ROR code (using the scaffold) than writing it from scratch in a statically typed language. Using dynamic languages frees up the minds from wondering about
- which variable has which type
- how to grow a string dynamically as needs be
- how to write code so that if i change type of one variable, i dont have to rewrite all the function that interact with it
to problems that are closer to business needs like
- data is saving/updating etc in the database, how do i use it to drive traffic to my site
Anyway, one advantage of loosely typed languages is that we dont really care what type it is, if it behaves like what it is supposed to. That is the reason we have duck-typing in dynamically typed languages. it is a great feature and i can use the same variable names to store different types of data as the need arises. also, statically typed languages force you to think like a machine (how does the compiler interact with your code, etc etc) whereas dynamically typed languages, especially ruby/ror, force the machine to think like a human.
These are some of the arguments i use to justify my job and experience in dynamic languages!
I think both styles have their strengths. This either/or thinking is kind of crippling to our community in my opinion. I've worked in architectures that were statically-typed from top to bottom and it was fine. My favorite architecture is for dynamically-typed at the UI level and statically-typed at the functional level. This also encourages a language barrier that enforces the separation of UI and function.
To be a cynic, it may be simply that dynamic languages allow the developer to be lazier and to get things done knowing less about the fundamentals of computing. Whether this is a good or bad thing is up to the reader 🙂
FWIW, Compiling on most applications shouldn't take hours. I have worked with applications that are between 200-500k lines that take minutes to compile. Certainly not hours.
I prefer compiled languages myself. I feel as though the debugging tools (in my experience, which might not be true for everything) are better and the IDE tools are better.
I like being able to attach my Visual Studio to a running process. Can other IDEs do that? Maybe, but I don't know about them. I have been doing some PHP development work lately and to be honest it isn't all that bad. However, I much prefer C# and the VS IDE. I feel like I work faster and debug problems faster.
So maybe it is more a toolset thing for me than the dynamic/static language issue?
One last comment… if you are developing with a local server saving is faster than compiling, but often times I don't have access to everything on my local machine. Databases and fileshares live elsewhere. It is easier to FTP to the web server and then run my PHP code only to find the error and have to fix and re-ftp.
Productivity in a certain context. But that is just one environment I know, compared to some others I know or have seen used.
Smalltalk on Squeak/Pharo with Seaside is a much more effective and efficient web platform than ASP.Net(/MVC), RoR or Wicket, for complex applications. Until you need to interface with something that has libraries in one of those but not smalltalk.
Misspelled variable names are red in the IDE, IntelliSense works but is not as specific. Run-time errors on webpages are not an issue but a feature, one click to bring up the debugger, one click to my IDE, fix the bug in the debugger, save, continue. For simple bugs, the round-trip time for this cycle is less than 20 seconds.
Dynamic Languages Strike Back
http://www.youtube.com/watch?v=tz-Bb-D6teE
A talk discussing Dynamic Languages, what some of the positives are, and how many of the negatives aren't really true.
Because I consider stupid having to declare the type of the box. The type stays with the entity, not with the container. Static typing had a sense when the type of the box had a direct consequence on how the bits in memory were interpreted.
If you take a look at the design patterns in the GoF, you will realize that a good part of them are there just to fight with the static nature of the language, and they have no reason whatsoever to exist in a dynamic language.
Also, I'm tired of having to write stuff like MyFancyObjectInterface f = new MyFancyObject(). DRY principle anyone ?
Put yourself in the place of a brand new programmer selecting a language to start out with, who doesn't care about dynamic versus staic versus lambdas versus this versus that etc.; which language would YOU choose?
C#
using System; class MyProgram { public static void Main(string[] args) { foreach (string s in args) { Console.WriteLine(s); } } }
LUA:
function printStuff(args) for key,value in pairs(args) do print value .. " " end end strings = { "hello", "world", "from lua" } printStuff(strings)
This all comes down to partially what's appropriate for the particular goals and what's a common personal preference. (EG Is this going to be a huge code base maintained by more people than can conduct a reasonable meeting together? You want type checking.)
The personal part is about trading off some checks and other steps for development and testing speed (while likely giving up some cpu performance). There's some people for which this is liberating and a performance boost, and there's some for which this is quite the opposite, and yes it does sort of depend on the particular flavor of your language too. I mean no one here is saying Java rocks for speedy, terse development, or that PHP is a solid language where you'll rarely make a hard to spot typo.
I have love for both static and dynamic languages. Every project that I've been involved in since about 2002 has been a C/C++ application with an embedded Python interpret. This gives me the best of both worlds:
- The components and frameworks that make up the application are, for a given release of an application, immutable. They must also be very stable, and hence, well tested. A Statically typed language is the right choice for building these parts.
- The wiring up of components, loading of component DLLs, artwork, most of the GUI, etc… can vary greatly (say, to customise the application for a client) with no need to change any framework or components code. A dynamic language is perfect for this.
I find that the mix of a statically typed language to build the system and a dynamically type language to configure it gives me flexibility, stability and productivity.
To answer the question of "What's with the love of dynamic languages?" For me it's the ability to completely re-wire a system at runtime in any way imaginable. I see the scripting language as "running the show", therefore the executing application may do anything you desire.
I don't have much experience with dynamic languages in general, but the one dynamic language I do know, JavaScript(aka ECMAScript), I absolutely love.
Well, wait, what's the discussion here? Dynamic compilation? Or dynamic typing? JavaScript covers both bases so I guess I'll talk about both:
Dynamic compilation :
To begin, dynamic languages are compiled, the compilation is simply put off until later. And Java and .NET really are compiled twice. Once to their respective intermediate languages, and again, dynamically, to machine code.
But when compilation is put off you can see results faster. That's one advantage. I do enjoy simply saving the file and seeing my program in action fairly quick.
Another advantage is that you can write and compile code at runtime . Whether this is possible in statically compiled code, I don't know. I imagine it must be, since whatever compiles JavaScript is ultimately machine code and statically compiled. But in a dynamic language this is a trivial thing to do. Code can write and run itself. (And I'm pretty sure .NET can do this, but the CIL that .NET compiles to is dynamically compiled on the fly anyways, and it's not so trivial in C#)
Dynamic typing :
I think dynamic typing is more expressive than static typing. Note that I'm using the term expressive informally to say that dynamic typing can say more with less. Here's some JavaScript code:
var Person = {};
Do you know what Person is now? It's a generic dictionary. I can do this:
Person["First_Name"] = "John"; Person["Last_Name"] = "Smith";
But it's also an object. I could refer to any of those "keys" like this:
Person.First_Name
And add any methods I deem necessary:
Person.changeFirstName = function(newName) { this.First_Name = newName; };
Sure, there might be problems if newName isn't a string. It won't be caught right away, if ever, but you can check yourself. It's a matter of trading expressive power and flexibility for safety. I don't mind adding code to check types, etc, myself, and I've yet to run into a type bug that gave me much grief (and I know that isn't saying much. It could be a matter of time 🙂 ). I very much enjoy, however, that ability to adapt on the fly.
Nice blog post on the same topic: Python Makes Me Nervous
Method signatures are virtually useless in Python. In Java, static typing makes the method signature into a recipe: it's all the shit you need to make this method work. Not so in Python. Here, a method signature will only tell you one thing: how many arguments you need to make it work. Sometimes, it won't even do that, if you start fucking around with **kwargs.
Because it's fun fun fun. It's fun to not worry about memory allocation, for one. It's fun not waiting for compilation. etc etc etc
Weakly typed languages allow flexibility in how you manage your data.
I used VHDL last spring for several classes, and I like their method of representing bits/bytes, and how the compiler catches errors if you try to assign a 6-bit bus to a 9-bit bus. I tried to recreate it in C++, and I'm having a fair struggle to neatly get the typing to work smoothly with existing types. Steve Yegge does a very nice job of describing the issues involved with strong type systems, I think.
Regarding verbosity: I find Java and C# to be quite verbose in the large(let's not cherry-pick small algorithms to "prove" a point). And, yes, I've written in both. C++ struggles in the same area as well; VHDL succumbs here.
Parsimony appears to be a virtue of the dynamic languages in general(I present Perl and F# as examples).