Over the last few weeks, there have been some changes to Epigram that make programming in the command-line interface slightly more pleasant. We are starting to think about a high-level language, but in the meantime, I thought it would be nice to look at what sort of programming is possible today. None of this is revolutionary or indeed particularly exciting, but it should make the exciting stuff easier to write. This post would be literate Epigram if there was such a thing; as there isn’t, you will have to copy code lines one at a time into Pig if you want to follow along.
The Art of the Possible
August 20th, 2010No Representation without Taxation
May 31st, 2010I think we’re at a point where we need to question our term/value representation technology. That’s not to say we need to change it, but we should look at where things are getting a bit out of hand and ask if there’s anything we can do. The system is not so large that…actually, it’s small. However, before we do anything foolish, I thought I’d try to remember where we’ve been and why. Please join in. We need to figure out what breaks what. Most representation choices have pros and cons (a few just have cons).
Where are we at the moment? Read the rest of this entry »
The Battered Ornaments
May 24th, 2010Here’s a story I’ve had on the go for a while.
It’s an experiment in managing the multitudinous variations on the theme of a datatype, inspired by this overlay from a talk I gave ten years ago. If you squint hard at it, you can see that it shows the difference between lists and vectors. Let’s see how to formalize that notion as a big pile of Agda. The plan, of course, is to do something very like this for real on Epigram’s built in universe of datatypes.
I’ll need some bits and bobs like Sigma-types (Sg). Step one. Build yourself a little language describing indexed functors.
Descriptions
data Desc (I : Set) : Set1 where
say : I -> Desc I
sg : (S : Set)(D : S -> Desc I) -> Desc I
ask_*_ : I -> Desc I -> Desc I
What do these things mean?
[_] : forall {I} -> Desc I -> (I -> Set) -> (I -> Set)
[ say i' ] X i = i' == i
[ sg S D ] X i = Sg S \ s -> [ D s ] X i
[ ask i' * D ] X i = X i' * [ D ] X i
Here, [ D ] X i is the set of D-described data which say they have index i; everywhere the description asks for some index i’, the corresponding set has an X i’. Meanwhile sg just codes for ordinary Sg-types, allowing nodes of datatypes to be built like dependent records. The X marks the spot for recursive data. Our next move is to take a fixpoint.
data Data {I : Set}(D : Desc I)(i : I) : Set where
<_> : [ D ] (Data D) i -> Data D i
I guess I’d better give you an example. Read the rest of this entry »
EPIG, a journey in Quotation
May 10th, 2010In this post, I talk about the computation of normal forms in Epigram. Quotation is a key step of normalization, doing some rather exciting magic.
Setting the scene
This post tells a story about terms. We shall discover that some classes of term are more desirable than others. Let us have a look at the battlefield. We define 3 classes of terms, gently sketched by Bosch:
A bit of infrastructure
April 24th, 2010I thought I would write a line or two about some recently acquired infrastructure.
Weeks ago, we had left our ivory tower, or rather, our beloved Livingstone tower for a gig in Oxford. Lot of fun, lot of adjunctions. But also a surprising discovery: we met some people who had pulled Epigram source code and actually looked at it. I mean, I might have pulled the code once or twice in the past, to impress girls in a Pub. But reading it…
Worse, we actually got our first bug report! Andrea Vezzosi, as a modern Dante Alighieri, braved the Inferno of She-ism (translates to “shitism” in Italian for some reason) and somehow went through the Purgatorio of Epigram’s syntax (honestly, I have no clue how he did that). Once there, Paradiso was at hand. But these damned labels were preventing the magic from happening! No mailing list, no bug tracker: no hope.
Around the same time, our counter-intelligence team reported that several Epigram agents under cover in Sweden had been busted and exposed to bursts of .45mm questions.
All in all, we came to the conclusion that, out there, there are people working harder on Epigram than we do. So, here is the kit for you to become an Epigram implementor:
- A mailing list!
- A bug tracker!
- An IRC channel, #epigram on Freenode
If you don’t feel like becoming a modern hero (tough job, indeed), you are also welcome to come on board and have a chat with the captain.
I’m putting a rough skeleton of my PhD thesis in the repository. I’m off to Honolulu, will be back in 3 years. Keep up the good work folks!
Prop?
April 18th, 2010Let me try to make a bit of high-level sense about Prop in Epigram 2. It’s quite different from Prop in Coq, it does a different job, and it sits in quite a delicate niche.
Firstly, Prop is explicitly a subuniverse of Set. If P is a Prop, then :- P is the set of its proofs, but P itself is not a type. (Are propositions types? How, functionally, should the Curry-Howard “isomorphism” be manifest?) Note that :- is a canonical set constructor; it is preserved by computation. Hence you know a proof set when you see one.
Secondly, we squash proof sets. All inhabitants of proof sets are considered equal, definitionally. We have that :- P ∋ p ≡ p’, and we can easily see when this rule applies, just because :- is canonical. Contrast this with Coq, where Prop is silently embedded in Type: that makes it harder to spot opportunities to squash proofs.
And that’s kind of it. Prop is a subuniverse of Set that’s safe to squash, even when computing with open terms. There’s nothing we do with Prop that we couldn’t do more clunkily in Set. It is, in effect, an optimization. However, the pragmatic impact of this optimization is considerable. More on what we’ve bought in a bit; let’s check that we can afford it.
Read the rest of this entry »
Coinduction, observationally
March 22nd, 2010I thought I might report a bit about what I’ve been up to with coinduction. Headline: we can set up propositional equality so that every coprogram equals its unfolding, even though that had jolly well better not hold definitionally if we want decidable anything.
What I’ve got is an Agda universe with inductive and coinductive Petersson-Synek trees (also known as Hancock-Setzer interaction structures). Actually, it’s a pair of universes—PROP and SET. Equality is a proposition computed recursively over the structure of sets and elements.
Read the rest of this entry »
W-types: good news and bad news
March 7th, 2010I thought I’d just collect together some disparate observations about W-types, and their use in encoding other recursive datatypes. My motivation, bluntly, is to point out the inevitable unsuitability of W-types as the basis for recursive datatypes in an implementation of decidable type theories. I don’t want to downplay the conceptual importance of W-types as a uniform basis for recursive structures in an extensional setting. I’m just saying that computers aren’t clever enough to cope all that well with W-type encodings: if we want to make our understanding go, we need to refine it. This is a long post, so if you want the bad news first, skip to the end.
What are W-types?
Martin-Löf identified a general notion of well-ordering — data with a well-founded notion of ‘structurally smaller’. The power of dependent types enabled him to express this parametrically, once for all, rather than by fiddling about with syntactic criteria for acceptable recursive definitions. Here goes (informal notation)
W (S : Set) (P : S → Set) : Set
(s : S) ⊲ (f : P s → W S P) : W S P
Read the rest of this entry »
Quotients
February 8th, 2010I’ve had an enquiry for more details on quotients in the new Epigram setup, so I’ll take that as a cue to blog a bit.
First, I’d better sketch some basics about propositions and equality. It’s the novel treatment of these things which lets us handle quotients in (hopefully) a neater way than has been possible thus far in a decidable type theory. The headlines:
- quotients given by a ‘carrier’ set, equivalence relation
- definitional equality on equivalence classes inherited from carrier on representatives
- propositional equality on equivalence classes is equivalence of representatives
- propositional equality is substitutive
The tabloid headline is STUFF YOUR SETOIDS.
Read the rest of this entry »
EE-PigWeek 4-9 Jan 2010
January 13th, 2010A big thanks to James Chapman for organising EE-PigWeek at the Institute of Cybernetics, Tallinn, Estonia. This time around, the crew comprised Brady, Chapman, Dagand, Gundry, McBride, Morris, and Norell. We started the week with an experimental system which did almost nothing. We finished the week with an experimental system which almost does something.
I’ll go into more details later, but this post is a quick summary of the equipment we’re on track with. All of this stuff would benefit from more careful pedagogy, one topic at a time. I’m thinking of the following list as a bunch of placeholders to be fleshed out in future, preferably once the technologies have paid off enough to sustain some useful examples.
Read the rest of this entry »
Bidirectional Basics
January 3rd, 2010I thought I’d start writing a thing or two about the setup for the incarnation of Epigram we’re currently working on. At the heart of the thing is a Language Of Verifiable Evidence, which is all you need, really. You can stick a fancy syntax and lots of abbreviation mechanisms on top of it, and you can glue lots of erasure mechanisms and a compiler to the bottom of it, but in the middle, there’s this language whose (open) terms you can typecheck and evaluate, without any need for further elaboration, wishful thinking, or appeal to oracle. Is this a core language? I don’t know: that phrase has been used in so many ways.
The setup of this language is obsessively bidirectional, to the point of separating the syntactic categories for which types get pushed in and from which types are extracted.
Pushing types in: TYPE ∋ INTM
Extracting types: EXTM ∈ TYPE
Read the rest of this entry »
Epic
December 18th, 2009I’ve just uploaded a new version of Epic to hackage, so installing it should now be a matter of typing:
cabal install epic.
You will also need the Boehm garbage collector, available from here. If you’re on a Mac, installing it should require nothing more than:
port install boehmgc
Also, if you’re on a Mac, you will probably have to persuade gcc to look in the right place for the relevant libraries. I have the following lines in my .profile which do the trick:
export C_INCLUDE_PATH=/opt/local/include:$C_INCLUDE_PATH export CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH export LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH export LIBRARY_PATH=/opt/local/lib:$LIBRARY_PATH
To check if everything has worked, put the following text into a file called hello.e:
main () -> Unit =
foreign Unit "putStr" ("Hello world!\n":String)
Then execute epic hello.e -o hello, and you should have an executable hello world program.
2+2=4
December 16th, 2009This may not seem startling, and it isn’t. It’s the first thing we check when we have a system that’s beginning to work. Today, we constructed + for the natural numbers by appeal to the generic elimination operator. Then we applied this + to two and two. Then we compiled the resulting definition to a standalone executable. Then we ran that executable. It printed four (in a suitable encoding). Dr Brady has been visiting, which helps with this sort of shenanigans.
When I say “the generic elimination operator”, I don’t mean the elimination operator for the natural numbers. I mean the generic elimination operator for all inductive datatypes, applied to the piece of data which describes the natural numbers. This version of Epigram has datatype-generic programming built in. So what we’ve really been doing is thrashing that datatype encoding mechanism. It seems to be working, so I’d better change it.
The long dark is ending. We’ve been hacking up bits of kit for ages, but we now have an end-to-end system: construction commands go in; compiled code comes out. Time to chuck in functionality and get playing!
Autumn Leaves
December 6th, 2009I thought I’d scribble something about what we’re up to. The team (Pierre-Évariste Dagand, Adam Gundry, Peter Morris, James Chapman) have been hard at work. I have been otherwise engaged. As a result, there has been considerable progress. Don’t worry. I expect I’ll mess things up properly over Christmas.
We’ve decided that the best way to get our new type theory out there for you to play with, sooner rather than later, is not to wrap it up in a new version of the Epigram language, but rather to present it as is, in a low-budget command-driven interactive proof assistant. This is beginning to materialise.
One of the good things about having new people in the team is that they’ve had to learn about how we get this stuff to work, and they’ve been writing down what they’re learning in the Epitome. Literate Programming Considered Essential. We’re not trying to take over the world: we’re just trying to make stuff worth stealing. That’s an unusual optimisation problem.
So, the rumours of our death have been slightly exaggerated. My plan is to continue staying out of the way of the coders and write more articles about How It All Works. We’re plotting a bit of a New Year hacking hooley in Tallinn (Glasgow isn’t cold enough). There might be a thing that does something a bit after that.
I’m hoping that this blog will wire up to the new repo real soon, so that you can peer on in. Afore I go, though, let me remark on the importance of Haskell as an enabling technology. Our engineering philosophy is do it once: we prefer to write one abstract piece of code which captures a concept than many concrete pieces of code which follow a pattern; without higher-kind types and classes, we’d be hosed. Given that our main implementation problem is (or rather, was) No Programmers, it is only because of Haskell that a thing exists at all.
PigWeek: Friday
July 25th, 2009Location: peripatetic. Exeunt: Peter and James. Brunch: Rio Café. Cake: The Liquid Ship. Enter: our web consultant.
Today, less hacking, more packing. Some plotting.
It’s been a good week. We have the infrastructure for the core theory, and we’re populating it with stuff. Peter is well on the way to the universe of containers: more on that in another post. James is getting in the zone with Observational Equality. Conor is trying to figure out how the elaboration monad comes together, and fixing She. Edwin has shown us how to communicate with his Epic compiler.
We’ll have a version of the core, its typechecker, and its compiler pretty soon, I think. The challenge now is to design the high-level source language. I can’t help feeling that we should think about effects sooner rather than later.
Pigweek: Thursday
July 24th, 2009Location: Livingston Tower – University of Strathclyde.
Clientele: Conor, Peter, James, Edwin.
Lunch: Oko.
Cake; Fifi and Ally’s.
Dinner: La Valleé Blanche.
Bit of propositional equality (James), bit of container technology (Peter) and some actual computation (Edwin). Conor continues to keep us well fed, well watered and well stocked with things to manufacture, he’s also keeping She in working order. The end of a productive week is drawing near. Edwin has gone back to St. Andrews, Peter and I are off tomorrow. It’s been good, hope to be back soon.
PigWeek: Wednesday
July 22nd, 2009Location: Conor’s Flat. Crew: Conor T. McBride, Peter W.J. Morris, James M. Chapman, Edwin C. Brady, joined for the afternoon by Nicolas P. Oury.
Lunch: Crabshakk
Cake: Kember and Jones
Dinner: Banana Leaf
Achievements: PWJM implemented a universe for containers, JMC worked on updating the proof state, ECB plugged his compiler in and learned his way around the source code, CTM successfully loaded and typechecked a term, while continuing to update She, and NPO got up to speed with the state of the system.
PigWeek: Tuesday
July 21st, 2009Location: Strathclyde Uni. Crew: C. McBride, P. Morris, J. Chapman and we welcomed the arrival of one E. Brady
Lunch: Peckham’s
Cake: Peckham’s
Dinner: we chopped, Mel cooked
Achievements: JC made a universe for propositions and PM one for finite enumerations; along the way they put together a setup for built-in operators. EB started to make his compiler do things in a more Pig-like way and CM built something that might load definitions into the system.
Tomorrow: The world.
PigWeek: Monday
July 21st, 2009Location: Conor’s flat. Crew: Conor McBride, James Chapman, Peter Morris. Lunch: Cafézique. Cake from: Delizique. Dinner: Banana Leaf, Home Wok, Oriental West, the chippy.
Freddie Flintoff helped us to a cracking start by skittling the Aussie tail end. James implemented the setup for untyped quotation (β-normal forms), typed quotation (η-long β-normal forms), definitional equality, and bidirectional type checking.
Peter Morris implemented the feature file for Sigma-types, contributing code fragments to several components via the aspect-oriented programming technology which she supports. He also sorted out our Makefile, so that code gets preprocessed in the right order.
She is getting quite a lot of challenging work, so I’m on running repairs, and other boring jobs.
Wrote a parser; implemented λ-calculus again
July 11th, 2009Here are terms and values, bidirectionally. Inevitably, I can’t decide what to call things and forgot what I did last time.
> data Dir = In | Ex
> data Phase = TT | VV
>
> data Tm :: {Dir, Phase} -> * -> * where
> L :: Scope p x -> Tm {In, p} x
> C :: Can (Tm {In, p} x) -> Tm {In, p} x
> N :: Tm {Ex, p} x -> Tm {In, p} x
> P :: x -> Tm {Ex, p} x
> V :: Int -> Tm {Ex, TT} x
> (:-) :: Tm {Ex, p} x -> Elim (Tm {In, p} x) -> Tm {Ex, p} x
> (:?) :: Tm {In, TT} x -> Tm {In, TT} x -> Tm {Ex, TT} x
>
> data Scope :: {Phase} -> * -> * where
> (:.) :: String -> Tm {In, TT} x -> Scope {TT} x
> H :: Env -> String -> Tm {In, TT} x -> Scope {VV} x
> K :: Tm {In, p} x -> Scope p x
>
> data Can :: * -> * where
> Set :: Can t
> Pi :: t -> t -> Can t
> deriving (Show, Eq)
>
> data Elim :: * -> * where
> A :: t -> Elim t
> deriving (Show, Eq)
And there’ll be more, no doubt. The parser is a bit scrappy.
The evaluator is idiombastic:
> ($-) :: VAL -> Elim VAL -> VAL
> L (K v) $- A _ = v
> L (H g _ t) $- A v = eval t (g :< v)
> N n $- e = N (n :- e)
> body :: Scope {TT} REF -> Env -> Scope {VV} REF
> body (K v) g = K (eval v g)
> body (x :. t) g = H g x t
> eval :: Tm {d, TT} REF -> Env -> VAL
> eval (L b) = (|L (body b)|)
> eval (C c) = (|C (eval ^$ c)|)
> eval (N n) = eval n
> eval (P x) = (|(pval x)|)
> eval (V i) = (!. i)
> eval (t :- e) = (|eval t $- (eval ^$ e)|)
> eval (t :? _) = eval t
where ^$ is a short infix name for traverse.