1 / 27

Cayenne: A language with dependent types

Cayenne: A language with dependent types. Lennart Augustsson Presenter: Umut Acar. Cayenne (Hot Stuff!). Haskell-like language with dependent types Haskell is non-strict (lazy), declarative Types are first class Records can have types as their components Dependent types:

kris
Download Presentation

Cayenne: A language with dependent types

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. Cayenne: A language with dependent types Lennart Augustsson Presenter: Umut Acar

  2. Cayenne (Hot Stuff!) • Haskell-like language with dependent types • Haskell is non-strict (lazy), declarative • Types are first class • Records can have types as their components • Dependent types: • The type of a function can depend on the argument value, • \x -> if (x>2) then 1 else true • A record component can depend on some other component • Records can be used as signatures and structures • Big win over Haskell---Haskell support for modules is no good • Big win over SML---no need for a module language Type Refinements for Programming Languages

  3. The downside • Type checking of Cayenne is undecidable! Type Refinements for Programming Languages

  4. Writing printf in Cayenne • Type of printf depends on its first parameter, format string • printf (“Hello world\n”) • printf :: String -> Int • printf (“Number = %d\n”, n) • printf: String * Int -> Int • How can we even write the type for printf? Type Refinements for Programming Languages

  5. Can Compute type of printf • printf::(fmt::string) ->(PrintfType fmt) • printf (“%s = %d”, “five”,5) :: string -> string -> int -> int • We can “construct” types: types are expressions! PrintfType :: String ! # PrintfType (Nil) = String PrintfType ('%':'d':cs) = Int -> PrintfType cs PrintfType ('%':'s':cs) = String -> PrintfType cs ... PrintfType ('%':_:cs) = PrintfType cs PrintfType (_:cs) = PrintfType cs Type Refinements for Programming Languages

  6. The Code for printf • printf calls pr which returns the appropriate function depending on the format string printf::(fmt::String) -> PrintfType fmt printf fmt = pr fmt “” where pr “” res = res pr (‘%’:’d’: cs) res = \i -> pr cs (show (i) ++ res) .... Type Refinements for Programming Languages

  7. Records • Record types start with the keyword sig • Record values start with the keywors struct • Example: type person = sig age::int salary::int address::string poorJoe::person = struct age = 25 salary = 20000 address = “254 Joesplace Street” Type Refinements for Programming Languages

  8. Modules with records, signatures • Record types correspond to signatures of SML • Example: An integer set type IntSet = sig type T empty :: T singleton :: Int -> T union :: T -> T -> T member :: Int -> T -> Bool Type Refinements for Programming Languages

  9. Modules with records, structures • Use records for structures of ML • Example: An integer set listSet::IntSet listSet = struct type t = Int List empty = [] singleton i = [i] union a b = a @ b member i a = foldr (\x -> x=i) a False unionFindSet::IntSet unionFindSet = struct .... Type Refinements for Programming Languages

  10. Modules are first class values • Can pick an implementation for IntSet at run time intset = if (input size > 30) then listSet else unionFindSet ... s1 = intset.singleton 1 s2 = intset.singleton 2 s12 = intset.union s1 s2 Type Refinements for Programming Languages

  11. The Core Cayenne Language expr :: = (varid :: type) -> expr -- fun type \(varid :: type) -> expr -- lambda expr expr -- application data {conid { type } | } -- sum type conid@type -- constructor case varid of { arm } :: type -- case analysis sig { sign } -- signatures struct {defn} -- structures expr . lblid -- record selection varid -- variable #_1; #_2,... -- type of types arm ::= (condid {varid}) -> expr; varid -> expr sign ::= lblid :: type; lblid :: type = expr defn ::= vis lblid :: type = expr; vis ::= private | public abs abs ::= abstract |concrete types ::= expr Type Refinements for Programming Languages

  12. The Core Language • Core Cayenne language has three type forming constructs • Dependent functions • Data types (sums) • Dependent records (products) • No syntactic distinction between expression and types • type ::= expr Type Refinements for Programming Languages

  13. The Core Language: dependent functions • Functions and application are defined as • Note the occurrence of a variable in a function type • printf :: (fmt::string) -> PrintfType fmt expr ::= (varid :: type) -> expr -- fun type \(varid :: type) -> expr -- lambda expr expr -- application Type Refinements for Programming Languages

  14. The Core Language: sum types • Sum types are mostly standard except • Constructor names need not be unique accross different types • Therefore we need a type signature for constructors, i.e., @ expr ::= data {conid { type } | } -- sum type conid@type -- constructor case varid of { arm } :: type -- case analysis arm ::= (condid {varid}) -> expr varid -> expr Type Refinements for Programming Languages

  15. Example: Sum Types • The type for case expression must be specified • In general, it is not possible to find the type of a case Bool = data False | True -- define booleans case l of (Nil) -> True (Cons h t) -> False :: Bool case l of (Nil) -> 1 (Cons h t) -> “Hello” :: (case l of True -> Int False -> String) Type Refinements for Programming Languages

  16. The Core Language: records • Records are enriched to support modules • Record types are signatures, values are structures • Signatures can contain translucent sums • Structures have private or public abstract/concrete members expr :: = sig { sign } -- signatures struct {defn} -- structures expr . lblid -- record selection sign ::= lblid :: type lblid :: type = expr -- translucent sums defn ::= vis lblid :: type = expr vis ::= private | public abs abs ::= abstract |concrete Type Refinements for Programming Languages

  17. A simple record example • The visibility keywords determine the signature of a structure struct private x :: Int = 1 public abstract y :: Int = x+1 public concrete z :: Int = x+2 :: sig y :: Int z :: Int = 3 --translucent sums Type Refinements for Programming Languages

  18. Modules with records • Modules are units of compilation • They are records with syntactic sugar • Module names reside in the global name space • Module names are distinguished by a $ in their name Type Refinements for Programming Languages

  19. Example: A tree module module $tree = struct concrete data Tree a = Leaf | Node (Tree a) a (Tree a) abstract depth :: (a :: #) |-> Tree -> Int depth (Leaf) = 0 depth (Node l _ r)= 1 + depth l ‘max’ depth r Type Refinements for Programming Languages

  20. The signature for the tree module • Exposes the types and values of all concrete constructors sig -- Tree is a type constructor Tree :: # -> # = data Leaf | Node (Tree a) a (Tree a) Leaf :: (a ::#) |-> Tree a = \a::#) |-> Leaf@(Tree a) Node :: (a::#) |-> Tree a -> a -> Tree a -> Tree a = \(a ::#) |-> \(l::Tree a) -> \(x::a) -> \(r:: Tree a) -> Node@(Tree a) l x y depth :: (a :: #) |-> Tree a -> Int Type Refinements for Programming Languages

  21. Typing Rules: Dependent Function Types Type Refinements for Programming Languages

  22. Typing Rules: Lambda and Application Type Refinements for Programming Languages

  23. Typing Rules: Sum Types Type Refinements for Programming Languages

  24. Typing Rules: Product Types, signatures Type Refinements for Programming Languages

  25. Typing Rules: Products, structures Type Refinements for Programming Languages

  26. Erasing Types • No run-time decision can be made based on the value of a (type) expression • No such (casetype e of Int -> ....) • Types can be erased • the author argues that no type information need to be maintained at run time • Cardelli conjectures that, with dependent types, types will be needed at run time[Cardelli, Phase Distinction] Type Refinements for Programming Languages

  27. The state of Cayenne • Has a prototype implementation and has been tested on a few thousands of lines of code • Test programs included Haskell programs and programs with dependent types, and proofs of mathematical propositions • Works remarkably well on these programs • The author does not explicitly claim that undecidability is not a problem in practice Type Refinements for Programming Languages

More Related