
Learn You an Agda - bkirwi
http://williamdemeo.github.io/2014/02/27/learn-you-an-agda/
======
pron
Languages that use types for elaborate proofs always seem to me like they only
prove the most uninteresting properties of programs, namely the parts that
deal with data transformations. Not that data transformations aren't
important, but the properties they need to preserve are usually easy to be
convinced of without any assistance by the compiler.

At the end of the day, programs are written for their side effects (unless
your program is a compiler, which is the classical example of an
"interesting", non-trivial data transformation, and possibly the only
example). What I'm most interested in is proofs that, say, in a concurrent
environment, a function that closes a socket will never be called as long as
there are pending tasks to write to the socket. Or, because I write concurrent
data structures, I'm interested to prove that a certain function will
eventually release all locks it acquires. Are there any such languages?

I've heard of effect systems, but I couldn't find enough information on them.
Are effect systems capable of the kind of proofs I'm interested in? Are there
practical programming languages with powerful effect systems?

EDIT: Some Googling yielded this: [http://lambda-the-
ultimate.org/node/4768](http://lambda-the-ultimate.org/node/4768) tldr: Not
yet.

EDIT: At least the lock proof seems to be implemented as one of Java 8's
pluggable type systems: [http://types.cs.washington.edu/checker-
framework/current/che...](http://types.cs.washington.edu/checker-
framework/current/checker-framework-manual.html#lock-checker)

It lets you add a type (Java 8's pluggable types are intersection types) to a
function called @EnsuresLockHeld(locks...) that proves some locks will be held
when a function returns and even @EnsuresLockHeldIf(locks..., result) that
proves a function grabs certain locks if its boolean result is equal to the
one specified in the type.

~~~
pseudonom-
It's not exactly what you're asking for but Ur/Web puts an expressive type
system to some slightly unusual ends:
[http://www.impredicative.com/ur/](http://www.impredicative.com/ur/).

~~~
kyllo
Whoa, this is pretty horrifying: app code, queries and markup all mixed
together, like typed-checked PHP. I know this is just a demo but "separation
of concerns" does not appear to have been a concern.

    
    
        fun list () =
                rows <- queryX (SELECT * FROM tab AS T)
                               (fn (fs : {T : $([Id = int] ++ map fst M.cols)}) => <xml>
                                 <tr>
                                   <td>{[fs.T.Id]}</td>
                                   {@mapX2 [fst] [colMeta] [tr]
                                     (fn [nm :: Name] [t ::_] [rest ::_] [[nm] ~ rest] v col => <xml>
                                       <td>{col.Show v}</td>
                                     </xml>)
                                     M.fl (fs.T -- #Id) M.cols}
                                   <td>
                                     <a link={upd fs.T.Id}>[Update]</a>
                                     <a link={confirm fs.T.Id}>[Delete]</a>
                                   </td>
                                 </tr>
                               </xml>);

------
digitalzombie
I really like these "learn you a" books.

I have no reason why but I just like the freaking pictures. It keeps me going.
It's like a children book but it also teaches me the subject I like,
programming languages.

~~~
wlesieutre
On top of the pictures, the examples are a lot more fun than foo and bar.
Here's (part of) how _Learn You a Haskell_ introduces map:

    
    
        ghci> map (++ "!") ["BIFF", "BANG", "POW"]
        ["BIFF!","BANG!","POW!"]

~~~
Dewie
I hate foo/bar for some reason. I think it's because it is supposed to be
"this is just whatever", and yet they force me to think about Kung Fu, the Foo
Fighters and crowbars.

~~~
carapace
You know it's an old military acronym, right? F.U.B.A.R. stands for eFfed Up
Beyond All Recognition. (And SNAFU is Situation Normal: All eFfed Up.) ;-)

------
lelf
I like to show you the immense beauty of the Agda standard library:
[http://agda.github.io/agda-
stdlib/html/README.html](http://agda.github.io/agda-stdlib/html/README.html)
(all clickable and…you'd better have proper unicode fonts).

~~~
mcbuilder
Even something as mundane as Data.Bool is beautiful, defining False in terms
of bottom.

I love to look at unicode, but is it a pain to type it in practice, even given
emacs?

~~~
tel
Note that `false` the value of type `Bool` is _not_ defined in terms of
bottom. It is a constant in its own right just like `nil` and `cons 1 nil`
are.

What happens in Data.Bool is that we have the function from values to types
`T` such that `T true` and `T false` are _types_ equal to top and bottom
respectively. This value-to-type encoding is called a "universe" and allows us
to talk about propositions which are based on boolean function results like

    
    
        theorem1 : T (1 - 1 == 0)
    

which is somewhat interestingly different from

    
    
        theorem2 : 1 - 1 = 0
    

in that the first will reflect upon the definitions of the (recursive)
functions (-) and (==) while the second reflects only upon the definition of
(-).

------
agumonkey
First time I read about 'mixfix' operators, one less thing I'll have to invent
I guess.
[https://www.google.fr/search?q=mixfix+notation](https://www.google.fr/search?q=mixfix+notation)

------
akkartik
It lost me at this point:

 _Type the following into an emacs buffer, and then type C-c C-l (use \\_1 to
type the subscript symbol ₁):_

    
    
      proof₁ : suc (suc (suc (suc zero))) even
      proof₁ = ?
    

On my newly created emacs setup from the earlier instructions, it's not clear
what "type into an emacs buffer" means. Do I create a new file with C-x C-f?
Create a new buffer with C-x b? I tried both, and promptly lost agda-mode.

I then tried restarting emacs and opening a new .agda file so I get agda mode.
Loaded the earlier module and then tried loading this, and it didn't seem to
know about _suc_ in the context of this buffer/file. So now I'm lost.

~~~
sjolsen
That should read, "Type the following into _the_ Emacs buffer." You should
have something like:

    
    
        module LearnYouAn where
        
          data ℕ : Set where
            zero : ℕ
            succ : ℕ → ℕ
        
          _+_ : ℕ → ℕ → ℕ
          zero + m = m
          (succ n) + m = succ (n + m)
        
          data _even : ℕ → Set where
            ZERO : zero even
            STEP : ∀ n → n even → succ (succ n) even
        
          proof₁ : succ (succ (succ (succ (zero)))) even
          proof₁ = ?

~~~
akkartik
Thanks! Can't believe I didn't think of that :/

What's the distinction between _C-c C-space_ and _C-c C-r_? It looks like the
former computes proof obligations for _?_ s, but what does the latter do? And
why couldn't we use the latter in the first instance, to deduce the outermost
_STEP ? ?_

 _Edit_ : never mind, that did work.

~~~
sjolsen
> What's the distinction between C-c C-space and C-c C-r?

Beats the hell out of me. Here's the docstring for agda2-give (bound to C-c
C-SPC):

    
    
        Give to the goal at point the expression in it
    

Here's the one for agda2-refine (C-c C-r):

    
    
        Refine the goal at point.
        If the goal contains an expression e, and some "suffix" of the
        type of e unifies with the goal type, then the goal is replaced
        by e applied to a suitable number of new goals.
        
        If the goal is empty, the goal type is a data type, and there is
        exactly one constructor which unifies with this type, then the
        goal is replaced by the constructor applied to a suitable number
        of new goals.

------
tomwilde
If I wrote a natural number calculator in Agda; would all my numbers be
represented as lists of successions from zero or can the compiler convert them
to two's-complement integers as we know and love them?

In case the compiler can do that conversion: is it is programmed to do that
for some subset of numeric types or can it infer an optimal binary
representation of a value somehow?

On the other hand, if they really were represented as lists then I presume
this language is intended as purely academic work and has no application in a
production environment. Am I wrong?

~~~
Dewie
It's a proof assistant. Not really something you use for number crunching,
industry or not.

~~~
eli_gottlieb
But a proof assistant for numerical programming would be _extremely_ useful.

------
gosub

        If we can construct a value of a certain type, we have simultaneously constructed a proof that the theorem encoded by that type holds.
    
        data _even : ℕ → Set where
    

I do not understand how to interpret this passage. _ even, given a number,
returns a type? in this case, zero even is a type, but we have not created any
value with that type. What am I missing?

~~~
tel
That's exactly correct.

In a Dependently Typed (DT) language like Agda the language of values and the
language of types are one and the same. Thus, a function from types to types
is exactly the same sort of thing as a function from values to values. In this
case we have a third sort of totally-natural-day-old-kind-of-thing: a function
from values of ℕ to types (in Set). It's "just" a function from values to
types.

Now, we annotate values with their types. Thus we might have a new top-level
definition

    
    
        something : zero even
        something = _
    

where we've used our postfix `even` function to construct a type from the
value `zero`. Is this type inhabited? That's a question of proof and
programming. Regardless of its inhabitation, though, we can clearly see that
the notion of `zero even` simply _being_ a type is sound---that's the nature
of function application when the target domain is that of Set!

------
mjfl
Recently learned this language in a functional programming course. Very cool
language. The Curry-Howard Isomorphism proves that programming languages are
equivalent to mathematical proofs and you can really feel it here. I could see
this language being very useful in math-y applications such as cryptography
and verification.

------
kxyvr
Is there any reason to use Agda over Coq or vice versa?

~~~
cies
[http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.AgdaVs...](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.AgdaVsCoq)

You might also want to compare to Idris (and maybe Epigram, but its no longer
in development).

[http://www.quora.com/How-does-Idris-compare-to-other-
depende...](http://www.quora.com/How-does-Idris-compare-to-other-dependently-
typed-programming-languages)

[http://www.reddit.com/r/haskell/comments/132kg0/agda_epigram...](http://www.reddit.com/r/haskell/comments/132kg0/agda_epigram_or_idris_which_one_to_learn/)

[http://www.reddit.com/r/dependent_types/comments/q8n2q/agda_...](http://www.reddit.com/r/dependent_types/comments/q8n2q/agda_vs_idris/)

[http://stackoverflow.com/questions/9472488/differences-
betwe...](http://stackoverflow.com/questions/9472488/differences-between-agda-
and-idris)

All have pros and cons; i like that Idris can compile to JS
([https://raichoo.github.io/posts/2014-01-28-improved.html](https://raichoo.github.io/posts/2014-01-28-improved.html))

------
Energy1
How does Agda compare to the likes of Clojure, Haskell, ML, Scheme etc? What
are the best reasons to learn it?

~~~
pmahoney
The article covers this here [http://williamdemeo.github.io/2014/02/27/learn-
you-an-agda/#...](http://williamdemeo.github.io/2014/02/27/learn-you-an-
agda/#what-is-agda-anyway)

Some excerpts:

> Agda is a programming language that uses dependent types ... you can
> actually include values inside a type. For example, the List type
> constructor can be parameterized by both the type of its contents and the
> length of the list in question ... . This allows the compiler to check for
> you to make sure there are no cases where you attempt to call head on a
> potentially empty list, for example.

> If I can come up with a function of type Foo -> Bar (and Agda says that it’s
> type correct) that means that I’ve written not only a program, but also a
> proof by construction that, assuming some premise Foo, the judgment Bar
> holds.

> Proofs work in concurrent scenarios. You can’t reliably unit test against
> race conditions, starvation or deadlock. All of these things can be
> eliminated via formal methods.

> Thanks to Curry-Howard, Agda can also be used as a proof language, as
> opposed to a programming language. You can construct a proof not just about
> your program, but anything you like.

~~~
lmm
Is there a comparison to Idris? It sounds like they're very similar, and more
of the people I've followed seem to be interested in Idris than Agda.

------
frontsideair
I always wondered about dependent types. Even though it was a little bit too
technical for me, at least I have some idea about what it really is.

By the way, Z notation rocks.

------
eli_gottlieb
Ok, that's neat. Is there a proof checker and an editor/IDE other than Emacs'
Agda mode?

Because I'm probably going to stick with Coq for its tooling.

------
alphonse23
I posted this on lobste.rs and somebody stole my link....

Hackernews always gets so much more comments.

~~~
bkirwi
Not guilty! I picked this one up on Twitter this afternoon, but it's possible
the lineage traces back to your lobste.rs post. (I have no lobste.rs account,
though not for lack of interest -- while sparse, the comments there seem to be
of very high quality.)

------
olderwannalear
My thanks OVERFLOWS. For those who are 'older but not quite Learn U Agda vs
'wiser strategies' HELPFUL.

Think eric raymond and too bad that perl is just another dead language -- your
wisdom though as recompense. When you are older, it becomes EASIER for
crunchfit and yes, it sometimes becomes harder to exercise to point of vomit -
"ad nauseum' in Latin, but the pain is much easier. Don't you do three hundred
(300) pushups a day?

So, the routine is simple. Get stuck running Haskell (another bump on the road
to the true language of Coq) \- go ahead and flame - do the pushups. Then
laugh cause it releaxes and then refrshed back to AGDA.

PS. Engineering school was arduous and graduate school. The personal private
books/research were just hobbies and no I will not mention my name. Even the
so-called Yourdon 'death marches' are just a bump on the road.

It's worse than some females - over the period of a 'big city man.' \- go
ahead flame - Just take code from arxiv, run it in Haskell and Agda and there
are only three explanations 1.)the programmer is stupdi - yup that's me
2.)scientific fraud - always possible 3.)the 'compiler' or the strange AMD CPU
is fickle in a feminine way? 4.)the language paradigm is 'slightly broken.'
5.) all of the above

Fair Warning and Serpents be Here. Haskell, Agda and even Coq are DEFINED as
EXPERIMENTAL RESEARCH Languages. Of course, you can always go Python (which
version?) and Javascript, which is the bubble gum and string that holds
together the Internet.. along with BAsh shellshock.

It this why they call it a bit of 'hacking'? PPS. learn to ride bicycle in big
city and survived with most of my fingers intact.

------
mike_hearn
Ah yes, dependent types. They tried to teach this at my university because
some researchers there were working on it. Too bad they didn't bother to teach
something more useful, like what malloc and free do.

But let's see. Perhaps the field has become less wonkish and more relevant to
real programmers in the last ten years.

 _Most language tutorials start with the typical “Hello, World” example, but
this is not really appropriate for a first example in Agda. Unlike other
languages, which rely on a whole lot of primitive operations and special cases
for basic constructs, Agda is very minimal - most of the “language constructs”
are actually defined in libraries._

That sounds reasonable ...

 _Agda doesn’t even have numbers built in, so the first thing we’re going to
do is define them_

That's much less reasonable ...

 _This is a very elegant way to define infinitely large sets. This way of
defining natural numbers was developed by a mathematician named Giuseppe
Peano, and so they’re called the Peano numbers .... Now we can express the
number one as suc zero, and the number two as suc (suc zero), and the number
three as suc (suc (suc zero)), and so on._

Oh dear. This is a new use of the word elegant I have not encountered before.

I was expecting the next stage of the tutorial to describe how to make numbers
in Agda resemble number systems actually used by humans, or even machines, but
no such luck. They stick with a Lisp-style Peano representation throughout the
entire thing. Having defined an entirely unworkable method of representing
integers because their standard library apparently doesn't do so (?!) they
then go on to prove things like 1 + 1 == 2.

Yeah, I think I'll skip. Perhaps in another few decades someone will have
bothered to make a dependently typed language that doesn't use untypeable
characters as part of its syntax, and has an integer type built in, and we'll
all get awesome statically checkable code for free. Until then I'm gonna stick
with FindBugs.

~~~
ocharles
Wow, you are just radiating ignorance; I don't even know why I'm wasting my
breath. Nonetheless,

> Oh dear. This is a new use of the word elegant I have not encountered
> before.

The Peano numbers are elegant because they correspond directly with induction.
Agda is first and foremost a proof assistant, so it's natural that we lean
towards things that help as write our proofs. This is not "Lisp-style" at all,
it's a mathematically consistent way of defining natural numbers. The idea
extends further with ornamentation to model lists and other data structures.

> Having defined an entirely unworkable method of representing integers
> because their standard library apparently doesn't do so (?!) they then go on
> to prove things like 1 + 1 == 2.

I don't know what's "unworkable" about Paeno arithmetic. Yes, it's not the
most efficient representation, but you're working in a proof engine, so that
is secondary to our concerns. Furthermore, Agda has {-# BUILTIN #-} pragmas
that let us switch out this data type with something that is more optimal. We
don't use "the number system actually used by humans" (whatever that is) or
machines, at least traditionally, because they just make the proofs harder.

> Perhaps in another few decades someone will have bothered to make a
> dependently typed language that doesn't use untypeable characters as part of
> its syntax, and has an integer type built in

Yea, some of us did "bother" \- you're looking for Idris. But I'd really
rather you didn't join us.

~~~
mike_hearn
I know Agda isn't really a programming language, but then why is this book
trying to claim it is? It says at the start:

_Agda is a programming language_

That's the standard it sets right from the first chapter. It then goes on to
say that this programming language doesn't have numbers.

If the book had said, "Agda is a proof assistant for CS and mathematics
researchers to research inductive logic" then I'd have been much less harsh on
it, but whilst this book is claiming it's a tool for programmers I will judge
it by that standard. And by that standard representing numbers and even
forcing you to type them in as (suc (suc (suc (zero))) is _not_ elegant.

~~~
edwinb
As I see it, this is not so much a book at this stage as an introductory
tutorial written by someone as they were learning Agda (about four years ago I
think), as a contribution to the community to help other beginners. As such,
one of the (unstated) assumptions is that the reader is already motivated to
learn about programming with dependent types.

The early examples you see with inductive structures such as Nat are about
learning the foundations, and you can't go on to do anything especially
interesting without a solid understanding of the foundations. Its structure
often also turns out to have a convenient correspondence with more realistic
data structures, such as lists (their length) and trees (their depth).

I do sometimes wonder if we should start using something more obviously useful
as an introductory example though. There's plenty of possibilities, and
programmers aren't generally going to be using Nats in practice (I rarely do).

I don't use Agda myself (I use Idris, which is similar but is more directly
aimed at general purpose programming) but I do know that it has primitive
types...

Anyway, there's all kinds of interesting work going on at the minute which
goes way beyond these introductory examples. For example, we're working on a
way of specifying and verifying implementations of communication protocols
([https://github.com/edwinb/Protocols](https://github.com/edwinb/Protocols)),
which we'd like to apply to cryptographic protocols when we've made some more
progress. You can hear me waffling on about that, as well as about how we deal
with stateful systems in general, here:
[https://www.youtube.com/watch?v=rXXn4UunOkE&feature=youtu.be](https://www.youtube.com/watch?v=rXXn4UunOkE&feature=youtu.be)

I post this mainly because I suspect I'm one of the wonks who was researching
dependently typed programming at your university ten years ago. At the time,
there was lots of foundational work to do, and there is still lots to do
before it's industrial strength, but we've made a lot of progress, and I think
the goal is worth striving for.

