Michi’s blog » read post

Prototyping thought

  • October 28th, 2006

In a recent post, pozorvlak reminded me of one of the reason it is important to have a good, obvious, and quick-to-write programming language around.

He, as I, is a mathematician, spending his time thinking, finding patterns, and trying to formulate (more or less) absolute proof that his patterns hold all the time, alternatively ways to demonstrate that they may not be universal.

In the post linked above, he starts by a neat little exercise, gets interested, and goes out to look at more examples. These show a very clear pattern, and after following this pattern quite some way out, he finally believes the pattern enough to start searching for a proof: which he also finds.

Now, this is one central heuristic pattern in mathematics. Calculate examples. Look at the examples. All of a sudden a pattern appears, and you think up a reason why such a pattern could be there. While proving the “correctness”, if you may, of the pattern, you’ll either end up formulating in enough detail what’s going on so that you may possibly expand the statement to cover even more — or you may realize that it does not hold and find a way to construct a counterexample. Either way, the mass of knowledge increases.

Now, what does this have to do with programming languages?

I started looking at Haskell due to a sequence of blogposts from sigfpe, who was describing Haskell programming from a highly algebraic point of view. And even after my involving myself in the subject, one thing that stands out is the relatively low distance between thought expressed in my ordinary day-to-day mathematical discourse, and thought expressed in Haskell code. For the ubiquitous example, let’s take the factorial function. Mathematically, I think about factorials as
“n! is the product of all integers from 1 to n”
or
“n!=Γ(n-1)” (though this not so often, I must admit)

Then again, “the product of all”, when I introduce it strictly for the first time tends to be expressed along the lines of
“Πn=1k f(n) is f(k)*Πn=1k-1” or something along those lines.

So, what happens if I want to start playing around a bit with factorials, and see whether I can say anything interesting about them?

In C or similar languages, I’ll fire up an editor, and a command shell, and start writing code that looks something like

#include <stdio.h>
int main(int argc, void* argv) {
 int i, j, f=1;
 scanf("%d", &i);
 for(j=1; j<i; j++) {
  f=f*j;
 }
 printf("%d",f);
}

and I will spend more time writing scaffolding and reworking the problem into something I can write in C than I will actually working with my mathematical intuition about it.

C++, Java, PHP, Perl — it won’t be much different in any of these. None of them have an interpreter I like, none of them differ all too much from the mindset of C. (Yes, I say this knowing full well the difference between imperative and object-oriented programming…)

In functional languages, the way I write the code is very much more reminiscent of the way I define it in my head. I could dig out enough Lisp or Scheme from the back of my mind to give you an example, but it’s getting late and I couldn’t be bothered. So instead I’ll go straight on to the thingie I want to praise.

In Haskell, I’ll fire up my interpreter, and write at the prompt something very much like

> let fac 0 = 1; fac n = n*fac (n-1)
 

and then start firing off actual calculations into the box.

> (fac 8)/((fac 3)*(fac 5))
56.0
 

During my time so far, I’ve used Haskell quite a bit in my research to generate lists of testcases. Not necessarily because Haskell is the best possible language for it, but because I could very quickly write down my thoughts, get working code out of it, and just go ahead and do what I wanted. Most languages I’ve worked with have their uses - and I’m not out to bash anything right now. But with Haskell, I’ve had a much lower threshold thought-to-code, and much less distance between my coder head and my mathematician head, than with anything else I’ve seen so far.

4 People had this to say...

Jules Said...

Haskell is even nicer!

fac n = product [1..n]

This is a lot like “n! is the product of all integers from 1 to n”

Also, the Haskell isn’t Lisp:

> fac 8 / (fac 3 * fac 5)
56.0

I admit that I sometimes add extra parens because I’m not sure if they’re necessary…

  • October 29th, 2006 at 15:11
Michi Said...

Well yeah… The lispiness of my code really is because of my not being certain whether arithmetic of function evaluation binds tighter…

  • October 29th, 2006 at 21:53
pozorvlak Said...

perl -e ‘$fac = 1; $fac *= $_ for 1..$ARGV[0]; print $fac;’

:-)

I must say, I’ve always found the Perl toplevel more useful than the Haskell one, but YMMV. And Haskell can be very nice for expressing listy-type things, such as the case in point :-)

  • December 7th, 2006 at 17:00
Anonymous Said...

Function application binds stronger, in fact: strongest. (Only the @ symbol, which may only occur in patterns, binds even stronger.)

  • March 4th, 2008 at 16:53

Want your say?

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

post navigation
about
Michi is a PhD student working in homological algebra. This blog is his outlet for texts with some manner of thought put into them. Over at his LiveJournal intimate details and streams of consciousness might be found.
Not all here is mathematics. All here, though, are my personal thoughts and opinions. Please read the about page (linked above) for more details.
This blog uses statcounter.com for logging and traffic analysis. In order to identify return visitors, this site will issue a cookie on viewing the blog.
buttons

latest comments
search
blogs and links
the rdc* theme