1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
//! Once upon a type
//!
//! - **Date:** March 6, 2016
//! - **Subject:** Type systems: strong vs. weak, dynamic vs. static, and
//! degrees of expressivity.
//! - [**Audio**][mp3]
//!
//! [mp3]: https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e011.mp3
//!
//! <audio style="width: 100%" title="e011: Once Upon a Type" controls preload=metadata><source src="https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e011.mp3"></audio>
//!
//!
//! Notes
//! -----
//!
//! Talking about type systems! A broad and wide-ranging discussion about type
//! systems in general, with specific examples from languages like PHP,
//! JavaScript, Python, C, C++, Java, C♯, Haskell, and Rust!
//!
//! - What is a type system?
//! - What are the kinds of things we get out of type systems?
//! - What are the tradeoffs with different type systems?
//! - What is Rust's type system like?
//! - What is especially attractive about Rust's type system?
//!
//! A comment on the C integer/character string addition example: what's
//! actually happening there is that the character string is an array "under the
//! covers," and as such has an address. C silently switches to using the memory
//! address, which is of course just an integer, when you try to add the two
//! together. As I said on the show: the result is nonsense (unless you're using
//! this as a way of operating on memory addresses), but it's compileable
//! nonsense. In a stricter and stronger type system, memory addresses and
//! normal numbers shouldn't be addable!
//!
//!
//! Links
//! -----
//!
//! - [Rust 1.7 released][l1]
//! + [`HashMap` changes][l2]
//! - [Introduction to Type Theory][l3]
//! - [Visualizing Rust's type-system][l4]
//! - [The Many Kinds of Code Reuse in Rust][l5]
//!
//! [l1]: http://blog.rust-lang.org/2016/03/02/Rust-1.7.html
//! [l2]: http://blog.rust-lang.org/2016/03/02/Rust-1.7.html#library-stabilizations
//! [l3]: http://www.cs.ru.nl/~herman/PUBS/IntroTT-improved.pdf
//! [l4]: https://jadpole.github.io/rust/type-system
//! [l5]: http://cglab.ca/~abeinges/blah/rust-reuse-and-recycle/
//!
//!
//! Sponsors
//! --------
//!
//! - Aleksey Pirogov
//! - Chris Palmer
//! - [Derek Morr][s3]
//! - Hamza Sheikh
//! - Lachlan Collins
//! - Leif Arne Storset
//! - Luca Schmid
//! - Micael Bergeron
//! - Pascal
//! - Ralph Giles ("rillian")
//! - Ralph "FriarTech" Loizzo
//! - reddraggone9
//! - Ryan Ollos
//! - [William Roe][s11]
//!
//! [s3]: https://twitter.com/derekmorr
//! [s11]: http://willroe.me
//!
//! ### Become a sponsor
//!
//! - <a href="https://www.patreon.com/newrustacean" rel="payment">Patreon</a>
//! - [Venmo](https://venmo.com/chriskrycho)
//! - [Dwolla](https://www.dwolla.com/hub/chriskrycho)
//! - [Cash.me](https://cash.me/$chriskrycho)
//!
//!
//! Contact
//! -------
//!
//! - New Rustacean:
//! + Twitter: [@newrustacean](https://www.twitter.com/newrustacean)
//! + Email: [hello@newrustacean.com](mailto:hello@newrustacean.com)
//! - Chris Krycho
//! + GitHub: [chriskrycho](https://github.com/chriskrycho)
//! + Twitter: [@chriskrycho](https://www.twitter.com/chriskrycho)
use std::fmt;
/// Is the thing "expressive", whatever that means?
pub enum Expressive {
Ridiculously,
PrettyDarn,
Fairly,
SortOf,
Barely,
NotEvenALittle,
}
impl fmt::Display for Expressive {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let description = match *self {
Expressive::Ridiculously => "ridiculously",
Expressive::PrettyDarn => "pretty darn",
Expressive::Fairly => "fairly",
Expressive::SortOf => "sort of",
Expressive::Barely => "barely",
Expressive::NotEvenALittle => "not even a little",
};
write!(f, "{} expressive", description)
}
}
/// Is the thing *strong*?
pub enum Strong {
Indeed,
ABit,
NotEspecially,
NopeNopeNope,
}
impl fmt::Display for Strong {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let description = match *self {
Strong::Indeed => "strong indeed",
Strong::ABit => "a bit strong",
Strong::NotEspecially => "not especially strong",
Strong::NopeNopeNope => "strong? NOPE NOPE NOPE",
};
write!(f, "{}", description)
}
}
/// Is the thing statically known?
pub enum StaticallyKnown {
Yeah,
Nope,
}
impl fmt::Display for StaticallyKnown {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let description = match *self {
StaticallyKnown::Yeah => "it's totally known at compile time",
StaticallyKnown::Nope => "we don't know anything about it until run time",
};
write!(f, "{}", description)
}
}
/// Look, we composed those enums into another type. How... droll.
pub struct TypeSystem {
name: String,
expressive: Expressive,
strong: Strong,
statically_known: StaticallyKnown,
}
impl TypeSystem {
pub fn builder(
name: &str,
expressive: Expressive,
strong: Strong,
statically_known: StaticallyKnown,
) -> TypeSystem {
TypeSystem {
name: name.to_string(),
expressive,
strong,
statically_known,
}
}
}
/// An incredibly contrived function which just shows enums at work.
///
/// I wanted there to be *some* sample code this episode, you know? This one
/// just assembles the types into a vector and prints them all. It does,
/// however, let us refresh ourselves on a bunch of other concepts we've covered
/// on the show---pretty much everything but generics makes an appearance in
/// some way in this module.
pub fn describe_type_systems() {
let js = TypeSystem::builder(
"ECMAScript",
Expressive::Fairly,
Strong::NopeNopeNope,
StaticallyKnown::Nope,
);
let php = TypeSystem::builder(
"PHP",
Expressive::Barely,
Strong::NopeNopeNope,
StaticallyKnown::Nope,
);
let c = TypeSystem::builder(
"C",
Expressive::Barely,
Strong::NotEspecially,
StaticallyKnown::Yeah,
);
let cpp = TypeSystem::builder(
"C++",
Expressive::SortOf,
Strong::ABit,
StaticallyKnown::Yeah,
);
let java = TypeSystem::builder(
"Java",
Expressive::SortOf,
Strong::ABit,
StaticallyKnown::Yeah,
);
let csharp = TypeSystem::builder(
"C♯",
Expressive::Fairly,
Strong::Indeed,
StaticallyKnown::Yeah,
);
let swift = TypeSystem::builder(
"Swift",
Expressive::PrettyDarn,
Strong::Indeed,
StaticallyKnown::Yeah,
);
let rust = TypeSystem::builder(
"Rust",
Expressive::PrettyDarn,
Strong::Indeed,
StaticallyKnown::Yeah,
);
let haskell = TypeSystem::builder(
"Haskell",
Expressive::Ridiculously,
Strong::Indeed,
StaticallyKnown::Yeah,
);
let langs = vec![js, php, c, cpp, java, csharp, swift, rust, haskell];
for lang in langs {
println!(
"{language} is {expressive}, {strong}, and {statically_known}",
language = lang.name,
expressive = lang.expressive,
strong = lang.strong,
statically_known = lang.statically_known
);
}
}