1 / 14

S EMINAL : Searching for Type-Error Messages

S EMINAL : Searching for Type-Error Messages. Benjamin Lerner, Dan Grossman, Craig Chambers University of Washington. # let map2 f aList bList = List.map (fun (a, b) -> f a b) (List.combine aList bList);;

charleen
Download Presentation

S EMINAL : Searching for Type-Error Messages

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. SEMINAL: Searching for Type-Error Messages Benjamin Lerner, Dan Grossman, Craig Chambers University of Washington

  2. # let map2 f aList bList = List.map (fun (a, b) -> f a b) (List.combine aList bList);; val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list = <fun> # map2 (fun (x, y) -> x + y) [1;2;3] [4;5;6];; This expression has type int but is here used with type 'a -> 'b Try replacing fun (x, y) -> x + y with fun x y -> x + y Example: ML Curried functions

  3. template <class A, class B> list<B> map(B (*f)(A), list<A> aList); template <class A> list<list<A> > transpose( list<list<A> > aMatrix); map(ptr_fun(transpose<int>), myIntMatrixList); temp.cpp:42: error: no matching function for call to map(std::pointer_to_unary_function<std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >, std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > > >, std::list<std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >, std::allocator<std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > > > >&) Try replacing ptr_fun(transpose<int>) with &(transpose<int>) Example: C++ Template Usage temp.cpp:42: error: No match for map( pointer_to_unary_function<list<list<int> >, list<list<int> > >, list<list<list<int> > > &)

  4. What went right? • Easy polymorphic functions • map2 works for any kind of list • transpose works for any kind of matrix • Type inference • Writing types manually is tedious • Type-inference makes generic programming easier • …Even more powerful type-systems need type inference even more.

  5. What went wrong? These type-error messages… • …are not local (particularly ML) • Symptoms <> Problems • …are not intuitive (particularly C++) • Very lengthy types are hard to read • …are not descriptive • Location + types <> Solution • …are due to type inference/instantiation

  6. Related work • Instrument the type-checker, making its messages more informative • But that leads to tight coupling • Implementing a TC is easy • Implementing a production TC is hard • Adding good error messages makes it even harder • Interferes with easy revision or extension of TC • Error messages in TC adds to compiler’s trusted computing base See paper for citations

  7. Our Approach, in one slide • Treats type checker as oracle • Makes no assumptions about the type system • Note: no dependence on how TC works • Tries many variations on program, see which ones work • Must do this carefully – there are too many! • Note: “Variant works” <> “Variant is right” • Ranks successful suggestions, presents results to programmer

  8. Architecture

  9. Architecture – Searcher Defines the strategy for looking for fixes: • Look for single AST subtree to remove that will make problem “go away” • Replace subtree with “wildcards”  • Interesting subtrees guide the search • If removing a subtree worked, try its children … • Often improves on existing messages’ locations • Rely on Enumerator’s suggestions for more detail

  10. Architecture – Enumerator Defines the fixes to be tried: • Try custom attempts for each type of AST node • E.g. Function applications break differently than if-then expressions • Enumeration is term-directed • A function of AST nodes only • More enumerated attempts  better messages • Called by Searcher when needed

  11. Architecture – Ranker Defines the relative merit of successful fixes: • Search can produce too many results • Not all results are helpful to user • E.g. “Replace whole program with ”! • Use heuristics to filter and sort messages • “Smallest fixes are best” • “Currying a function is better than deleting it” • Simple heuristics seem sufficient

  12. Preliminary results • ML prototype: on ocaml-3.08.4 • Mostly complete • C++ prototype: on Eclipse 3.2, CDT 3.1, gcc 3.4.4 • Active work • Ongoing analysis of ~2K ML files collected from students • Group messages as “good”, “misleading”, “bad” • Check if message precisely locates problem • Check if message approximates student’s actual fix • Results: • Very good precision on small test cases • Good precision on real, large problems • Most poor results stem from common cause

  13. Errors may be widely separated Least common parent is too big Idea: ignore most code, focus on one error Triage:Trade “complete”for “small” Dealing with multiple errors

  14. Conclusions • Searching for repairs yields intuitively helpful messages • SEMINAL decouples type-checker from error-message generator • Simpler TC architecture • Smaller trusted computing base • It’s a win-win scenario!

More Related