Hacker News new | ask | show | jobs
by msla 3233 days ago
The conflation between 'strong' and 'static', and 'weak' and 'dynamic', is probably terminal at this point, but maybe I can do something to, at least, explain the position of the people who don't conflate those terms:

Strong typing is about creating, expressing, and enforcing a contract which determines which operations are valid on which values. Not variables, values. Having the semantics of the value in the compiler or the runtime ensures that errors are handled predictably, with explicit detection and possible reporting.

Weak typing is a lack of those semantics. In the most extreme case, you have languages such as B, where the only type is the machine word, which isn't a type at all because it doesn't imply anything about semantics: You can do anything to a machine word, so nothing can possibly be invalid, so there's nothing to enforce or detect or report. Similar "size specifications", such as int, or long, or float, are only loosely describable as types for the same reason: They specify how many bits a value has, not what's valid to do to it.

So a language such as Python is strongly typed because it can detect violations of the contract inherent in the types it knows about at runtime. C is less strongly typed, because, first, it focuses on its "size specification" types, and, second, you can subvert even that type system totally with nary a peep. Languages such as Ada, which inherited the "size specification" types from Algol, are only strongly typed to the extent you can augment their type system with types which are actually semantic, as opposed to size-based.

2 comments

> The conflation between 'strong' and 'static', and 'weak' and 'dynamic', is probably terminal at this point,

Type system of C is weak and static.

Type system of JavaScript is weak and dynamic.

Type system of Lisp is strong and dynamic.

Type system of OCaml is strong and static.

Type system of Python is dynamic. It may be strong or weak, depending on your opinion about duck typing (does it weaken the type system or not?).

The "weak" terminology has a flaw because it sometimes means "leaves type errors undetected, with undefined behavior" and sometimes it refers to a situation whereby a character string like "3.14" can be treated as a number and such.

Awk and Perl are not weakly typed in the same sense that C is weakly typed.

There is also the related aspect of conversions. Ada is said to be stronger than C even if we ignore the "holes in the type system" of C because it doesn't allow implicit conversions (conversions without an explicit conversion operator or casting syntax). Though C won't treat a "3.14" character string as a number, it implicitly converts among numbers of different kinds, and converts between void * and object pointers. Narrowing conversions silently discard data ("implementation-defined result"), and so do conversions between same size but different signedness. Out-of range conversions between integer and floating-point values can trigger undefined behavior. (These issues are still there when the conversions are explicit, but when the conversion are implicit, the issues can sneak into the code more easily by accident).

Though Lisp was listed in the grandparent posting as "strongly typed", it also has something similar to C's implicit conversions:

  [1]> (sin 42)
  -0.91652155
  [2]> (sin 42.0)
  -0.91652155
  [3]> (+ 1 2.0)
  3.0
Unlike C, it won't go from floating to integer:

  [4]> (evenp 3.0)

  *** - EVENP: 3.0 is not an integer
Whereas if we had an

  bool evenp(int arg);
function in C and called it as

  evenp(3.0);
or even

  evenp(3.1);
it would work.
Honest question:

Is Python-with-type-hinting-in-function-definitions (and maybe type assertions) equally as "strong" as common style Python?

It's not static typing -- it's not Haskell -- but it's already a step further.

Edit: I find myself doing a lot of "assert isinstance(x,foo)".

It seems like it's about as strong, in terms of what types it knows about, but it allows more error detection at "compile time" or, at least, the time at which you run the static type-checking code on the codebase. As Guido said, this is like a super-linter.

https://www.python.org/dev/peps/pep-0484/

(I remember C linters trying to expand the C type system by doing things like complaining if you used non-boolean expressions in a boolean context, well before C had an actual bool type.)

Haskell types don't exist at runtime. If you use a static analyzer like mypy, Python types are “static” in the same sense as Haskell (statically verified as correct in advance), though mypy’s type system is less robust than Haskell’s.
I'm not knowledgeable of this stuff, but I'll keep taxing your patience until you tell me to stop.

Haskell types don't exist at runtime... because Haskell code (like with any other compiled language) gets translated to a lower-level machine language that works with untyped memory addresses?

Or are you saying that (for example) Fortran types are closer to the metal somehow?

Haskell types don't exist at runtime, because you can't check a type at runtime.

Any type-checking has to happen at compile time, because that information doesn't make it through.

So, something like Python's isinstance or type functions can't exist.

Sorry if dumb question. If Haskell types don't exist at runtime how do type class functions work? I'd think the type needs to get inspected to choose the implementation to call?