In Types and Programming Languages, Ben Pierce says “Terms like ‘dynamically typed’ are arguably misnomers and should probably be replaced by ‘dynamically checked’, but the usage is standard”. Generally, you’ll see ‘tag’ used by type theorists to distinguish what dynamic languages are doing from what a static language considers a type.
Type systems have existed as a field in math for over a century and predate programming languages by decades. They do a slightly different sort of thing vs dynamic checking, and many type system features like generics or algebraic data types make sense in a static context but not in a dynamic one.
many type system features like generics or algebraic data types make sense in a static context but not in a dynamic one
Hum… Not so much. You can do polymorphism with dynamic types perfectly well, with mechanisms that are exactly equivalent to the ones used on static languages (python people just love that). You can also have tagged unions with a completely equivalent mechanism from algebraic data types (that everybody ends-up doing in json sooner or later). Also you can do out of order verifications in a logical fashion, rewrite code at run time, or anything else even. It’s compile-time that has limitations on what it can do, runtime has none.
I am not at all against inventing new names. But I am really against naming concepts that are not independent from each other. And insisting on those is just signaling-oriented pedantry. So you can very well insist that the dynamic thing is not called “type”, but you can’t really do it in a way that implies the only thing you can get out of them is a type mismatch error.
What kind of runtime tag corresponds to generics, exactly?
Python handles generics essentially the same way that Java 1.0 handles generics: it just kinda punts on it. In Java 1.0, list is a heterogenous collection of Objects. Object, in Java 1.0, allows you to write polymorphic code. But it’s not really the same sort of thing; that’s why they added generics.
It’s compile-time that has limitations on what it can do, runtime has none.
Ish.
There’s typing a la Curry, where semantics don’t depend on static types and typing a la Church, where semantics can depend on static types.
Haskell’s typeclasses, Scala’s implicits and Rust’s traits are a great example of something that inherently requires Church style typing.
One of the nice things typeclasses let you do is to write functions that are polymorphic on the return type, and the language will automagically pick the right one based on type inference. For example, in Haskell, the result of the expression fromInteger1 depends on type ascribed to it. Use it somewhere that expects a double? It’ll generate a double. Use it somewhere you expect a complex number? You’ll get a complex number. Use it somewhere you’re using an automatic differentiation library? You’ll get whatever type that AD library defined.
That’s fundamentally not something you can do in python. You have to go with the manual implementation passing approach, which is incredibly painful so people do it very sparingly.
More to the point, though, limitations have both costs and befits. There’s a reason python doesn’t have goto and that strings are immutable, even though those are limitations. The question is always if the costs outweigh the benefits or not.
Bob Harper uses ‘unityped’ in his post about how dynamic typing is a static type system with a single type in disguise. I’ve literally never heard “monotyped” used as a term in a dynamic context.
In Types and Programming Languages, Ben Pierce says “Terms like ‘dynamically typed’ are arguably misnomers and should probably be replaced by ‘dynamically checked’, but the usage is standard”. Generally, you’ll see ‘tag’ used by type theorists to distinguish what dynamic languages are doing from what a static language considers a type.
Type systems have existed as a field in math for over a century and predate programming languages by decades. They do a slightly different sort of thing vs dynamic checking, and many type system features like generics or algebraic data types make sense in a static context but not in a dynamic one.
Hum… Not so much. You can do polymorphism with dynamic types perfectly well, with mechanisms that are exactly equivalent to the ones used on static languages (python people just love that). You can also have tagged unions with a completely equivalent mechanism from algebraic data types (that everybody ends-up doing in json sooner or later). Also you can do out of order verifications in a logical fashion, rewrite code at run time, or anything else even. It’s compile-time that has limitations on what it can do, runtime has none.
I am not at all against inventing new names. But I am really against naming concepts that are not independent from each other. And insisting on those is just signaling-oriented pedantry. So you can very well insist that the dynamic thing is not called “type”, but you can’t really do it in a way that implies the only thing you can get out of them is a type mismatch error.
What kind of runtime tag corresponds to generics, exactly?
Python handles generics essentially the same way that Java 1.0 handles generics: it just kinda punts on it. In Java 1.0, list is a heterogenous collection of Objects. Object, in Java 1.0, allows you to write polymorphic code. But it’s not really the same sort of thing; that’s why they added generics.
Ish.
There’s typing a la Curry, where semantics don’t depend on static types and typing a la Church, where semantics can depend on static types.
Haskell’s typeclasses, Scala’s implicits and Rust’s traits are a great example of something that inherently requires Church style typing.
One of the nice things typeclasses let you do is to write functions that are polymorphic on the return type, and the language will automagically pick the right one based on type inference. For example, in Haskell, the result of the expression
fromInteger 1
depends on type ascribed to it. Use it somewhere that expects a double? It’ll generate a double. Use it somewhere you expect a complex number? You’ll get a complex number. Use it somewhere you’re using an automatic differentiation library? You’ll get whatever type that AD library defined.That’s fundamentally not something you can do in python. You have to go with the manual implementation passing approach, which is incredibly painful so people do it very sparingly.
More to the point, though, limitations have both costs and befits. There’s a reason python doesn’t have goto and that strings are immutable, even though those are limitations. The question is always if the costs outweigh the benefits or not.