views:

809

answers:

7

What do you lose in practice when you choose a statically-typed language such as Scala (or F#, Haskell, C#) instead of dynamically-typed ones like Ruby, Python, Clojure, Groovy (which has macros or runtime metaprogramming capabilities)? Please consider best statically-typed languages and best (in your opinion) dynamically-typed languages, not the worst ones.

Answers Summary:

Key advantages of dynamic languages like Ruby over statically-typed language like Scala IMHO are:

  • Quick edit-run cycle (does JavaRebel reduces the gap?)
  • Currently community of Scala/Lift is much smaller then of Ruby/Rails or Python/Django
  • Possible to modify type definitions (though motivation or need for that is not very clear)
+3  A: 
  1. Dynamic languages tend to have much more flexible type systems. For example, Python lets you inject a new method into an existing classes, or even into a single object.
  2. Many (not all) static languages lack the facility to construct complex literals. For instance, languages like C# and Java cannot easily mimic the following JavaScript { 'request':{'type':'GET', 'path':mypath}, 'oncomplete':function(response) { alert(response.result) } }.
  3. Dynamic languages have very fluid semantics. Python allows import statements, function definitions and class definitions to appear inside functions and if statements.
  4. eval is a staple of most dynamic languages and few static languages.
  5. Higher order programming is easier (in my subjective opinion) in dynamic languages than static languages, due to the awkwardness of having to fully specify the types of function parameters.
    • This is particulary so with recursive HOP constructs where the type system can really get in the way.
  6. Dynamic language users don't have to deal with covariance and contravariance.
  7. Generic programming comes practically free in dynamic languages.
Marcelo Cantos
I don't think I've ever dealt with covariance and contravariance in Haskell. Nor do I specify types of function parameters. 2,5,6 and 7 are advantages of dynamic languages over *wimpy* static languages. Many static languages provide those features.
Nathan Sanders
I second Nathan's comment. #3 is just as true in Scala as in Python.
Seth Tisue
1. Marcelo, I wonder why do you necessary need to add methods to a class? What are the advatages over declaring the class members explicitely? Also I know there few tricks in statically-typed langauges that allow to fix them to some extends in that respect. E.g. you can add several members by one expression to a Scala class: class MyClass extends SomeMetaprogrammingStuff { val (myGetter, mySetter) = DeclareGetterAndSetter }. Also you can use Scala traits (aka mix-ins), Scala implicit conversions or extension methods in C#, or plainly use global functions :) . What is missing in this list?
Alexey
2. Marcelo, you can do something like this in Scala: import scala.collection.{Map => %} %('request -> %('type -> "GET", 'path -> mypath), 'oncomplete -> {response: Response => alert(response.result)}). I think it's more or less equivalent to your JS example except that you need to do some trivial manipulations with imports (once per source file).
Alexey
Marcelo, do you actually know Scala, which the question asked about? Only (1) and (4) are even mostly true there; (6) and (7) can be argued either way ("I like it to be easy" vs. "far too easy to shoot yourself in the foot at runtime"). (2) and (3) are more true for Scala than most dynamic languages!
Rex Kerr
These are good reasons to like dynamically typed languages, but Alexey said "_Please consider best statically-typed languages_". IMHO, that means Haskell, Scala and C#. I do not think it is useful to discuss advantages that simply do not apply against these, and it is certainly out of the scope of the question.
Daniel
@Daniel: To be fair: i added the phrase to the question after Marcelo had answered.
Alexey
Thanks all for the comments. I'll make just a handful of observations. 1) The question was not just about Scala, but about static languages in general; 2) I agree that not all static languages have the same characteristics (I was generalising somewhat, which is impossible to avoid with such a question); 3) I wasn't trying to argue in favour of dynamic languages -- the question was what do you lose with static languages, not what is bad about them (for instance, I'm not saying that method injection is a good thing, just that it's something you typically don't get in static languages).
Marcelo Cantos
+4  A: 

The choice of which static or dynamic language is more significant than the static/dynamic choice itself. Some dynamic languages have good performance and good tools. Some static languages can be concise, expressive, and incremental. Some languages have few of these qualities, but do have large libraries of proven code.

p-lo
Sorry, you "meta-statement" does not contribute a lot the answering the question. The subject is the specific advatages you gain loose switching between dynamic language of your choice and Scala (or C#, Ocaml, Haskell, D, F#).
Alexey
perhaps this is because the question is broken not his answer.
jk
+7  A: 

In principle, you give up being able to ignore what type you're using when it is not clear (in the static context) what the right thing to do is, and that's about it.

Since complex type-checking can be rather time-consuming, you also probably are forced to give up fast on-line metaprogramming.

In practice, with Scala, you give up very little else--and nothing that I particularly care about. You can't inject new methods, but you can compile and run new code. You do have to specify types in function arguments (and the return type with recursive functions), which is slightly annoying if you never make type errors yourself. Since it compiles each command, the Scala REPL isn't as snappy as e.g. the Python shell. And since it uses Java reflection mechanisms, you don't have quite the ease of online inspection that you do with e.g. Python (not without building your own inspection library, anyway).

Rex Kerr
Rex Kerr, could you eleborate a bit what you meant: "Since complex type-checking can be rather time-consuming, you also probably are forced to give up fast on-line metaprogramming." I completely didn't undestand the phrase.
Alexey
@Alexey He means the code compiles more slowly.
Daniel
@Alexey What Daniel said. The "metaprogramming" comes from this scenario: you have code that writes code and then wishes to execute it immediately. The less your compiler has to check, the faster that code will start running (and the more frequently it's feasible to modify it).
Rex Kerr
Another point is that you can spend more doing "type debugging," which has only a runtime analogue in dynamic languages. The advantage to the static approach is that you guarantee type safety for all executions, while the advantage of the dynamic approach is that it may* be easier to understand the reasons for particular type errors. *this point is contentious, however.
lindydonna
+3  A: 

I'm not sure if you lose anything but simplicity. Static type systems are an additional burden to learn.

I suppose you usually also lose eval, but I never use it, even in dynamic languages.

I find the issue is much more about everything else when it comes to choosing which language to use for a given task. Tooling, culture, libraries are all much more interesting than typing when it comes to solving a problem with a language.

Programming language research, on the other hand, is completely different. :)

wolverian
CS 101 - any Turing complete language is capable of expressing eval.
James Iry
+1  A: 

Some criticism of Scala has been expressed by Steve Yegge here and here, and by Guido van Rossum, who mainly attacked Scala's type system complexity. They clearly aren't "Scala programmers" though. On the other hand, here's some praise from James Strachan.

Yardena
A: 

In my opinion, the difference between the static and dynamic typing comes down to the style of coding. Although there is structural types in Scala, most of the time the programmer is thinking in terms of the type of the object including cool gadgets like trait. On the other hand, I think Python/Javascript/Ruby programmers think in terms of prototype of the object (list of methods and properties), which is slightly different from types.

For example, suppose there's a family of classes called Vehicle whose subclasses include Plane, Train, and Automobile; and another family of classes called Animal whose subclasses include Cat, Dog, and Horse. A Scala programmer would probably create a trait called Transportation or something which has

def ride: SomeResult
def ride(rider: Someone): SomeResult

as a member, so she can handle both Train and Horse as a means of transportation. A Python programmer would just pass the train object without additional code. At the run time the language figures out that the object supports ride.

The fact that the method invocations are resolved at the runtime allows languages like Python and Ruby to have libraries that redefines the meaning of properties or methods. A good example of that is O/R mapping or XML data binding, in which undefined property name is interpreted to be the field name in a table/XML type. I think this is what people mean by "flexibility."

In my very limited experience of using dynamic languages, I think it's faster coding in them as long as you don't make mistakes. And probably as you or your coworkers get good at coding in dynamic language, they would make less mistakes or start writing more unit tests (good luck). In my limited experience, it took me very long to find simple errors in dynamic languages that Scala can catch in a second. Also having all types at compile time makes refactoring easier.

eed3si9n
+1  A: 

My 2 cents...

IMO (strong) statically-typed languages might reduce the amount of necessary testing code, because some of that work will be done by the compiler. On the other hand, if the compiling step is relatively long, it makes it more difficult to do "incremental-style" programming, which in the real life might result in error-prone code that was only tested to pass the compiler.

On the other hand, dynamically-typed languages feel like there is less threshold to change things, that might reduce the responding time from the point of bug-fixing and improvement, and as a result might provide a smoother curve during application development: handling constant flow of small changes is easier/less risky than handling changes which are coming in bug chunks.

For example, for the project where the design is very unclear and is supposed to change often, it might have been easier to use dynamic language than a static one, if it helps reduce interdependencies between different parts. (I don't insist on that one though:) )

I think Scala sits somewhere in between (e.g. you don't have to explicitly specify types of the variables, which might ease up code maintenance in comparison with e.g. C++, but if you end up with the wrong assumption about types, the compiler will remind about it, unlike in PHP where you can write whatever and if you don't have good tests covering the functionality, you are doomed to find it out when everything is live and bleeding). Might be terribly wrong of course :)

Ashalynd