14

What kind of type inference does Typed Racket do? I found the following snippet on the Racket mailing list:

The Typed Racket type system contains a number of features that go beyond what's supported in Hindley/Milner style type systems, and so we can't use that inference system. Currently, Typed Racket uses local type inference to infer many of the types in your program, but we'd like to infer more of them -- this is an ongoing area of research.

The blurb above uses the term "local type inference", and I've also heard "occurrence typing" used a lot, but I'm not exactly sure what these terms mean.

It seems to me that the type inference system that Typed Racket currently uses is unnecessarily weak. Here's an example of what I mean. The following does not type check:

(struct: pt ([x : Real] [y : Real]))

(define (midpoint p1 p2)
  (pt (/ (+ (pt-x p1) (pt-x p2)) 2)
      (/ (+ (pt-y p1) (pt-y p2)) 2)))

You have to explicitly annotate midpoint with (: midpoint (pt pt -> pt)), otherwise you get the error: Type Checker: Expected pt, but got Any in: p1. Why can't the type checker just conclude from this that the types of p1 and p2 must be pt? Is this a fundamental limitation of the way that Racket implements types (i.e. is this line of reasoning actually wrong sometimes, because of some of Racket's more advanced type features), or is this something that could possibly be implemented in the future?

Alexis King
  • 40,717
  • 14
  • 119
  • 194
Ord
  • 5,113
  • 4
  • 25
  • 42
  • 8
    Sam Tobin-Hochstadt's PhD dissertation should have the gory details: http://www.ccs.neu.edu/racket/pubs/dissertation-tobin-hochstadt.pdf – dyoo Oct 24 '12 at 18:18

1 Answers1

6

By default, unannotated top-level functions are assumed to have input and output types of Any. I offer this vague explanation: since Racket's type system is so flexible, it can sometimes infer types that you wouldn't expect, and allow some programs to typecheck when you might prefer them to emit a type error.

Tangent: you can also use the define: form if that is what suits you.

(define: (midpoint [p1 : pt] [p2 : pt]) : pt
  ...)
Dan Burton
  • 51,332
  • 25
  • 109
  • 190
  • 1
    Adding to this answer: I'll take "well-defined" over "clever" any day of the week. The problem with "clever" is that as a programmer, sooner or later you're going to wind up somewhere just on the other side of the boundary between checkable and not-checkable, and you have to figure out how to change your code so that the checker can validate it. In a situation like this, trying to intuit which cleverness to appeal to can be very difficult. – John Clements Oct 25 '12 at 03:00
  • 1
    So it sounds like there isn't really a fundamental *limitation* - instead, there's just this fuzzy grey area between programs that are well-typed and programs that aren't (and maybe this area is larger in Typed Racket than other type systems, since the Racket system is so flexible). The people who designed Typed Racket's inference simply stayed as far away from that boundary as possible: there are only a few, well-defined cases where type inference can happen, and everything else must be explicitly declared. That way, they avoid getting into a tangled mess. Is that about right? – Ord Oct 25 '12 at 21:42
  • 2
    @Ord that's about right. You can read Sam's dissertation for the details. He even dedicates a section of it to this question: section 3.2. – Dan Burton Oct 26 '12 at 01:19