(Replying to PARENT post)

For a contrary perspective, see my blog-post "We can’t afford to write safe software" (http://reprog.wordpress.com/2010/06/05/we-cant-afford-to-wri...) in which I make the rather obvious point that all the scaffolding you have to erect in statically typed languages is itself a cost, and that ignoring that is misleading. ("You have to fill in a form in triplicate before you can throw an exception", as one of our poets has written.)

Please note (if you can't be bothered to read the actual post before responding), I am _not_ saying that static typing has no value. I'm saying it has both a value _and_ a cost, and too many arguments seem to consider only one of these.

πŸ‘€MikeTaylorπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

The core of the argument is that the features of static code bases are something you need anyway when programming in the large, and I basically agree with that.

I'm not totally convinced, though. Take the simple case of "tell me what range of values to expect here". Java / C++ deal with this with their types, and you can be reasonably confident that you're getting the object you expect. As I'm sure somebody will mention, those types are a bit weak, and can't guarantee the object you get is exactly what you expect. What if you don't test with the right sub-class? What if it's an int, but it's out of the range you expect?

"No, that's not what types guarantee!" you may say. And it's true.

I think one of the problems is that language features aren't perfect. Forcing everybody to admit they're dealing with integers is more desirable than no contract at all, but would it be better if you dealt with Scores, which where integers in the range of 0-100?

In a big enough codebase, the language is never powerful enough to handle all your checking for you, so you need some level of discipline. I worry that by having something "good enough" when your code base is moderate, it allows teams to slip by into "large" without ever considering what their tools, conventions, and limitations should be.

πŸ‘€trjordanπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Unfortunately, everyone uses statically-typed languages wrong, so they get about the same protection with their compiler that you get with Ruby or Perl or Python.

Consider this common mistake:

   interface Greet {
       void sayHello(String firstName, String lastName)
   }

   class PrintGreeter implements Greet {
       public void sayHello(String lastName, String firstName) {
           ...
       }
   }
Where's your compiler NOW?
πŸ‘€jrockwayπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

I have a pretty different experience here.. we have 30+ million lines of JS in production (2k+ devs and tens of thousands of files -- it isn't as scary as it sounds). Prior to converting app development to JS in 2005, development was mostly done in C/C++ and the boost in productivity by writing things in JS has been clear as day. This isn't to say that it is easy to maintain; in our case, a core infrastructure team maintains the guts reasonably well (+dev/test tools) and it allows higher-level teams to build the product. The best feature of the script when it comes to higher-level product is that large portions (if not the entire thing) can be scrapped and started anew in a different way without a significant loss of investment. I suppose a distinction could be made between referring to a single large product/codebase versus a much larger amount of physical code but split between many teams/products. There are probably only a handful of apps that wind up being "large" (in the 10k+ LoC range).
πŸ‘€apaprockiπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Maybe 100K LOC in a dynamic language is more difficult to maintain than 100K LOC in a statically typed language, but what if the same functionality requires 500K LOC in the statically typed language? It is easier to maintain a small code base, other things being equal.
πŸ‘€BeliavskyπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Often times I find large static code bases to be lacking tests. When you have type safety, the tendency is to test less, and in many organizations, forgo testing entirely. A dynamic language will force you to write tests a lot sooner, before the whole codebase turns into a bad game of jenga. In my experience, testing seems to be a lot easier in a dynamic language as well.

I would say that the most stable codebase would be a static one with lots of tests, but I would also guess that this would be the slowest to develop, and would be the most difficult to implement in a real world team of developers.

I know most of us would balk at a huge codebase with zero tests, but it happens all the time. I would definitely prefer a dynamic code base in which I could get my team to write decent tests, but give up type safety, than to have type safety at the cost of decent tests.

πŸ‘€morganherlockerπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Given the lack of evidence to support the claim I find the argument specious. There are large code bases written in dynamic languages that are well maintained by thousands of contributors that could weaken such a claim without strong data backing it up (OpenStack comes to mind). The author fails to provide a link to a single study and relies purely on intuition for eir argument.

I only see one link to that answer on SO that points to a single study. It was provided by another commentator asking for the OP to provide evidence for the "strong correlation," claim. Not very good.

Though I'd hate to work with a team that used a statically typed language and tools that didn't write tests for their software. It's not magic soya-sauce that frees you from ever introducing bugs into your software. Most static analyzers I've seen for C-like languages involve computing the fixed-point from a graph (ie: looking for convergence). Generics makes things a little trickier. Tests are as much about specification as they are about correctness.

In my experience there are some things you will only ever know at run-time and the trade-off in flexibility for static analysis is not very beneficial in most cases.

Some interesting areas in program analysis are, imho, the intersection of logic programming, decomposition methods and constraint programming as applied to whole-program analysis. Projects like kibit in Clojure-land are neat and it would be cool to see them applied more generally to other problems such as, "correctness," and the like.

πŸ‘€agentultraπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

From the link:

"Rather it is also everything else [correctness facilities besides static typing] that is frequently missing from a dynamic language that increases costs in a large codebase. Dynamic languages which also include facilities for good testing, for modularization, reuse, encapsulation, and so on, can indeed decrease costs when programming in the large, but many frequently-used dynamic languages do not have these facilities built in. Someone has to build them, and that adds cost."

...I think that's a little generous to statically typed languages. C and C++, both heavy-hitters in the static language world, have anemic modularization, reuse, encapsulation, mocking frameworks, etc.

πŸ‘€humanrebarπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Why needs this to be discussed again and again? It is such an obvious thing. Use a statically typed language and you get a proof that your program does not contain bugs of a certain class for free. Use a dynamically typed language and you lose this proof or you have to do it on your own. Does this proof come with price tag attached? Yes, but a very small one - sometimes type inference fails and you are forced to manually specify the type. I don't see why this is worth any discussion.
πŸ‘€danbrucπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Static and dynamic are nearly orthogonal to strong and weak typing.

A language with strong typing facilitates communication about the intent of code as well as its function. Strong typing is easier to build into a static compilation phase, but this is not an absolute requirement.

Granted, three of the four quadrants are well covered. Dynamic, strongly-typed languages will take a speed hit unless designed by a wizard.

πŸ‘€samatmanπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

This aligns well with my experience. Maintaining even medium-sized projects in Python, Javascript and PHP has been a very frustrating experience. In practice, nobody ever writes detailed comments or tests (well, not tests that test for type errors anyway. If you're lucky, you'll inherit something that tests the basic functionality of the system and that's about it.), and types are sometimes about the only thing that can help you navigate through the code. Just being able to see what types of arguments a function receives and what it can do with them has saved me tons of time.
πŸ‘€10098πŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

In my experience this all comes down to proper decomposition of services. Don't have large codebases. Break it down into individual services, libraries, etc. Version your APIs. Use proper semantic versioning in your libraries. Most of the trouble I've found has been in changing code that is coupled to a lot of other code. That sucks in every language. It's worse in dynamic languages only because detection is harder and tooling is weaker.

Sounds great on paper, I know, and is much harder in practice. But if done correctly then dynamic languages are awesome boosts to productivity.

πŸ‘€phamiltonπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

I maintain a large set of codebases right now, and the most easy to maintain is certainly the components written in a dynamic language (Lua). Its so darned pleasant to return to that module, after dire straits suffered in Java- and C#- realms, that I'm seriously considering just moving everything to Lua, from here onwards.

So I don't know if I have an answer to this question -but certainly it appears, to me, that the more dynamic the language is - the easier it is to maintain .. certainly the mere fact of lighter tooling means this is true?

πŸ‘€fit2ruleπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

So after reading through the comments, a lot of devs apparently do not make the distinction between static typing and Java.
πŸ‘€kenster07πŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Do we have actual studies about this? Does it take into account the cost of initial development? The cost of fixing bugs? The maintainability and the learning curve?
πŸ‘€VeejayRampayπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Talk about begging the question. It would be far more interesting to talk about the characteristics which make large codebases easier or harder to work with and how to encourage those practices in different environments.
πŸ‘€acdhaπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

# randomly placed in an initialization file

   Object.class_eval do

     def to_s

        "a"

     end

   end
# in some other context perhaps a controller action...

   def lookup_user
   
     user = User.find_by_name(params[:name].to_s)
   
     if user.blank?
   
       flash[:error] = "No user found by that name"
   
       redirect_to "/users"
   
       return
   
     end

     # good stuff goes here

   end
# # try debugging it... it's tricky... use grep? #

the thing is this is actually not too bad... in C++ try debugging a memory leak...

(formatting...)

πŸ‘€taf2πŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Static typing is a blanket of testing that covers the entire project. Likely not thick enough to be sufficiently warm, but still a better base layer than a patchy sprinkling of straw.
πŸ‘€frou_dhπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

I guess we should just understand what's the goal of scripting versus what's the goal of statically typed languages.

Statically typed languages should just provides code that need to be reused often. Also needed when you need performance or low power consumption.

Scripting should be about using those libraries together.

People should try to understand how gmail works, because I think javascript is just used for presenting data to a browser, while gmail servers do the heavilifting.

πŸ‘€jokoonπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Its difficult to maintain large codebases period.
πŸ‘€justinzollarsπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

> So for that reason alone, dynamically typed languages make it harder to maintain a large codebase, because the work that is done by the compiler "for free" is now work that you must do in the form of writing test suites.

Static types are not enough to ensure that your algorithm receives correct input, to ensure you that you will need to write tests anyway. So with static languages you get one check "for free" out of the many that you will have to write yourself.

If you rigorously write tests for a JavaScript code as you would have for a Java code, it becomes just as reliable.

πŸ‘€voidrπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Why, that's simply an indication that you haven't chosen the right tool for the job! Remember, using the right tool for the job is paramount. That's why every blog post on HN about libraries/frameworks/languages ultimately boils down to "use the best tool for the job". So if dynamic languages are making it harder to maintain your code, that means you chose wrong, tool-wise and/or job-wise.

Remember, great software can be made with any programming language! This is why all your favorite apps are written in Visual Basic. Hope this helps!

πŸ‘€badman_tingπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

I'm curious what the experience is of maintaining larger codebases in functional languages.

I ask this because it seems like a lot of "big code" issues stem from poor development practices polluting the codebase over a long period of time, destroying any sort of design that once existed.

Does it help if the language takes a hardline stance against mutable state and side effects? I'm certain you can screw those up, but it's confined to a single place.

πŸ‘€mattgreenrocksπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Maybe the kind of people who like standards and practices tend to shy away from dynamic languages. Maybe C coders are just more likely to be Style Guide people.

Maybe the idea that you can avoid side effects is a fiction that the horror of manual memory management cures you of.

πŸ‘€erikpukinskisπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

TL;DR - most dynamic languages allow most things to change at any time. So with a large codebase, it's hard to know where a particular something is getting changed (or not). IOTW, it makes error traceability of the codebase more difficult.
πŸ‘€midas007πŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Code base is incorrect metric. (Good) Dynamic languages enable smaller code bases.

And you really, really should try harder to make small isolated components (services, daemons, sites, commands, whatever) and avoid large codebases.

πŸ‘€njharmanπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Managing large codebase is nothing to do with typed property. Untyped languages just give you more freedom (see lambda calculus) but you can shoot yourself if you are not ready to use it.
πŸ‘€hurturkπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

πŸ‘€msaneπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Wow, what disinformation. My background in static like Java has been that moving to dynamic makes it easier to do large.
πŸ‘€puppetmaster3πŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

This question is begged.
πŸ‘€SixSigmaπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

In my own experience, the problem has been dedugging.
πŸ‘€adrianlmmπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Really? I don't think so.
πŸ‘€c2uπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Wow, that author has not been keeping up with changes in the JavaScript scene.
πŸ‘€hawleyalπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0

(Replying to PARENT post)

Static and dynamic typing tend to fall down in different ways at Big Code. Dynamic typing can make some kinds of versioning hell in distributed systems less of a problem (which is why languages designed for distribution, like Erlang) tend to be dynamic, and compile speed can be a massive PITA in a language with a static type system worth using (like Scala).

If you're using Java or C++ or mainstream OOP, you're not getting the benefits out of static typing anyway and a Python or Clojure is a big improvement. That said, there are domains where compile-time static typing is extremely useful (and justifies the associated costs due to, e.g., the loss of a Lisp's intuitive macro system and first-class REPL) but those are going to call for a Hindley-Milner type system, not Java's weird mess of one.

πŸ‘€michaelochurchπŸ•‘11yπŸ”Ό0πŸ—¨οΈ0