News for hackers. Stuff that matters.
Re:Fun vs. Computer Science (2016) by yorwba on Saturday August 26, 2017 @05:21AM (#15104755)
I think it might be possible to get the benefits of static type checking while still allowing interactive modifications, but most current type systems don't lend themselves to that.

While it would be possible to replace any value by another of the same type (e.g. redefining a function without changing the signature), I'm not aware of any statically checked language with a REPL that allows that. When I'm playing around in the Haskell REPL, redefining a function requires also redefining all other functions that use it, and that's a chore that isn't even required by the type system.

Other modifications are likely to break static checks, e.g. adding a new case to a sum type would invalidate exhaustiveness checking (and thus probably a bunch of compiler optimizations), so no standard type system would allow it. But having a check that makes sure you handle the added case everywhere would actually be nice to have, especially when it can tell you interactively where you need to add more code.

The major hurdle to altering a running program without violating type safety is the fact that you can't just check the original program and the modified version for internal consistency, you also have to ensure that old code that's still running won't be confused when it calls new code and gets an unexpected return value. In the case of adding to a sum type, you could compile in a fall-through case for all pattern matches, and then patch in the new handler code.

For even larger changes, like completely replacing the return type of a function, it might be necessary to specifically engineer the type system such that it can support this case. Ideally, it would support almost all modifications that work in a dynamically typed language, while still preventing anything that would take the program into an inconsistent state.

Re:Fun vs. Computer Science (2016) by hyperpape on Saturday August 26, 2017 @09:03AM (#15105248)
Not sure about Haskell (what I know about the compilation model makes it seem more difficult), but in a typical Java environment (including an IDE remote debugging tomcat/jetty, for instance), the debugger will hot swap changes that are just to method bodies.

The sad part is that this encourages bad development practices because piling on nested loops doesn't require bouncing the server, while properly factored code does.

There are tools like JRebel that are supposed to fix this, but I haven't used them.

Re:Fun vs. Computer Science (2016) by catnaroek on Saturday August 26, 2017 @10:20AM (#15105556)
> Ideally, it would support almost all modifications that work in a dynamically typed language, while still preventing anything that would take the program into an inconsistent state.

This is impossible. Data structures have these little things called “invariants” that require proof to be established. In statically typed languages, abstract data types are used to prevent users from breaking these invariants, by making the representation invisible to anyone but the implementor.

If the data structure underlying an abstract data type can be modified anytime, then every time you patch your program, you would have to check two things:

(0) That the new data structure respects every invariant relied upon by other code.

(1) That either the new data structure is compatible with the old one (which is often not the case), or there are no reachable instances of the old data structure in memory.

This is an even bigger pain in the ass than just stopping the program and fixing it.

Re:Fun vs. Computer Science (2016) by yorwba on Saturday August 26, 2017 @10:54AM (#15105697)
I'm aware that a fully general invariant checker is impossible, but there are still type systems that can catch a lot of errors in practice. If dynamic modifications have to be taken into account, that makes the problem more difficult, but not necessarily impossible. Even though there are changes that can't be checked at all, those can't be too common, or humans wouldn't be able to handle them either.

I'm not sure why you think that the checking will be painful, it almost sounds like you think that it would be done by the programmer. The whole point of type systems is that they can be checked automatically, so the programmer is prevented from doing something stupid.

Dynamic languages already allow all kinds of modifications that might or might not break invariants or introduce subtle incompatibilities; a type system would only make it safer.

It is also not just a matter of "stopping the program and fixing it". Suppose you are writing a game, and during playtesting you encounter a bug, where something is stuck in an endless respawn loop. In a dynamic language, you could look at the misbehaving code, develop a fix, and immediately observe its effects. This allows you to quickly iterate until you have found a solution that works. Compared to a "stop, fix, retry"-cycle, it's simply going to be faster, even assuming you can reproduce the bug reliably (maybe using some kind of input replay).

Re:Fun vs. Computer Science (2016) by catnaroek on Saturday August 26, 2017 @12:44PM (#15106202)
> but there are still type systems that can catch a lot of errors in practice.

I have yet to see a type system that can take a putative implementation of a data structure with arbitrarily complicated invariants, and spits out whether the implementation is correct or not. (Note that Coq, Agda, etc. don't quite fit the bill, because they require the programmer to enter the proof himself, even if these tools can partially automate the process.)

> I'm not sure why you think that the checking will be painful, it almost sounds like you think that it would be done by the programmer. The whole point of type systems is that they can be checked automatically, so the programmer is prevented from doing something stupid.

My point is precisely that type systems aren't normally used to enforce data structure invariants directly. Instead, data abstraction (i.e., the inability to inspect the representation of abstract data types from client code) is used to confine the potential to break data structure invariants to a small fragment of a big program (namely, where the abstract data type is implemented). This is in furious contradiction with the idea of inspecting and modifying anything anytime from anywhere.

Re:Fun vs. Computer Science (2016) by yorwba on Saturday August 26, 2017 @01:26PM (#15106395)
I'm not talking about the kinds of invariants that require an undecidable type system to formalize, but about the most simple things. "Any value passed to this function can be iterated over." "This sequence of checks is exhaustive." "Calling this function with these arguments won't throw an exception."

Those tend to be the mistakes I make when programming interactively in Python. Forgetting to put a single value into a one-element list. Forgetting to check for None. Misspelling a key in a dictionary. Swapping the order of two arguments in a function call.

Yes, in some cases those properties can only be verified by proving some invariant equivalent to the Collatz conjecture. I'd conjecture that most instances could still be solved by an appropriate type system. I'm not too worried if it can't prevent me from invalidating invariants, so long as it can prevent me from making simple mistakes that are obvious in retrospect.

Re:Fun vs. Computer Science (2016) by catnaroek on Saturday August 26, 2017 @01:50PM (#15106514)
> Those tend to be the mistakes I make when programming interactively in Python.

Those tend to be the mistakes that I take for granted any seasoned programmer can detect and fix almost instantaneously and effortlessly. (Of course, not because programmers are superhuman, but rather because Hindley-Milner is the bare minimum a high-level language should have.) It's pathetic that we're still discussing these in 2017.

> Yes, in some cases those properties can only be verified by proving some invariant equivalent to the Collatz conjecture.

I have yet to see a useful program whose correctness is contingent on the Collatz conjecture being true. But I have seen lots of programs that are much easier to verify by hand than using a type system.

> I'm not too worried if it can't prevent me from invalidating invariants, so long as it can prevent me from making simple mistakes that are obvious in retrospect.

I'm not worried either. I'm just saying that “allow anything to be modified anytime, anywhere” is counterproductive. But if you really want to do it, you can do that in ML and Haskell too: just stuff all your top-level definitions into mutable cells.

Re:Fun vs. Computer Science (2016) by yorwba on Saturday August 26, 2017 @03:07PM (#15106873)
> It's pathetic that we're still discussing these in 2017.

Evidently most language creators find it difficult to integrate both interactive programming and static typing, which suggests to me that the problem is not easy. Or maybe there just isn't enough overlap between the groups who value one or the other.

> just stuff all your top-level definitions into mutable cells

That seems like it could be part of a potential solution, but it would require rewriting the program so that everything is implicitly wrapped in the IO monad. And it still doesn't handle the case were you want to add to an existing data type.

Re:Fun vs. Computer Science (2016) by catnaroek on Saturday August 26, 2017 @03:14PM (#15106891)
> Evidently most language creators find it difficult to integrate both interactive programming and static typing.

Interactivity is one thing. Randomly redefining things is a-whole-nother thing. ML and Haskell are interactive. They just don't stuff absolutely everything in mutable cells like most dynamic languages do.

> That seems like it could be part of a potential solution, but it would require rewriting the program so that everything is implicitly wrapped in the IO monad.

You can't have it both ways: either you have effects and accept that you have effects, or don't have effects and accept that you don't have effects. (IOW, lying is bad.)

Re:Fun vs. Computer Science (2016) by branja on Saturday August 26, 2017 @12:36PM (#15106175)
Look into success typing
Re:Fun vs. Computer Science (2016) by yorwba on Saturday August 26, 2017 @01:12PM (#15106316)
Thank you for the recommendation. I think I found the paper that introduced the idea: http://www.it.uu.se/research/group/hipe/papers/succ_types.pd...

If I understand correctly, success typing rejects only programs that will lead to a type error at runtime, but allows all programs that it can't prove incorrect. I think that's an interesting idea and definitely better than no type checks at all, but I'd still like to have a type system that can prove some programs to be type safe, if possible.

Re:Fun vs. Computer Science (2016) by branja on Saturday August 26, 2017 @02:58PM (#15106827)
I agree. Yet I want as much inference as possible as you described upthread