Uses for Dynamic Languages

2019-02-09 08:47发布

问题:

My primary language right now is D, and I'm in the process of learning Python because it's required for a course I'm taking. While I understand why dynamic languages would be a breath of fresh air for people programming in static languages without type inference or templates (IMHO templates are to a large extent compile-time duck typing), I'm curious what the benefits are of dynamic languages even when you have those.

The bottom line is that, if I'm going to learn Python, I want to learn it in a way that really changes my thinking about programming, rather than just writing D in Python. I have not used dynamic languages since I was a fairly novice programmer and unable to appreciate the flexibility they supposedly offer, and want to learn to take full advantage of them now. What can be done easily/elegantly in a dynamically typed, interpreted language that's awkward or impossible in a static language, even with templates, polymorphism, static type inference, and maybe runtime reflection?

回答1:

In theory, there's nothing that dynamic languages can do and static languages can't. Smart people put a lot of work into making very good dynamic languages, leading to a perception at the moment that dynamic languages are ahead while static ones need to catch up.

In time, this will swing the other way. Already various static languages have:

  • Generics, which make static types less stupid by letting it select the right type when objects are passed around, saving the programmer from having to cast it themselves

  • Type inference, which saves having to waste time on writing the stuff that should be obvious

  • Closures, which among many other things help to separate mechanism from intention, letting you pull together complicated algorithms from mostly existing ingredients.

  • Implicit conversions, which lets you simulate "monkey patching" without the risks it usually involves.

  • Code loading and easy programmatic access to the compiler, so users and third parties can script your program. Use with caution!

  • Syntaxes that are more conducive to the creation of Domain Specific Languages within them.

...and no doubt more to come. The dynamic movement has spawned some interesting developments in static language design, and we all benefit from the competition. I only hope more of these features make it to the mainstream.

There's one place where I don't see the dominant dynamic language being replaced, and that's Javascript in the browser. There's just too much of an existing market to replace, so the emphasis seems to be towards making Javascript itself better instead.



回答2:

Here's Steve Yegge on the subject.

Guido van Rossum also linked to that talk in his take of Scala.



回答3:

"I'm curious what the benefits are of dynamic languages even when you have those."

Compared to D programming language:

  • Python is a more compact language. It allows you to express as much as D but it uses many fewer different concepts to achieve it -- less is more.

  • Python has a powerful standard library -- batteries included.

I don't know whether D has interactive prompts but in Python an interactive shell such as ipython is an integrated part of development process.



回答4:

Example in 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!'

How long do you think this took me to write, and how many compile-run-debug cycles?

If you think my example is trivial, I can reply by saying that dynamic languages make trivial many programming tasks.



回答5:

In dynamic languages you can use values in ways that you know are correct. In a statically typed language you can only use values in ways the compiler knows are correct. You need all of the things you mentioned to regain flexibility that's taken away by the type system (I'm not bashing static type systems, the flexibility is often taken away for good reasons). This is a lot of complexity that you don't have to deal with in a dynamic language if you want to use values in ways the language designer didn't anticipate (for example, putting values of different types in a hash table).

So it's not that you can't do these things in a statically typed language (if you have runtime reflection), it's just more complicated.



回答6:

I actually wrote a blog post on this: linky. But that post basically can be summed up like this:

You'd be surprised at how much of a load off your mind it is to not have to name at compile time what type your variable is. Thus, python tends to be a very productive language.

On the other hand, even with good unit tests, you'd also be surprised at what kinds of stupid mistakes you're allowing yourself to make.



回答7:

One big advantage of dynamic typing when using objects is that you don't need to use class hierarchies anymore when you want several classes to have the same interface - that's more or less what is called duck typing. Bad inheritance is very difficult to fix afterwards - this makes refactoring often harder than it is in a language like python.



回答8:

The point is that in a dynamic language you can implement the same functionality much quicker than in a statically typed one. Therefore the productivity is typically much higher.

Things like templates or polymorphism in principle give you lots of flexibility, but you have to write a large amount of code to make it work. In a dynamic language this flexibility almost comes for free.

So I think you look at the difference in the wrong way, productivity really is the main point here (just like garbage collection improves productivity, but otherwise does not really allow you to do new things).



回答9:

With a dynamic language it's much easier to have a command line interpreter so you can test things on the command line and don't have to worry about a compile step to see if they work.



回答10:

I find dynamic languages like Perl and to a lesser extent Python allow me to write quick and dirty scripts for things I need to do. The run cycle is much shorter in dynamic languages and often less code needs to be written then in a statically typed language which increases my productivity. This unfortunately comes at the cost of maintainability but that is a fault of the way I write programs in dynamic languages not in the languages them selves.



回答11:

I was going to say closures but found this thread... (not that I understand how it would work in a "static" language)

Related concepts are functions-as-first-class-objects and higher-order procedures. (e.g. a function that takes a function as input and/or returns a function as output)

edit: (for the nitpickers here) I'll echo a comment I made on @David Locke's post. Dynamically-interpreted languages make it possible to use an existing software program/project in conjunction with a small function or class created at the spur-of-the-moment to explore something interactively. Probably the best example is function graphing. If I wrote a function-graphing object with a graph(f,xmin,xmax) function, I could use it to explore functions like x2 or sin(x) or whatever. I do this in MATLAB all the time; it's interpreted and has anonymous functions (@(x) x^2) that can be constructed at the interpreter prompt to pass into higher-order functions (graphing functions, derivative operators, root finders, etc).



回答12:

Take a look at this e4x example in JavaScript:

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 );
}

Especially, take a look at line:

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

In typical static languages, you don’t get to write sales.item, since you can not know that item is property of sales until runtime. This is not limited to e4x. You get to program in similar style when connecting when writing SOAP clients or any other underlying type you do not know until runtime. In a static language, you would typically need to run a tool that will generate stub classes or program in a very verbose way. Then, if something changes in a web service, you need to regenerate stubs all over again. Take a look at java DOM code:

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;
    }
}

Definitely much more verbose than your dynamic code. And, of course, it is not statically typed. There is no way to check that you misspelled “author” as "autor" until runtime. All this verbosity is essentially there to let you capture something that is dynamic in nature in static style.

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



回答13:

Compiled languages tend to be used when efficiency and type safety are the priorities. Otherwise I can't think of any reason why anyone wouldn't be using ruby :)