Structural Typing
=================
```Example from 1 languages: Python
# Python's optional static type system features 2 kinds of structural types:
from typing import Protocol
class Clearable(Protocol):
def clear(self): ...
def print_and_clear(x: Clearable):
print(x)
x.clear()
print_and_clear([1, 2, 3]) # OK because lists have a clear() method
print_and_clear({1, 2, 3}) # OK because sets have a clear() method
print_and_clear(1) # not OK because ints don't have a clear() method
from typing import TypedDict
class NameDict(TypedDict):
first_name: str
last_name: str
class EmployeeDict(TypedDict):
employee_id: int
first_name: str
last_name: str
def greet(name: NameDict):
print(f"Hello {name['first_name']} {name['last_name']}!")
john: EmployeeDict = {
"first_name": "John", "last_name": "Smith", "employee_id": 123
}
# EmployeeDict is a (structural) subtype of NameDict even though there is no
# explicit relation between them, so this passes type checking:
greet(john)
```
```Example from 1 languages: C++
// concepts use structural typing:
#include <iostream>
#include <string>
using namespace std;
// NOTE that concept implementations MUST be defined BEFORE the concept itself
string toTypedJson(int x) {
return "{\"type\": \"int\", \"value\": " + to_string(x) + "}";
}
template <typename T>
concept ToTypedJson = requires (T a) {
{toTypedJson(a)} -> convertible_to<string>;
};
template <ToTypedJson T>
void printAsTypedJson(T x) {
cout << toTypedJson(x) << endl;
}
int main() {
printAsTypedJson(123);
}
```
```Example from 1 languages: TypeScript
// https://www.typescriptlang.org/docs/handbook/type-compatibility.html
// Subtype relations are structural for both interfaces and classes.
// Interface example:
interface CanCheckIncludes<T> {
includes(x: T): boolean;
}
function logIfIncludes<T>(includer: CanCheckIncludes<T>, includee: T) {
if (includer.includes(includee)) {
console.log(includer);
}
}
logIfIncludes("abc", "b");
logIfIncludes([1, 2, 3], 4);
logIfIncludes(1, 1); // Fails typechecking, as numbers don't have includes()
```
```Example from 1 languages: Scala
// https://docs.scala-lang.org/scala3/reference/changed-features/structural-types.html#using-java-reflection-1
import scala.reflect.Selectable.reflectiveSelectable
type Reversable[T] = { def reverse: T }
def printReversed[T](x: Reversable[T]): Unit = {
println(x.reverse)
}
printReversed("abc")
printReversed(Array(1, 2, 3))
printReversed(1) // Doesn't compile because integers don't have a reverse method
```
*
Languages *with* Structural Typing include Python, C++, TypeScript, Scala, OCaml
*
Languages *without* Structural Typing include JavaScript, C, Java, Bash, Rust, Kotlin
*
View all concepts with or missing a *hasStructuralTyping* measurement
http://pldb.info/../lists/explorer.html#columns=rank~id~appeared~tags~creators~hasStructuralTyping&searchBuilder=%7B%22criteria%22%3A%5B%7B%22condition%22%3A%22null%22%2C%22data%22%3A%22hasStructuralTyping%22%2C%22origData%22%3A%22hasStructuralTyping%22%2C%22type%22%3A%22num%22%2C%22value%22%3A%5B%5D%7D%5D%2C%22logic%22%3A%22AND%22%7D missing
http://pldb.info/../lists/explorer.html#columns=rank~id~appeared~tags~creators~hasStructuralTyping&searchBuilder=%7B%22criteria%22%3A%5B%7B%22condition%22%3A%22!null%22%2C%22data%22%3A%22hasStructuralTyping%22%2C%22origData%22%3A%22hasStructuralTyping%22%2C%22type%22%3A%22num%22%2C%22value%22%3A%5B%5D%7D%5D%2C%22logic%22%3A%22AND%22%7D with
*
Read more about Structural Typing on the web: 1.
https://en.wikipedia.org/wiki/Structural_type_system 1.
Built with Scroll v178.2.3