Live data from Hacker News

Dynamic type systems are not inherently more open

lexi-lambda.github.io

211–220 of 286 posts

Re: Dynamic type systems are not inherently more open

#211
> We don’t have to respond to an ill-formed value by raising an error! We just have to explicitly ignore it.

The point of the article is basically "dynamic type systems are not inherently more open because we can just ignore type errors in static type languages [which means, of course, that we're making them behave like dynamic languages]"... Well, shoot.

Ultimately, this seems like her previous article was just contributing to that six-decade-old flamewar. Since this is a flamewar, it got comments disagreeing, and now she posted an article disagreeing with the disagreements.

Everything worked as expected and nothing that hasn't been said before (over and over) was said.

Why can't people just be ok with "I like this paradigm and it's ok if you like another"? Sure, the discussion has led to plenty of advances in programming language design, but at this point it's pretty clear that, if it were possible to absolutely prove that one type system is better than another, we would have done so already. Meaning that everything pretty much comes down to opinion.

Re: Dynamic type systems are not inherently more open

#212

Dynamic type systems are inherently more open. This article really bends over in strange ways to say otherwise. Fact is: dynamic typing is all about making fewer claims in your code about what you expect about the world around you. With dynamic types, to load a property you might just have to say the property name and receiver. With static types, you usually also have to say the type of all other properties of the re…

> Static type systems will typically require you to state the full type of o. This is not the case for languages with support for structural typing (as the article mentions in the appendix), and most modern statically typed languages have some degree of support for abstract interfaces of some sort which also support writing functions with only partially known information about the type. I think one of the core insigh…

The difference between static and dynamic typing isn't about how explicit you are about the assumptions in your code. You can be equivalently explicit in dynamic and static languages. The fundamental difference lies in when you want the types to be verified. In static typing, that is before the program is run. In dynamic typing, that is before the code is executed if you are explicit, or when the code is executed if you are not explicit enough.

An example of dynamic typing being used pervasively in what we commonly call statically typed languages is the downcast. (SubType)superTypeObject is a dynamic typing construct. It is saying "defer unification of these types until runtime," because there is insufficient information at compilation type to determine the real type of superTypeObject.

Of course, such downcasts are discouraged in statically typed languages without explicitly checking the type of superTypeObject before performing the downcast, but not all type systems are capable of asserting these checks are all in place at compile time. Some statically typed languages don't even have a downcast.

You can be completely explicit about checking types before using them in a dynamically typed language, and have the proper error handling in place in the case that the type unification you're expecting doesn't happen.

Re: Dynamic type systems are not inherently more open

#214

I have developed and maintained several large systems in both dynamic and statically typed languages. From a maintenance point of view, the statically typed ones definitely win out. Trying to reason about bits of code with no idea what was supposed to be passed in. Working out which bits of code are actually dead and can be safely removed. Refactoring bits of code. All incredibly difficult in the dynamically typed sy…

There are two aspects to maintenance. One is in maintaining a codebase, which is what you're referring to. This greatly benefits from static typing as you can have good guarantees about your code before you deploy it.

The other aspect of maintenance is in keeping a running system up without any downtime. There are plenty of of use cases where recompiling code and relaunching an application is not a viable solution. You need to be able to patch a running system. Dynamic typing is beneficial here because you need the old running code to be able to call into the new code which it knew nothing about when it was originally compiled.

Re: Dynamic type systems are not inherently more open

#215
post #82

This is so predictable. 1. Author attacks premise of dynamic type systems argument. 2. Author presents premise for static type system (which is practically confluent/equivalent/equifinal to premise he just undermined). >static type systems allow specifying exactly how much a component needs to know about the structure of its inputs, and conversely, how much it doesn’t. Indeed, in practice static type systems excel at…

Please don't post in the flamewar style to HN. We're trying for something very different here.

https://news.ycombinator.com/newsguidelines.html

Re: Dynamic type systems are not inherently more open

#216
post #82

This is so predictable. 1. Author attacks premise of dynamic type systems argument. 2. Author presents premise for static type system (which is practically confluent/equivalent/equifinal to premise he just undermined). >static type systems allow specifying exactly how much a component needs to know about the structure of its inputs, and conversely, how much it doesn’t. Indeed, in practice static type systems excel at…

This is so predictable. 1. HN commenter misses the point of the article. 2. HN commenter even misgenders the article's author.

Please don't reply to a bad comment with a worse one. That only poisons the thread further, and the site guidelines explicitly ask you not to do it.

https://news.ycombinator.com/newsguidelines.html

