
Algebraic Subtyping (2016) [pdf] - mpweiher
https://www.cl.cam.ac.uk/~sd601/thesis.pdf
======
rjtobin
Also by Stephen (and previously discussed on HN):
[https://www.cl.cam.ac.uk/~sd601/papers/mov.pdf](https://www.cl.cam.ac.uk/~sd601/papers/mov.pdf)

As usual, he injects just the right amount of humour. Eg. this footnote in his
thesis:

"*This paper is out of print, in Russian, and quite difficult to get a hold
of, so the interested reader is directed to a shorter proof by Conway [Con71,
p. 105], which is merely out of print."

~~~
myst
It's not difficult to get a hold of tho

[http://umj.imath.kiev.ua/article/?lang=en&article=10002](http://umj.imath.kiev.ua/article/?lang=en&article=10002)

~~~
yrhz90
It looks like that volume was produced after this thesis was submitted.

------
acjohnson55
From just skimming the intro, this seems like very exciting work. And the
formulation of the problem in terms of data flow was really novel to me.

I was surprised that I couldn't find any references to Martin Odersky in the
paper, whose work for years at EPFL has been focused on unifying functional
and object oriented programming under a sound type system. This work produced
the Scala programming language. More recently, he reworked the foundations of
Scala using a system he developed called the calculus of dependent object
types (DOT) [1]. I couldn't seem to find any references to this in the thesis.
It's hard to imagine the author was unaware of this work, but I'm really
interested in hearing more about how the two approaches compare.

Anyway, I'm imagining this work could have great applications for things like
TypeScript, and maybe even Scala.

[1] [http://scala-lang.org/blog/2016/02/03/essence-of-
scala.html](http://scala-lang.org/blog/2016/02/03/essence-of-scala.html)

~~~
ezyang
Scala's type inference is not complete; it is marketed as a way to "omit
certain type annotations". One of the reasons why Hindley-Milner is so
influential is because you really _don 't_ need any type annotations: the
inference algorithm always works.

As for DOT [https://www.cs.purdue.edu/homes/rompf/papers/amin-
wf16.pdf](https://www.cs.purdue.edu/homes/rompf/papers/amin-wf16.pdf) DOT is
an _explicitly_ typed calculus (similar to System F), for which no attempts at
type inference are made. So... they're not really comparable at all.

~~~
acjohnson55
Thanks for the insight.

So, I suppose the follow-up question would be whether the techniques of the
paper would make it possible to reformulate DOT without explicit types. Sorry
if that's an ignorant question.

------
ezyang
The lesson of "algebra before syntax" is one that I have seen before, and it
is very gratifying to see it pay off such dividends here.

There is also discussion on LtU here: [http://lambda-the-
ultimate.org/node/5393](http://lambda-the-ultimate.org/node/5393)

~~~
agumonkey
Ha, seems like ltu is having issues; cached version
[https://webcache.googleusercontent.com/search?q=cache:http%3...](https://webcache.googleusercontent.com/search?q=cache:http%3A%2F%2Flambda-
the-ultimate.org%2Fnode%2F5393)

------
Patient0
I've only read the introduction so far - but already it has taught me
something. As a lay-person I am finding it very readable and accessible.

I'd always thought that subtyping inference was only something you need for OO
style languages. But he begins with two very clear, non-OO, motivating
examples and a key insight: failing to support subtyping ignores the data flow
of the program.

~~~
vog
I just had a look at it, and this thesis is really well-written. A beautiful
piece of work, with the right mix of concrete examples, abstract concepts, and
meta-concepts that describe why and how the author developed their concepts.
Can't wait to read more of it.

------
xyzzy123
Lots of positive comments. Given that I'm an idiot, can anyone summarise why
this is interesting?

My view is that this extends the work possible with the type system at compile
time (e.g. in an integer sense, which would be pretty cool if you scoped it as
that) but doesn't extend to "real" numbers or byte manipulation of data.

Like do I need this level of structure in my data, and am I being short-
sighted by thinking of it as constraining?

Perfectly happy to get smashed to heck in exchange for being enlightened :)
Thanks!

EDIT: sorry in advance for the degree of my ignorance.

~~~
tomp
(Disclaimer: I have yet to read the paper.) It's interesting because it's both
_important_ and _hard_.

It's important because it allows you to infer types in the presence of
parametric polymorphism ("generics") and subtyping ("OOP"). For example,
consider this function:

    
    
      twice(f, x) = f(f(x))
      twice : forall a. (a -> a) -> a -> a             // OCaml type (no subtyping)
      twice : forall a, b <: a. (a -> b) -> a -> b     // "ugly" type with subtyping
      twice : forall a, b. (a -> a & b) -> a -> b      // equivalent to the above, but maybe nicer to see and reason about
    

In OCaml, the type of this function would be too narrow, so you wouldn't be
able to call `twice` with arguments such as `round : float -> int` (assuming
`int <: float`). Stephen's previous work [1] infers the third type (`&` means
intersection type).

It's hard because subtypes are hard to reason about. Type inference usually
works by solving equations; if you have 3 type variables 'a, 'b and 'c, and
you know that

    
    
      'a == list[int]
      'b == list['c]
      'a == 'b
    

then you can infer that `'c == int`. This breaks down in presence of
subtyping; for example, you cannot use

    
    
      'a & 'b == 'c & 'b
    

to infer that `'a == 'c` (a possible solution is `'a == int`, `'b == int`, `'c
== float`).

Type inference in the presence of subtyping is so hard that _no_ programming
language does it currently. There are many tricks and approximations - e.g.
Scala does _type propagation_ (if it knows the types of function parameters,
it can infer the types of most other variables), and _bidirectional type
inference_ (it can figure out the types of anonymous function arguments), but
AFAIK there is no existing implementation of it. Hopefully this paper changes
that. Of course, there is an argument to be made that writing types in code
makes it more readable, and therefore types _should_ be written - in general,
I agree with this argument, but type inference can still be very helpful (e.g.
you write a function with complicated types and ask the compiler to fill in
the type; or you write a number of tiny helper functions with obvious types).

[1] MLsub
[https://www.cl.cam.ac.uk/~sd601/mlsub/](https://www.cl.cam.ac.uk/~sd601/mlsub/)

~~~
kvb
Though note that an even better type would probably be

    
    
        twice : forall a,b,c. ((a->b)&(b->c)) -> a -> c
    

(e.g. in MLSub, the type for

    
    
        twice (fun x -> x::[]) 1
    

is the unsatisfying

    
    
        (rec a = (a list | int) list)
    

rather than the expected

    
    
        (int list) list
    
    )

~~~
tomp
You're right, interesting example! Although I'd prefer to "fix" this by
incorporating first-class polymorphism [1] with MLsub - I guess non-
polymorphic functions satisfying the constraint `(a -> b) & (b -> c)` are
quite rare (although I'm sure that _you_ can think of an example).

[1] [https://github.com/tomprimozic/type-
systems/tree/master/firs...](https://github.com/tomprimozic/type-
systems/tree/master/first_class_polymorphism)

Edit: although on second thought, just first-class polymorphism isn't enough
to fix this... any type system where the function `twice` has the same type as
the function `three_times` will exhibit the same problem!

~~~
kvb
Non-polymorphic functions of the type `a->a` trivially satisfy it, of course.
Also, I think polymorphic functions are the most interesting case where you
can't use twice as desired in an ML-like language, so it's too bad that
despite the fancier type they don't work too well in MLsub. Here's another
example that fails when I'd hope for it to succeed:

    
    
      let one = twice (fun o -> o.x) { x = { x = 1 } }

------
Munksgaard
I've been waiting for this paper ever since I saw Stephens presentation of
MLsub [0] at ICFP 2015. I thought the paper had an interesting take on type
checking, and it has given me some ideas that I've been wanting to try out for
myself.

I look forward to reading the dissertation over the weekend.

[0]:
[https://www.cl.cam.ac.uk/~sd601/mlsub/](https://www.cl.cam.ac.uk/~sd601/mlsub/)

------
auggierose
Just read the introduction, and it hits all the right spots in explaining why
people (including me) have failed to come up with good subtyping in Hindley-
Milner world. I expect people to rush to update their various HM-based systems
to this new approach. This seems like a really big thing to me.

------
infinity0
"The primary tool by which this was achieved was not advanced or complicated
algorithms, but attention to the minutiae of basic definitions."

------
Ericson2314
> Disjoint union is the coproduct in the category of sets, so we have a good
> excuse to use the symbol +

This is definitely making fun of somebody

------
vog
[deleted]

Stupid misunderstanding. Sorry, forget what I wrote. I wanted to delete my
comment, as it provides no insight and not even an interesting question. But
unfortunately the delete button disappeared here in Hacker News.

~~~
Manishearth
"PhD" stands for "Doctor of Philosophy".

------
fpoling
And now I know why record-like types are so awkward in many functional
languages. A classical type inference just cannot type them requiring heavy
type annotations.

------
xyzzy123
Thanks. Do you have any useful insights such as programming in a relevant
language? Shoot from github first if you want to hulk smash demonstrating
competence.

P.S: let me know if I'm not adequately rating your contributions.

~~~
dang
Incivility like this will get your account banned on HN, so please don't do it
here.

We detached this comment from
[https://news.ycombinator.com/item?id=13782112](https://news.ycombinator.com/item?id=13782112)
and marked it off-topic.

