"Strong typing" is an ambiguous term, I'm going to need something more specific. As far as I'm aware, "strong typing" is used as a spectrum, in which case C is relatively strong because the compiler will reject parameters that don't match a function signature's data type unless explicitly cast.
Nonetheless, unit tests aren't a panacea. If all you do is just run your unit tests, watch them pass and proclaim "Well, everything works! No need to do any acceptance, integration, system, fuzz or other form of testing! Not even gonna run it, let's just ship!", then that's quite stupid, to put it mildly.
> "Strong typing" is an ambiguous term, I'm going to need something more specific. As far as I'm aware, "strong typing" is used as a spectrum, in which case C is relatively strong because the compiler will reject parameters that don't match a function signature's data type unless explicitly cast.
C has some unfortunate integer conversion rules and a style that often encourages the use of (unsafe) void pointers. Perhaps more importantly, the only way to implement polymorphism is with casting or unions, both of which are very much unsafe.
Still, you can write safe code in C, at least once you write an object system. Use structs rather than typedefs, avoid casts, use only memory-safe things, write wrapper functions to allow you to do allocation and deallocation in a safe way. It's actually possible to reach a similar safety level to something like Haskell - but it will require a lot of tedious hand coding because the language doesn't have the abstraction facilities that would let you write these helpers generically. Eventually you end up greenspunning.
> Nonetheless, unit tests aren't a panacea. If all you do is just run your unit tests, watch them pass and proclaim "Well, everything works! No need to do any acceptance, integration, system, fuzz or other form of testing! Not even gonna run it, let's just ship!", then that's quite stupid, to put it mildly.
Sure. But I think it's reasonable for your day-to-day code loop to be edit / run unit tests, and to do the fancier testing or manual testing maybe a few times a week.
In a language like Haskell (actually I use Scala) you can get to the same point with compilation. It won't just happen without working at it, you need to think about what invariants are important and then encode them into your types. And you wouldn't want to release/deploy without executing the program or running some tests. But you can get to the point where in day-to-day coding an edit/compile cycle is enough.
C is strongly typed, it just has too few types to enable the really useful benefits of static type checking. If typedef actually let you define new types instead of just defining a shorthand for an existing type, it would be a much safer language.
"Actually, the reality of C is much more complex: C has two different type systems. There is one type system (with types such as int, double and even function types) at the level of the program, and a different type system, defined solely by lengths of bitstrings, at the level of execution. … As a result, it isn't even meaningful to talk about soundness for C, because the static types and dynamic type representations simply don't agree."
page 263 "Programming Languages: Application and Interpretation" Shriram Krishnamurthi 2003
That's an outdated version of a bad book. That statement is completely false. Notice how as racket's type system improved, he continued to update the book to be more and more pro-types and removed more and more the deliberate FUD like that?
>There is one type system (with types such as int, double and even function types) at the level of the program
Yes, that is the only type system.
>and a different type system, defined solely by lengths of bitstrings, at the level of execution
That is not a type system. By definition type systems are at the program level. Data classification occurs at the level of execution, and such a system exists in virtually every language whether it has a type system or not.
If you have ever used the phrases “strong typing” or “weak typing”, define them.
That’s what I thought. But thank you for playing.
Indeed, the phrases are not only poorly defined, they are also wrong, because the problem is not with the “strength” of the type checker but rather with the nature of the run-time system that backs them.
Concerning "strong typing", yeah I completely agree. I've wanted to talk about types and programming languages for some time now, but I've had trouble because the word "type" means very different things depending on what programming languages you are familiar with.
I think the thing that people are so excited about for recent type systems is that they have some basis in type theory. So maybe we can call these type systems "mathematically typed" or something along those lines?
Nonetheless, unit tests aren't a panacea. If all you do is just run your unit tests, watch them pass and proclaim "Well, everything works! No need to do any acceptance, integration, system, fuzz or other form of testing! Not even gonna run it, let's just ship!", then that's quite stupid, to put it mildly.