Live data from Hacker News

Typing Is Hard

typing-is-hard.ch

81–83 of 83 posts

Re: Typing Is Hard

#81
post #73
post #47

> There exist many type inference algorithms, the best known one is the so-called Algorithm W. Is this correct? I dug out Milner's paper [1] where he states that Algorithm J is more efficient (which was what I had been led to believe), but that Algorithm W is more suited to functional (as opposed to imperative) implementations. Edit: Actually I think I'm parsing this sentence incorrectly, "best known" means literally…

Best known is indeed meant as "most widely known" (although that may be true for only my little bubble). I think it's taught in most type theory / formal methods courses though. If anybody has facts for/against this claim I'd be happy to update the page.

Yeah I think you're definitely right, and Algorithm W is how HM was introduced to me when I studied it.

kevincox's comment sums up my misunderstanding.

Re: Typing Is Hard

#82

Reminder: strict type checking is more trouble than it’s worth for some of us. Ask yourself why dynamic type languages keep appearing, despite a fanatical resolve to purge them from the face of the earth? It’s almost as if some people prefer them. But I guess the knowledge of salvation by compile time binding must be brought to the late binding heathens, to use a poor analogy. On the other hand, I’m willing to admit…

I generally agree, except if I don't. Whether or not that is the case, I'm entirely uncertain about! Generalizing to transportation one might ask: What is the better transportation device, a boat or a horse? ... of which one can somewhat reasonably conclude, that whether the question itself is the right question, is the real question. Few oppose types if they don't have to do anything at all and if it doesn't take an…

One thing I don’t miss is C style Wild West access.

E.g., My coworker grabbed a word from somewhere, slapped a cast on it and proceeded to write into it. Hilarity ensues.

All the burden of explicit compile time checking, but no guarantees that anything is what you said it is by the time your coworker uses it. Of course, no computer Run-time is wasted on silly things like type, bounds or null checking, either.

Re: Typing Is Hard

#83
post #51

Earlier quoted context omitted.

> I don’t see how JS or Python (not so sure about Julia) meaningfully have “dynamic checking for types”. What would you describe as dynamic typechecking then? Would Scheme be a language that would fall under your definition, since it has much less dynamic dispatch? > isn’t inserting any meaningful check until the last possible moment when there is nothing left to do but blow up anyway I mean, inserting it earlier wou…

> What would you describe as dynamic typechecking then? Would Scheme be a language that would fall under your definition, since it has much less dynamic dispatch? I’m not sure about Scheme because I’m not very familiar, but one possibility is simply that “dynamic type checking” is meaningless. In other words, one could argue that anything that blows up at runtime is “runtime type checked” but that doesn’t seem meanin…

I agree with everything you say, except I have a lower bar of "meaningful".

> one possibility is simply that “dynamic type checking” is meaningless.

If I take your quotation out of context, this was the assumption of some people who separated languages into simply "strongly" vs "weakly" typed, by which they meant "checked by compiler" vs "not checked". It's incorrect though, and is the reason for separate "static" vs "dynamic" distinction.

C is a famous example of static (checked at compile time) but weak (≈ unsound) typing — compiler will happily accept programs that corrupt memory in all kinds of ways. mutating "const" variable, freeing used memory, crashing, remote code execution, and more... I don't think there are any invariants that a C compiler can enforce.

Scheme, Python, Lua, Javascript etc. OTOH, have no static (= compile-time) type checking, yet they maintain some invariants! An object that has pointers to it will not be freed; An object's type is known, and will not change (well, some class transmutation is allowed but some not, an int will not turn into an array); Some types are immutable; You can never divide a string / string! etc...

Moreover, by maintaining run-time metadata about object's types, they can tell you specifically that an operation raised a TypeError. Thus these languages are strongly typed at run time.

IOW, I'm arguing that anything that blows up at run time is checked IFF it tells you it was a type error. This is meaningful compared to C segfaults that tell you nothing :-)

---

The Java paper https://dl.acm.org/doi/pdf/10.1145/2983990.2984004 shows an interesting subtlety. "Fortunately, parametric polymorphism was not integrated into the Java Virtual Machine (JVM), so these examples do not demonstrate any unsoundness of the JVM" — yet they present unsound programs that "type-checks according to the Java Language Specification and is compiled by javac, version 1.8.0_25".

What gives? If a bad program compiles, how come JVM is still sound? See, Java has two type systems!

- JVM is the runtime, intended to be capable of loading even untrusted bytecode yet still maintain some type invariants. It manages memory and type metadata, and for this bad program will correctly identify type violation at run-time: "When executed, a ClassCastExceptionis thrown inside the main method with the message “java.lang.Integer cannot be cast to java.lang.String”"

- The compilers uses a distinct more complex static type system. The question of soundness is: can any program that passed the compiler cause JVM run-time type errors?

  + Java language allows you to write type casts.  These are deliberate "trust me" holes in the *static* type system, whose specified semantics is: JVM will check type at run time and raise exception if not as programmer promised.
    As https://typing-is-hard.ch/#what-about-unsafe-casts says, since these are deliberate, and fall back to meaningful run-time type checking(!), let's ignore them — redefine "soundness" as: can a program with no exclicit casts cause a run-time type error?

  + Generics only exist in static type system!
    They are invisible to JVM (aka "type erasure"), they compile into dynamically checked casts.  
    Their soundness goal was that the compiler can prove these implicit casts will never fail — e.g. you can only put candies into ArrayList, so arr.get(0).eat() is guaranteed to give you a candy you can eat.
    That paper demonstrates a simple 17-line program with no explicit casts that compiles yet causes run time type error.
---

If you think what type soundness means, ALL statically typed languages have 2 type systems! There are execution semantics — what it means to, say, compute number + number. And there is a static language of talking about types that aims to predict / prove the types that will be involved at run time. Static checking fails if they don't match. Dynamic checking largely fails when you don't do it :-) But also when you erased info you needed to do it.

Post reply on HN