300 likes | 535 Views
GHC status report. Simon Peyton Jones Microsoft Research September 2015. GHC 7.10 (27 March 2015). GHC 7.10. Partial type signatures (Thomas Winant et al) API annotations (Alan Zimmerman): the ability to know exactly where every non-terminal in the original source text appears
E N D
GHC status report Simon Peyton Jones Microsoft Research September 2015
GHC 7.10 • Partial type signatures (Thomas Winant et al) • API annotations (Alan Zimmerman): the ability to know exactly where every non-terminal in the original source text appears • Applicative as a superclass of Monad (finally) • More robust GMP hook-up (Herbert Valerio Riedel) f :: _ -> Int -> [ _ ] g :: (_) => a -> a
GHC 7.10 • Preliminary support for Cloud Haskell 'static' • Plugin API for a SMT solver in the type inference engine (Iavor Diatchki, experimental)
On the way for GHC 8.0(early 2016) • GADT-aware pattern-match overlap/exhaustiveness warnings (George Karachalias, Tom Schrjvers et al; see our ICFP paper) • Injective type families (Jan Stolarek; see our HS paper) • Applicative do-notation (Simon Marlow) • Implicit-parameter support for call stacks (Eric Seidel et al)
On the way for GHC 8.0 • Strict Haskell (Johan Tibbell and Adam Sandberg Eriksson) • Overloaded record fields (Adam Gundry) • Kind equalities, and GADTs at the type level (Richard Eisenberg and Stephanie Weirich) • Visible type application (Stephanie Weirich, Richard Eisenberg) • Type-indexed type representations
On the way for GHC 8.0 • MonadFail • DWARF-based stack backtraces (Peter Wortmann) • A Shake-based build system (Andrey Mokhov) • Backpack... (Edward Yang)
Implicit locations head :: [a] -> a head (x:xs) = x head [] = error "head of empty list" • But who called 'head'??????? ghci> complicated_function 89 *** Exception: head of empty list
Homebrew solution head :: String -> [a] -> a head _ (x:xs) = x head info [] = error ("head of empty list" ++ info) • Change in head's type signature • Every call site must be changed to pass an informative string foogle x y z = ....(head "In foogle" ts)....
Implicit locations head :: (?cs:: CallStack) => [a] -> a head (x:xs) = x head [] = error ("head of empty list\n" ++ showCallStack ?cs) • Better, but what if you don't know where 'foogle' was called? foogle x y z = ....(head ts).... ghci> complicated_function 89 *** Exception: Head of empty list ?cs, called at Foo.hs:8:60 in main:Foo head, called at Foo.hs:10:9 in main:Foo
Implicit locations head :: (?cs:: CallStack) => [a] -> a head (x:xs) = x head [] = error ("head of empty list\n" ++ showCallStack ?cs) foogle :: (?cs :: CallStack) => Int -> Int foogle x = ....(head e).... • Re-uses existing notation • Easy to implement: the constraint solver is the only bit that changes • Zero impact on transformation, optimisation, code generation, etc
Overloaded record fields • Decent records are probably GHC's longest-asked-for feature • It's a swamp: many designs, all with complex tradeoffs. • We have finally plumped for a simple, modular design, with three pieces: • Allow duplicate field labels • Record classes for overloading • Overloaded labels for convenience
1. Duplicate fields data T = MkT { x, y :: Int } data S = MkS { x :: Bool, z :: Int } • Record construction and pattern matching are unaffected • Duplicated record selectors are ambiguous; but NB selective import f :: S -> T f (MkS { x = v } = MkS { x = True, y = v } module A where import M( T(MkT, x, y) ) -- But not S f r = x r + y r
2. Record class class HasField (x :: Symbol) r where type FieldType x r getField:: Proxy# x -> r -> FieldType x r • Every field gives rise to a new instance • Now selection is overloaded: instance HasField "x" T where type FieldType"x" T = Int getField (MkT { x = v }) = v f :: T -> Int f r = getField (Proxy :: Proxy "x") r + 1 -- Gets field "x" from a T record
3. Overloaded Labels class IsLabel (x :: Symbol) a where fromLabel:: a • Syntax "#x" expands to (fromLabel @ "x" @t) • So (#x r) would expand (via the instance) togetField (Proxy :: Proxy "x")just as we want • But the instance is library code; we can change it if we want #x to mean a lens instance (HasField x r, a ~ FieldType x r) => IsLabel x (r -> a) where fromLabel = getField(Proxy :: Proxy x)
Type indexed type representations class Typeable a where typeRep :: Proxy a -> TypeRep data Dynamic where Dynamic :: TypeRep -> a -> Dynamic toDyn :: forall a. Typeable a => a -> Dynamic toDyn x = Dynamic trep x where trep :: TypeRep trep = typeRep (Proxy :: Proxy a)
Type indexed type representations • Does not typecheck because (trx == trr) tells the type system nothing data Dynamic where Dynamic :: TypeRep -> a -> Dynamic fromDynamic :: forall a. Typeable a => Dynamic -> Maybe a fromDynamic (Dynamic trx x) | trx == trr = x | otherwise = Nothing where trr = typeRep (Proxy :: Proxy a)
Type indexed type representations • And yet, comparing TypeRepsshould tell us something! After all, they were built by the compiler! data Dynamic where Dynamic :: TypeRep -> a -> Dynamic fromDynamic :: forall a. Typeable a => Dynamic -> Maybe a fromDynamic (Dynamic trx x) | trx == trr = unsafeCoercex | otherwise = Nothing where trr = typeRep (Proxy :: Proxy a)
New story class Typeable a where typeRep :: TypeRep a eqT :: TypeRep a -> TypeRep b -> Maybe (a :~: b) data a :~: b where Refl :: a :~: a • Now, comparing TypeRepsdoes tell us something!
New story data Dynamic where Dynamic :: TypeRep a -> a -> Dynamic eqT :: TypeRep a -> TypeRep b -> Maybe (a :~: b) fromDynamic :: forall a. Typeable a => Dynamic -> Maybe a fromDynamic(Dynamic trx x) = case eqTtrx (typeRep :: TypeRep a) of Just Refl -> Just x Nothing -> Nothing
New story • From TypeRep to (TypeRep a) allows us to do type-safe reflection • Useful for Cloud Haskell style applications • Smaller trusted code base. I think GHC implementors only, rather than library authors • Interestingly, it turns out to need Richard Eisenberg's kind-level equalities!
What does that mean? • GHC is flourishing • lots of users • lots of innovation • lots of contributors • GHC is more and more a community project, both in leadership and execution • This is not a bad thing. But it relies on people actually stepping up. Introducing the new Well Typed GHC support team: • Austin Seipp • Ban Gamari Trac tickets over 10,000 Major role Not so much doing, but enabling others to do
What does that mean? Bottom line GHC and(especially) its ecosystem (cabal, Hackage, Haskell Platform...) badly need your help
GHC has a huge surface area • type system • optimisation • code generation for many platforms • SIMD instructions • dynamic linking • GHCi • the GHC API • plugins • FFI • concurrency, STM • Cloud Haskell • the build system • packages • garbage collection, finalisers • run-time system, scheduling • profiling • ....and more...
Things that need doing • Profiling and debugging • Connection between profiler output and -ddump-simpl for auto-generated SCCs. Use DWARF annotations? (Norman) • Sample-based profiling. DWARF will give this. (Lennart) • Free stack traces: always on. DWARF will give this. (Johan) • Core-to-Core API is hard to use (tall guy, glasses, black hair) • Inlining reporting (John Wigely) • Show instances for GHC internals (Johan) • Code generation something ...