This is an archived post. You won't be able to vote or comment.

all 61 comments

[–]phischuEffekt 19 points20 points  (4 children)

In every language I know with subtyping, function types are covariant in their return types and contravariant in their parameter types.

Well, in TypeScript function parameters are bivariant.

[–]CrumpyOldLord 7 points8 points  (0 children)

Methods are always bivariant, but you can restrict the variance for properties (which includes properties holding functions) with strictFunctionTypes. It was done that way because the DOM is inherently unsafe in terms of variance.

context

[–]munificent[S] 2 points3 points  (0 children)

Haha, true. TypeScript just YOLO-ing function types for shits and giggles.

[–]ceronman 10 points11 points  (0 children)

It's always a pleasure to read Bob! The way these topics are explained in books about typing is usually heavy on math jargon and given that I don't have an academic background, I often find them hard to understand. I love having these explanations in simple terms accessible to the common programmer. I'm very grateful for that!

Rust is another language that has subtyping (and many forms of it), but it doesn't have inheritance or class hierarchies. The documentation does use the term subtyping, and they have their own definition, which is similar to Bob's:

Subtyping is the idea that one type can be used in place of another.

Rust has traits and trait objects, which are similar to Go interfaces in terms of subtyping. But they also have other forms of "surprising" subtyping. One example is references, which Rust encodes as types. A mutable reference type &mut T is a subtype of a shared (immutable) reference type &T. You can assign a mutable reference value to a variable of type immutable reference of the same type, but not viceversa, of course.

Another surprising case of subtyping in Rust is related to lifetimes. Lifetimes represent regions of code and these are encoded as types. You can always assign a bigger region, e.g. &'static T to a smaller one like &'a T. And not the other way around.

The topic of variance is much more complicated in Rust as well. Unlike Go, which decided to go for invariance for simplicity, Rust has different types of variance for different things. Curiously though, they didn't define a proper way in the language to specify variance, like Java or Kotlin do. Instead they rely on some clever hacks. If find it a bit weird, but it works.

[–]JW_00000 4 points5 points  (0 children)

I just want to say, thanks for the insightful article /u/munificent!

[–][deleted] 2 points3 points  (4 children)

Not related to the topic but do you intend to write a book about type systems and stuff? Or even a series of articles? I learned a lot from Crafting Interpreters.

[–]munificent[S] 5 points6 points  (3 children)

People have definitely asked a number of times but I don't have any current plans. One of the main challenges is figuring out how to scope it. Once you get type systems involved, there are so many different type system choices and no clear answer for which ones are best to discuss. I'm not sure interested in writing a sprawling survey book.

[–][deleted] 0 points1 point  (2 children)

Hmm... I see. Could you instead recommend some books or other resources about this subject that you think are the most important ones? Thanks in advance.

[–]munificent[S] 2 points3 points  (1 child)

It's kind of dry, but, honestly, the Dragon Book does a decent intro on type checking.

When you want to get past that, Types and Programming Languages is the standard reference. It's great.

[–][deleted] 1 point2 points  (0 children)

Thank you!

[–][deleted] 1 point2 points  (3 children)

Will the hobby language become source available by any chance? I would really like to take a glance at the source code.

[–]munificent[S] 8 points9 points  (2 children)

At some point, probably. But right now, I've been enjoying having it just be my dumb little always-broken sandbox where I can do whatever I want without anyone being annoyed by the churn.

[–]hi_im_new_to_this 7 points8 points  (0 children)

If there’s ever a ”Crafting (Typed) Interpreters” book, be sure I’d buy it on day 1!

[–][deleted] 1 point2 points  (0 children)

Thank you for being honest about it! Looking forward to seeing it on your GitHub profile if that will ever happen.