Re: Dynamic type systems are not inherently more open

#217
I wrote the pickle.load comment [1]. I want to defend it here.

King (the author) places "dynamically typed" and "statically typed" in opposition. But keep in mind that many languages have both: Java, ObjC, TypeScript, C#, etc. I like to say that a a language "has" static and/or dynamic types, but "is" dynamic if it supports runtime features like reflection - of course this is a sliding scale.

King observes that static types allow you to make explicit what you know. After calling `pickle.load` you don't know anything about the result, so its static type is going to be something quite constraining like `String -> Object`. It seems we are in violent agreement on this point.

King then goes on to make a different claim: that it is possible to implement `pickle.load` in Java and also in Haskell. It is possible in Java but not in Haskell.

Here's the key line for Java:

However, nothing is stopping you from passing Serializable.class and branching on the type later

Notice the subtle shift in meaning for "type": from static type to runtime tag. It is possible to branch on the type at runtime, because the type is available at runtime, because Java has dynamic types. They're awkward and painful to use, but it is possible.

For Haskell:

Can we do this in Haskell, too? Absolutely—we can use the serialise library, which has a similar API to the Java one mentioned above.

Absolutely you cannot! The Serialise libary requires you to list all of the possible result types up-front, "by providing a set of type class instances." There is no way for a Haskell program to deserialise a value whose static type was not visible when the program was compiled. There is no way in Haskell to "get a list of all types" (it's hard to even formulate this).

Implementing Python-style pickle isn't really about types, it's about the language's dynamic features. Can you look up a types by name, reflect on a value at runtime? Dynamic features really do bring new capabilities to programs.

1: https://news.ycombinator.com/item?id=21479933

Re: Dynamic type systems are not inherently more open

#218
post #72

Having moved from Python to C# I'm still coming to terms with how I feel. It's really hard to express but I do have a nagging feeling that something has been lost that other commentators haven't quite put into words either. You just write different code in dynamic languages - even ignoring type declarations. And in many cases it feels like better, more humane code. One piece of evidence for this elusive difference is…

Have you used OCaml? It's a quite different experience than C#. See http://roscidus.com/blog/blog/2014/02/13/ocaml-what-you-gain...

Re: Dynamic type systems are not inherently more open

#219
post #108

Earlier quoted context omitted.

Type inference does not automatically "typify" your code. The type system -- whether the type annotations are explicit or the types are inferred -- determines which expressions are "well-formed" (i.e. syntactically correct), and so you can't write arbitrary code. E.g., in Haskell, you can know for a fact that at one call site a Maybe instance is Just, but whether you annotate your types or rely on inference, the type…

If the reason you know your Maybe T is a Just _ is that you tested it locally: in any language that favors the Maybe pattern, the idiomatic way of performing that test makes the result available to the type system (destructuring / combinators / 'nads). On the other hand, if you know your Maybe is a Just because of non-local information, you will eventually turn out to be wrong :)

No, you can know -- and even prove -- that at a certain callsite, a Maybe would be a Just, and if you were using a dependent type system, you can prove that in the type system (although it probably won't be automatically inferred -- you may have to work hard for the proof), but Haskell's type system is too weak to express such properties and such proofs, at least in the general case.

Re: Dynamic type systems are not inherently more open

#220
post #108

Earlier quoted context omitted.

Type inference does not automatically "typify" your code. The type system -- whether the type annotations are explicit or the types are inferred -- determines which expressions are "well-formed" (i.e. syntactically correct), and so you can't write arbitrary code. E.g., in Haskell, you can know for a fact that at one call site a Maybe instance is Just, but whether you annotate your types or rely on inference, the type…

If you're talking about the fact that you have to unbox the Maybe, that's not really related to type inference or static types but how "null" values are represented in the language. If you're talking about exhaustiveness checks, you can disable those and use `-fdefer-type-errors` to compile programs which don't type-check. Although I will say that most of the time when you have a Maybe instance that you know is Just,…

> If you're talking about exhaustiveness checks, you can disable those and use `-fdefer-type-errors` to compile programs which don't type-check.

Right, but if you were using, say, Idris, the program would type check. It's just that Haskell's type system is too weak. Disabling type checking is not what the question was about. The program is type-correct, yet not in Haskell's particular system.

> Although I will say that most of the time when you have a Maybe instance that you know is Just, it means you're branching in the wrong part of your program.

Perhaps, but that doesn't change the fact that if you write it in some way that is perfectly correct, Haskell's particular type system will still not accept your program.

Post reply on HN