9 ms·
Wow, this is fantastic. Now I have a word ("safyness") for what I and others have been saying for so long: that static typing prevents the bugs that are easies
by chubot 12y ago
Wow, this is fantastic. Now I have a word ("safyness") for what I and others have been saying for so long: that static typing prevents the bugs that are easiest to catch. If it were free, I would take it, but it often does so at a large cost to productivity, and even understanding of the dynamic/runtime behavior of the system.
That second problem I summarize using the phrase the "map is not the territory". (http://en.wikipedia.org/wiki/Map%E2%80%93territory_relation http://en.wikipedia.org/wiki/Map%E2%80%93territory_relation) I had heard this phrase for many years, outside the context of programming. I never quite understood what it meant until I spent time around hardcore C++ and Haskell people. Static typing is a model (a map) for runtime behavior.
- cgag 12y agoSurprising to me to use "the map is not the territory" this way when static typing constrains and makes provable claims about the territory. If none, or even most of those top 25 errors don't mostly look like type errors to you, you don't know enough about good type systems to be making judgement calls about them.
- muhuk 12y ago"Saf" means naive in Turkish. I am actually a big fan of statically typed languages. But it's naive to think a type system will make your programs correct by catching type errors. I do believe a type system helps making programs correct as a design aid.
- adamnemecek 12y agoCurry and Howard would like to have a word with you. http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspond...
- muhuk 12y agoIf they expect me to read some wikipedia article and then try to guess what they mean, they should work on their communication skills first. In other words; if you have an argument, please do share. Don't just appeal to authority.
- adamnemecek 12y agoTl;dr it directly proves that type systems can make your programs correct by catching type errors.
- muhuk 12y agoA correct program is correct whether there's a type system or not. Adding a type system to a correct program doesn't make it more correct. Adding a type system to an incorrect program doesn't make it correct (unless you refactor it). So, type systems DO NOT make programs correct. They help you design correct programs. I am not overlooking the role of static typing in writing correct programs. But I'd disagree if you said type systems by themselves affect correctness of a program directly. A program doesn't come into existence instantly, it is evolved by a design process.
- adamnemecek 12y ago> Adding a type system to an incorrect program doesn't make it correct (unless you refactor it). Of course not, but the compiler will tell you that the program is incorrect since it can deduce it.
- muhuk 12y agoThis means type systems help you make your program correct, I agree. Your argument was "type systems make your programs correct", I still disagree with that. I think the distinction is important enough.
- muhuk 12y agoAre you downvoting me because you can't stand different opinions?
- adamnemecek 12y agoNo, people are downvoting you because you are just wrong. Please see this diagram http://ro-che.info/ccc/17.html http://ro-che.info/ccc/17.html
- stcredzero 12y agowhat I and others have been saying for so long: that static typing prevents the bugs that are easiest to catch Not only are such bugs the easiest to catch, but they include bugs that can be insidious, expensive, and prohibit certain refactorings if they are not caught. This isn't to say that static typing is the only way. It's more accurate to say: If you aren't catching those bugs automatically, you are doing it wrong.
- dllthomas 12y agoRight. And it's not just that the typing is static, but that you are using it properly. Cf: struct price { int value; }; struct quantity { int value; }; int placeOrderUnsafe(int price, int quantity); int placeOrderSafer(struct price, struct quantity); ... placeOrderUnsafe(quantity.value, price.value) /* does the wrong thing */ placeOrderSafer(quantity, price) /* caught at compile */
- dllthomas 12y agoIn my current project (in C), I statically ensure that functions are run on the correct thread. "Oops, that function isn't supposed to be called there because it makes obscure assumptions" is one of the hardest bugs to catch, and my (unsophisticated!) type system regularly catches it for me.
- dman 12y agoHow do you do this?
- dllthomas 12y agoI create a struct representing each thread. Outside of a debug build, these structs are empty. This is always passed as the first argument to any interesting function (as it happens, while the C standard doesn't guarantee it, in GCC this generates the same bytecode as omitting the parameter), and always named th. When defining any global variable designed to be accessed without a lock, I also create a LOCAL_varname_ASSERT_THREAD function that takes the relevant thread as an argument and does nothing, for static assertion of type equality. This is all wrapped in macros to be convenient and readable. When you really start using your type system, it's amazing what can be "a type error", even in something as kludgy as C. At this point, I've been working on the codebase for a year and a half, and it's been in production for much of that. It's >100k LOC, has multiple threads, generates responses in <10us, has been through some major refactorings, and I've had maybe 3 problems involving concurrency that even hit my tests, with one (a high level livelock in my message passing) winding up in production. I don't know how I would have managed this without access to these kinds of static guarantees (which is not to say there aren't any other tools which could have replaced this one, but it is to say there is tremendous value to this tool when you know how to use it!).
- chubot 12y agoThis is interesting. Pretty sure I get it but if this is open source I'd like to see it. Two comments: 1) I'm not sure it would be much more effort to implement this scheme in a dynamic language. Most of them can introspect their own code and you could easily flag such an error at startup time. 2) I like the style of passing a thread to every function. In that case, I wonder why you even have globals that multiple threads need to access. What I try to do is initialize ALL shared data in main(). And then pass those structures ONLY to the exact threads that need them. This can be done in either static or dynamic languages; it enforces a nice structure and is easy to read. I'm not saying a dynamic language would be better for this project. C is a great tool and appropriate for a huge number of problems (also inappropriate for a huge number of problems). FWIW Ritchie's C (the one they wrote Unix in) was very weakly typed, and that heritage still shows. I don't think it's an accident that C is popular; its type system doesn't get in your way, doesn't bloat your code, and also allows creative use/abuse.