Microsoft Research September 2015 GHC 710 27 March 2015 GHC 710 Partial type signatures Thomas Winant et al API annotations Alan Zimmerman the ability to know exactly where every nonterminal in the original source text appears ID: 743348
Download Presentation The PPT/PDF document "GHC status report Simon Peyton Jones" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
GHC status report
Simon Peyton Jones
Microsoft Research
September
2015Slide2
GHC 7.10(27 March 2015)Slide3
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 -> aSlide4
GHC 7.10
Preliminary support for Cloud Haskell 'static'
Plugin API for a SMT solver in the type inference engine (
Iavor Diatchki, experimental)Slide5
Coming in GHC 8.0(early 2016)Slide6
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)Slide7
On the way for GHC 8.0Strict
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 representationsSlide8
On the way for GHC 8.0MonadFailDWARF-based stack
backtraces
(Peter Wortman
n)
A Shake-based build system (Andrey Mokhov)
Backpack... (Edward Yang)Slide9
Implicit locationsSlide10
Implicit locations
But who called 'head'???????
head :: [a] -> a
head (
x:xs
) = x
head [] = error "head of empty list"
ghci
>
complicated_function
89
*** Exception:
head of empty listSlide11
Homebrew solution
Change in head's type signature
Every call site must be changed to pass an informative string
head :: String -> [a] -> a
head _ (
x:xs
) = x
head info [] = error ("head of empty list"
++ info)
foogle
x y z = ....(head "In
foogle
"
ts
)....Slide12
Implicit locations
Better, but what if you don't know where '
foogle
' was called?
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
head :: (?
cs
::
CallStack
) =>
[a] -> a
head (
x:xs
) = x
head [] = error ("head of empty list\n"
++
showCallStack
?
cs
)
foogle
x y z = ....(head
ts
)....Slide13
Implicit locations
Re-uses existing notation
Easy to implement: the constraint solver is the only bit that changes
Zero impact on transformation, optimisation, code generation,
etc
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)....Slide14
Overloaded record fieldsSlide15
Overloaded record fieldsDecent 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 labelsRecord classes for overloadingOverloaded labels for convenienceSlide16
1. Duplicate fields
Record construction and pattern matching are unaffected
Duplicated record selectors are ambiguous; but NB selective import
data T =
MkT
{ x, y ::
Int
}
data S =
MkS
{ x :: Bool, z ::
Int
}
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 rSlide17
2. Record class
Every field gives rise to a new instance
Now selection is overloaded:
class
HasField
(x :: Symbol) r
where
type
FieldType
x r
getField
:: Proxy# x -> r ->
FieldType
x r
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 recordSlide18
3. Overloaded Labels
Syntax "#x" expands to (
fromLabel
@ "x" @t)
So (#x r) would expand (via the instance) to
getField (Proxy :: Proxy "x")just as we wantBut the instance is library code; we can change it if we want #x to mean a lens
class
IsLabel
(x :: Symbol) a
where
fromLabel
:: a
instance (
HasField
x r, a ~
FieldType
x r)
=>
IsLabel
x (r -> a)
where
fromLabel
=
getField
(Proxy :: Proxy
x
)Slide19
Typed reflectionSlide20
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)Slide21
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)Slide22
Type indexed type representations
And yet, comparing
TypeReps
should
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
=
unsafeCoerce
x
| otherwise = Nothing where
trr
=
typeRep
(Proxy :: Proxy a)Slide23
New story
Now, comparing
TypeReps
does
tell us something!class
Typeable
a where
typeRep
::
TypeRep
a
eqT
::
TypeRep
a ->
TypeRep
b -> Maybe (a :~: b)
data a :~: b where
Refl
:: a :~: aSlide24
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
eqT
trx
(
typeRep ::
TypeRep
a) of
Just
Refl
-> Just x
Nothing -> NothingSlide25
New story
From
TypeRep
to (
TypeRep
a) allows us to do type-safe reflectionUseful for Cloud Haskell style applicationsSmaller trusted code base. I think GHC implementors only, rather than library authorsInterestingly, it turns out to need Richard Eisenberg's kind-level equalities!Slide26
The GHC communitySlide27
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 executionThis 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
Major role
Not so much
doing
, but
enabling others to do
Trac
tickets
over 10,000Slide28
What does that mean?
Bottom line
GHC and
(especially) its ecosystem
(cabal,
Hackage
, Haskell Platform...)
badly need your helpSlide29
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...Slide30
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 ...