如何使用动态语言进行不同的编程?
真正了解如何利用动态编程语言的人与使用静态语言的人相比,如何以不同的方式进行编程?
我熟悉关于静态类型与动态类型的整个争论,但这不是我要表达的内容。 我想讨论在动态语言中实用但在静态语言中不实用的问题解决技术。
我见过的大多数用动态编程语言编写的代码与用静态编程语言编写的代码没有太大区别。 俗话说,你可以用任何语言编写 FORTRAN,而且很多人都这样做。 但有些人使用动态编程语言来解决问题,而这种方式不容易转化为 C++ 等语言。 他们的技术有哪些?
有哪些讨论如何使用动态编程语言的好资源? 不是有关语言语法或 API 参考的书籍,而是有关利用动态语言功能解决问题的方法的资源。
编辑(2009 年 1 月 5 日):我很欣赏下面的答案,但它们似乎没有解释动态语言倡导者所说的生产力的巨大提高。
How would someone who really knows how to take advantage of dynamic programming languages approach programming differently than someone working in a static language?
I'm familiar with the whole debate over static versus dynamic typing, but that's not what I'm getting at. I'd like to discuss problem solving techniques that are practical in dynamic languages but not in static languages.
Most of the code I've seen written in dynamic programming languages isn't very different than code written in static programming languages. As the saying goes, you can write FORTRAN in any language, and many people do. But some people use dynamic programming languages to solve problems in a way that wouldn't easily translate into, for example, C++. What are some of their techniques?
What are some good resources that discuss how to use dynamic programming languages? Not books on language syntax or API reference, but resources on problem solving approaches that take advantage of dynamic language capabilities.
EDIT (1/5/2009): I appreciate the answers below, but they don't seem to account for the huge increases in productivity that dynamic language advocates say they experience.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
我喜欢苗条的回答。 我确实花费了大量时间在 Java 和 C++ 上制作自定义数据结构,而这些数据结构在 Python/Ruby 中是免费的。 并设计专门的函数来处理这些自定义数据结构。 是的,在C++中,STL确实很好。 是的,Java 中的泛型很好。 它们有助于更快地创建自定义数据结构,但是它们仍然需要大量的思考和考虑。
然而,动态语言更容易使用还有一个更根本的原因。 这是一个深刻的想法,称为鸭子类型。 上面的一些评论涉及鸭子类型,但请花点时间思考一下什么是鸭子类型。 这是一种根本不同的看待世界的方式。 与 Java 和 C++ 等语言不兼容的视图。
鸭子类型意味着您不必浪费时间来定义鸭子是什么。 由于不必正式定义对象,因此可以节省大量时间和精力。 获得正确的定义是很困难的。 看看我的这篇博客文章,其中我给出了示例:正式定义没有你想象的那么有用 事实
证明,鸭子类型非常有用。 XML 中的“必须忽略”原则< /a> 使得 XML 在 Web 上如此重要和有用。 但这只是鸭子打字的一个例子。
表达鸭子类型的另一种方式是通过网络口头禅“严格发送,慷慨接受”。 这也是一个非常基本的想法。
最后,您可能想回到我的一篇长篇博客文章,其中我解释了鸭子类型以及它与人工智能和建模等事物的关系:鸭子打字、人工智能和哲学
I like slim's answer. I do spend a crazy amount of time in Java and C++ crafting custom data structures that are just free in Python/Ruby. And crafting specialized functions to process these custom data structures. Yes, in C++, STL is really nice. Yes, Generics in Java are nice. They help create custom data structures much faster, however they still require a lot of thought and consideration.
However, there is a more fundamental reason why dynamic languages are easier to work with. It is a deep idea which is called duck typing. Some comments above refer to duck typing, but please take time to reflect on what duck typing is. It is a fundamentally different way to view the world. A view that is incompatible with languages like Java and C++.
Duck typing means that you waste not time in defining what a duck is. By not having to formally define your objects you save a lot of time and energy. Getting definitions right is hard. Have a look at this blog post of mine where I give examples: Formal definitions are less useful than you think
Duck typing has proven extremely useful. The "Must Ignore" principle in XML is what has made XML so significant and useful on the web. But that's just an instance of duck typing.
Another way to express duck typing is by the Web mantra "Be strict in what you send, generous in what you accept". That is also a very fundamental idea.
Finally, you may want to back to a long blog post of mine where I explain duck typing and how it relates to things like AI and modelling: Duck Typing, Artificial Intelligence and Philosophy
我发现自己利用动态编程语言的一种典型方式是简化和澄清语法。 例如,如果我代表一个数据库,如果我可以在数据库对象上为其表、表及其列的行等动态加载属性和方法,则用于与其交互的语法会更加清晰。 区别可能在于:
和
当您做复杂的事情时,第二种形式的“视觉噪音节省”确实开始增加。
One way I typically find myself taking advantage of dynamic programming languages is in simplifying and clarifying syntax. If I'm representing a database, for example, the syntax I use for interacting with it can be much cleaner if I can dynamically load properties and methods on the database object for its tables, the tables and rows for their columns, and so on. The difference might be between:
and
The 'visual noise savings' of the second form really starts to add up when you're doing complex things.
动态语言可以在运行时更改对象,您可以添加方法、属性...
动态语言魔法的一个很好的例子是这个 Groovy 代码片段,它只需两行代码即可调用 Web 服务上的方法:
这是另一个 Groovy 片段从 XML 中提取数据:
您无法在静态语言中执行此操作。 动态语言可以改变对象以反映实际的运行时条件。
Dynamic Languages can change the object at run time, you can add methods, properties...
One good example of Dynamic Languages magic is this Groovy code snippet which call a method on a webservice in just two lines of code:
This is another Groovy snippet that extract data from XML:
You cannot do this in Static Languages. Dynamic Language can change the objects to reflect the actual runtime condition.
我认为最显着的差异在于数据结构的选择。
在 Java 或 CI 中,结构或类的定义非常严格。 如果我需要添加属性,我会返回并更改定义。
在 Perl 中,我将只使用哈希,并在编码时“发明”键。
I think the most dramatic difference in choice of data structures.
In Java or C I define structs or classes very strictly. If I need to add a property, I go back and change the definition.
In Perl I'll just use a hash, and 'invent' keys as I code.
在动态语言中,我更具实验性。 即时更改更容易,因此我可以更快地探索解决方案。
如果我知道自己想做什么,以及一般如何去做,我就会喜欢 C++。 如果我不知道如何做我想做的事,并且可能不完全确定我想做什么,我更喜欢 Lisp。
In dynamic languages, I'm more experimental. It's easier to change things on the fly, so I can explore solutions faster.
If I know what I want to do, and generally how to do it, I like C++. If I don't know how to do what I want to do, and likely am not entirely sure about what I want to do, I much prefer Lisp.
快速迭代让程序员更快乐,而且它们的速度不会比交互式解释器快。 良好的解释器开发同时为您提供沙箱、测试和原型设计。
但是要小心排列编程。 我个人的经验法则是,仅仅因为它有效并不意味着它已经准备好了,当你可以解释它为什么有效时,它就已经准备好了。
Fast iterations make happier programmers, and they don't come any faster than an interactive interpreter. Good interpreter exploitation gives you sandbox, testing, and prototyping at the same time.
Beware programming by permutation, however. My personal rule of thumb is that it's just because it works doesn't mean it's ready, when you can explain why it works it's ready.
我最大的收获是数据库和对象之间的映射(ORM)。
如果没有类型的概念,那么将行中的每一列分配给对象中的值就变得非常容易。 当然,权衡是您认为存在的值类型与计算机执行的类型之间可能存在不匹配。
My biggest gains are in mapping between databases and objects (ORM).
If there is no concept of a type, it becomes very easy to say assign every column in a row to a value in an object. Of course the trade off is that there can be a mismatch between the type of value you think is there and what type the computer does.
这可以归结为我最喜欢的比率之一:我花多少时间思考解决问题,与我花多少时间思考用于解决问题的工具。 将其视为等同于信噪比。
使用鸭子类型语言(我认为这是最能帮助我提高生产力的因素),我只是能够花更多时间思考我的问题及其解决方案(并编写专门解决这些问题的代码),并且我花保持语言工件正常的时间更少。
还有很多我不写的代码,涉及声明,尤其是类型转换。
但这主要是让我的注意力集中在最佳位置。
It comes down to one of my favorite ratios: How much time I spend thinking about solving a problem, vs. how much time I spend thinking about the tool I'm using to solve the problem. Think of it as equivalent to S/N ratios.
With duck-typing languages (which I consider to be the factor that helps me the most with productivity), I simply am able to spend more time thinking about my problem and its solution (and write code that addresses those specifically), and I spend less time keeping the language artifacts straight.
Then there's a lot of code I just don't write, involving declarations and especially type-casts.
But it's mainly keeping my focus in the sweet spot.
我现在无法引用这一点(我的记忆力衰退了),但我听到了一些类似的内容:
因此,我可能会大胆猜测,并不是说您的编程方式不同,而是您可以将更多的精力投入到“解决问题”而不是解决方案的实现细节上。
I can't cite this right now (my memory is failing me), but I've heard something along the lines of:
So, I might venture a guess and say it's not so much that you program differently, it's that you can devote more of your brain to "solving the problem" rather than the solution's implementation details.
更多的库和更重要的更多可用的库。
我的猜测是,通常与动态语言相关的“鸭子类型”有助于显着简化代码并使编写通用代码变得更加容易。 您不受严格的类层次结构的限制,因此能够更轻松地将来自不同库的组件组合在一起。
More libraries and more important more useable libraries.
My guess is that the "Duck Typing" usually associated with dynamic languages helps simplify the code significantly and makes writing generic code much easier. You are not constrained by a strict class hierarchy and thus are able to more easily compose components from different libraries together.
John,根据您 2009 年 1 月 5 日的更新编辑,您可能会发现 AMOP有趣的阅读,以及您正在考虑的更多内容。 它非常以 lisp 为中心,但毕竟许多好的动态想法都是从那里开始的。 因此,如果您可以享受(或克服)这个方面,作者确实讨论了执行此类操作所需和用于的动态方面。 这是非常强大的东西。
John, just based on your update edit of 1/5/09, you might find AMOP an interesting read, and more on the line you're thinking of. It's pretty lisp-centric, but after all many of the good dynamic ideas started there. So if you can enjoy (or get past) that aspect, the authors do discuss the dynamic aspects needed and used to do something like this. It's pretty powerful stuff.
我没有具体的答案,只是一个建议:看看书“Ruby 中的设计模式”:它回顾了大多数经典的设计模式(à la Gamma 等人,等等)并用 Ruby 非常简洁地表达它们:)
I do not have a specific answer, just a suggestion: have a look at the book "Design patterns in Ruby" : it goes over most of the classic design patterns (à la Gamma et al., and more) and express them, quite succinctly, in Ruby :)
阅读 Mark Jason Dominus 的《Higher Order Perl》。 它只讨论 Perl,但它确实提供了 Perl 自然的技术,而在大多数静态语言中则不太自然。
只是对语言进行分类的多种方法中的一种。 我不会认为动态语言作为一个整体比静态语言更好或更差。 但我确实认为这本书
非常擅长展示使用 Perl 解决问题的不同方法
在大多数静态语言中是困难或不可能的。
Read "Higher Order Perl" by Mark Jason Dominus. It only discusses Perl but it does give techniques that are natural to Perl that would be less natural in most static languages.
is only one of many ways to classify a language. I would not make the argument that dynamic languages as a whole are better or worse then static languages. But I do think this book is
very good at showing different ways of approaching problems using Perl that would be more
difficult or impossible in most Static languages.
动态语言能够执行在运行时创建的代码。 如果注入恶意代码,这是非常危险的。 但如果你能净化环境,那就非常强大了。
我认为 Javascript 人们通过执行 JSON 文件来做到这一点。
Dynamic languages are capable of executing code which was created at run-time. This is very dangerous if malicious code is injected. But very powerful if you can sanitize the environment.
I think Javascript people do this by executing JSON files.
对我来说,这是周转速度。 我使用的动态语言(目前是 Python 和一些 JavaScript)是解释性的。 这意味着我可以即时尝试。 如果我想了解 API 的某个部分的行为方式,我可以花几分钟修改解释器。
如果我想用 C# 这样的语言做同样的事情,我必须启动 VS,创建一个项目,然后编译它。 如果我想测试我正在开发的更大软件的一部分,我可能必须对其进行编译,这可能需要很长时间。 幸运的是,在 .Net 中,我可以从 IronPython 中的大型项目加载程序集,并获得解释语言的一些相同的好处(即快速测试 API 的不同部分)。
For me it's turnaround speed. The dynamic languages I use (Python and a bit of JavaScript at the moment) are interpreted. This means I can try things out on the fly. If I want to see how a certain bit of the API behaves I can just hack away at the interpreter for a couple of minutes.
If I wanted to do the same in a language like C# I'd have to fire up VS, make a project, then compile it. If I want to test a part of a bigger piece of software I'm working on I probably have to compile that, which can take ages. Fortunately in .Net I can load up assemblies from the big project in IronPython and get some of the same benefits (i.e. quickly testing out different parts of the API) of interpreted languages.