int strlen(const char * notnull str);
where the compiler would complain if you passed a possibly-null string to
strlen. This would be especially nice considering the current behavior is just to segfault.
(If that declaration confuses you, see footnote*.)
This simple example is a nice place to start thinking about subtypes. Most OO programmers have a conception of what these are (despite generally having them confused with subclasses), but it's surprisingly difficult to keep things straight. So, two questions:
const char *a subtype of
const char * notnulla subtype of
const char *?
connect()(which works with TCPConnections) but you can only pass the former to
do_POST()(an operation specific to HTTP).
The way I usually keep this straight is with examples like I just gave. So to answer the questions:
- When a function wants a
const char *, it's saying that it won't modify the chars its passed, but also that it'll still accept plain
char *. Subset of functionality + accepting the other = no,
const char *is a supertype of
- You can no longer pass plain
const char *to my modified
strlen(), because they might be
NULL. More specific requirement on the argument means yes,
const char * notnullis a subtype of
const char *.
mutableexplicitly: then both
notnullare qualifiers that are further constraining the types, and both would indicate subtypes.
I think this is further confused by the fact that these qualifiers behave more like attributes than subtypes, but I don't really have a strong understanding of why I see a distinction there. (I can just imagine Graydon wincing at all of this now...)
* Footnote: C types are read backwards, which takes a bit to get used to. In a
const char *, it's the
charthat's immutable; an immutable pointer is
char * const, and read "constant pointer to char". ML fell into this same trap, so expressions like
ref 3have type
int ref. Haskell (do I even need to write this sentence?) has it in the other order, which is both cleaner and works analogously with functions (where the "argument" to the type is on the right: list of int, not int list).