1. 34
  1.  

  2. 17

    One thing missing form this is that “static types” is a huge range. Does one mean Go? Java? Ocaml? Agda? Agda and Go are farther apart than Python and Go. The type system Go gives a developer is roughly equivalent to the mental model a Python developer has when writing Python. In that sense, the Python developer was already using static types, Go just lets them write them down. I’m a static type enthusiast, and while I’d rather write Go than Python, it’s not by much. I’d much rather write Ocaml.

    From a type theoretic point, you can always encode a dynamically typed language in a statically typed language. From that perspective, static types have always been winning, language authors have just chosen to not finish implementing their type system. And the nimblness that a dynamic language is giving someone is disappearing. Haskell has type holes, so you can write your program and run it for the cases that you had it make sense and then let the compiler help you finish it.

    For myself, I’ve replaced most places that I would use something like Python with awk and shell scripts. Anything else my goto is Ocaml. At work, I generally have to use something like Python or Java, but not for any particulaly good technical reason, just some politician in engineering won that argument that day and those are the tools we can use.

    1. 2

      Why shell scripts and awk over Python?

      1. 5

        The only usecase I have which i don’t use Ocaml for is quick text munging tooling. awk and various other shell tools a power and, generally, more performant than doing it in Python.

    2. 18

      More than interesting: it’s reasoned.

      1. 5

        I was waiting for the part with at least a few theory/research backed advantages of dynamic languages, but he skimmed over it with suggesting they are fast, easy to learn or expressive. Otherwise only has solid arguments about the positive points of statically typed languages. I think this says it all.

        This discussion needs to be slotted into the landscape of the broader question of software as a craft and with a public burden - encouraging ‘speed’ or ‘ease of use’ at the expense of rigour, safety, security needs to be a decision, not an accident.

        1. 3

          *she

        2. 4

          I was a bit puzzled by the categorization of Ruby and Python as badly designed languages; Although I’m not personally a fan of either, I was under the impression that they were generally well-regarded. Was I mistaken?

          1. 8

            It’s a matter of opinion, of course. They’re obviously practically usable, but then so is PHP, which I’ve seldom heard of as an example of “well-designed”. :)

            Consider Ruby’s block vs. lambda vs. Proc, or its odd variable scoping rules.

            1. 1

              I thought I knew all the bad parts of Ruby, can you tell me what’s odd about its variable scoping rules?

            2. 10

              As @wrs said, it’s a matter of opinion. Also, for many people it’s difficult to separate something being well done from something being popular (except for PHP and MongoDB, people seem quite comfortable calling it crap regardless of its popularity).

              In total, Python is not a terrible language, IMO. It does fall over in a few key areas which makes it a language I’ll only used if I’m getting paid:

              • It does not distinguish creating a new variable from assigning a new value to an existing variable. Most languages get this correct, with let or explicit scope. Python does not, which makes for a lot of confusion.
              • Scoping in general in Python 2.x is utter bollocks. It is counter intuitive from a user perspective but makes complete sense when you figure out how they implemented it. Scoping is a complete leakage of an implemenation detail to language semantics.
              • Solely indentation based syntax. Many people will regard this as a huge plus for Python, I even did at one point. However, it comes with a clear, objective, and visible cost: it is nearly impossible to implement something new and interesting at a library level. Consider with. In many languages, like C++, Ocaml, and Haskell, with is implemented as part of a greater language abstraction (C++) or can easily be implemented as a library method (Ocaml, Haskell) without it being too painful to use. Because of indentation-based syntax in Python, it must not only become part of the language syntax but it has to be a special, one-off, thing. Lambdas are completely useless in the language and defining a function is too cumbersome to use with a library with function. The effect of this is so visible that Python had to have a language moritorium for several years to give compiler writers a chance to keep up. If these things could be pushed into libraries, this would not be needed.
              1. 13
                • I also started out liking the indentation, and came to despise it. Indentation is just hard for people to reason about: I’ve seen too many colleagues inadvertently move pieces of code outside of their blocks without even realizing it.

                • The second-class lambdas are terrible. The minute you start doing anything with higher-order functions, Python just feels worse than Ruby. (On the other hand, first-class decorators are great.) The BDFL seems to go out of his way to make functional idioms impossible, leading to…

                • …the overuse of list comprehension syntax is nuts. Fine, I get it. It can replace most iteration in most contexts. It’s also a bear to read the minute you get past the simplest toy examples. I’ve seen three-deep list comprehensions, which are about as easy to read as you can imagine, which makes the insistence that the conditional operator (?:) is “hard to read” really bizarre. It’s worth noting that Haskell has more powerful list comprehensions and yet you still use map, filter, and foldr more frequently.

                • It feels verbose. Compared to Ruby or Clojure, writing it is laborious and the code ends up being rather ugly. However, I’d still rather write Python than Ruby (but not Clojure).

                • The “batteries included” approach is wrong, in my opinion. The standard library is too big, and too many dark corners haven’t been cleared of cobwebs in years. There’s no clear indication of this, either, so you end up going and hunting for popular libraries every time you need to do something, to see if there’s a contraindication for the module in the standard library. Even worse, people use the “batteries included” philosophy as a selling point for Python.

                Overall, as @apy says, I will write Python for pay; it’s better than most alternatives.

              2. 7

                Well-designed and poorly designed in this article still read to me as shorthand for ‘designed by laypeople’ or ‘designed by people who are not well versed in type theory’. That said it really does depend heavily on the definition of ‘designed’. Dynamic languages are depicted as languages designed by academic outsiders and as languages with lowbrow mass appeal.

                “Most of the mainstream ones were designed by amateurs, people with no CS background or no adequate background in compiler construction”

                Ruby, Python, JS, and PHP were all designed by people who held CS or equivalent degrees. Where are we setting the bar for a ‘professional’ language designer?

                All of these languages have design flaws, and they have a number of features that a person can dislike, but the criteria are hopelessly subjective.

                Static vs. Dynamic isn’t really even a useful question, is it? Shouldn’t we use languages based on what we value? Don’t we?

                1. 4

                  Well regarded and well desgined are two different things.

                  This is an example of Python’s ‘good design’.

                  1. 2

                    Wow… How can you look at that and go “this is great, we’ll keep doing this”!?

                2. 4

                  I’m probably missing something here, but don’t we already get somewhat comprehensive type inference in a language like Haskell? It seems to do a reasonably decent job at picking the types for you as long as you don’t encounter ambiguity. Maybe Crystal has a more take on that?

                  1. 3

                    Haskell has no subtyping and in a sense much easier to do type inference. If you lift Haskell type inference algorithm and try to apply it to most other languages which have subtyping, it won’t work without modifications.

                    1. 2

                      I accidentally the word “effective”.

                    2. 4

                      I don’t think typed languages are about IDE support; I’d use them even without an IDE. Smalltalk may offer automated refactoring but it inherently can’t offer the safety of a modern typed language and that’s a huge cost.

                      I’d say the rise of typed languages with inferred union typing is the triumph of static over dynamic typing, in the sense of the original article, and in this sense dynamic languages are dead. I think we’ll continue to see a spectrum between permissive languages that permit potentially unsound constructs by default and only outlaw unambiguously wrong code, and strict languages that only allow definitely sound code by default, and that both will ultimately converge. But I think the days of purely unityped languages are over.

                      Equally and conversely, I think with even C++ adding auto, the days of explicitly typed languages with no type inference at all are also over. (In that sense, both static and dynamic languages should count this as a victory). And ultimately I expect the spectrum to narrow further as we get better at type inference.

                      1. 1

                        Maybe the distinctions between static/dynamic are more superficial than the blogosphere perceives them to be. Are there practical limits on the extent to which Hindley-Milner can be applied? Has anyone written about empirical experiences migrating code from a dynamically typed to a compile time typed language? Maybe it’s just not that hard.

                        I wonder what the market would look like for a static analyzer for Rails code.

                        1. 1

                          There used to be LASER, which did static analysis for Ruby, but it appears to have been abandoned. Which is really sad.