Friday, October 31, 2008

Learning from game designers

Here's a very readable presentation about how computer game designers
manage to build in a more evenly-sloped learning curve than application designers
do.

Princess-Rescuing Application

Wednesday, August 13, 2008

What kind of debugging should we be studying?

I really think, but just can't back this up, that a lot of the time when programmers are debugging, they're doing it on code that they're pretty familiar with. The research literature empirically studying people debugging, seems heavily biased towards comprehension and debugging of code that people are seeing for the first time. This has got to be a methodological issue -- it's just so much easier to bring people into a lab and hand them code they haven't seen before.

Some people I've asked about this seem to disagree -- they think it's commonplace for programmers to be thrown into new unfamiliar code in their workplace and have to figure it out. Could be, but I still think they spend most of their time around familiar code, hour by hour. And that will judge their debugging tools by how well they work for them in familiar code.

This makes a big difference, because people who are debugging familiar code already have some understanding of how it works, and they're trying to compare the real code against the understanding in their head, to see where they, or it, are going wrong. So it's kind of a scientific process, coming up with hypotheses and refuting them by testing them out, until they narrow down the exact point where the code goes astray from their notions about it.

People debugging unfamiliar code, on the other hand, are going to start with a comprehension phase where they go bottom up, looking at it and just trying to make sense of it. If academic research, and product development research, puts too much focus into understanding that particular situation, I think it will be giving short shrift to the later phases of code maintenance.

Tuesday, July 15, 2008

Help with study of functional programmers

Are you currently developing or maintaining a medium to large-sized
program written in a functional language, such as Haskell, F#, OCaml,
or Lisp? I'm doing a study of functional programmers, as part of
a research internship at Microsoft, and I would like the opportunity to look over
your shoulder while you do debugging or coding on your project.

I'm looking for people with at least a year's experience doing
functional programming, and who are currently working on a real
project (i.e. for some purpose other than learning functional
programming). I'm only allowed to use people who can work in the US
(because of the gratuity, which is taxable income). I'd simply come
watch you work, and ask a few questions along the way. You'd do
whatever you would normally be doing. If you're near Seattle or
Portland, I'd come to your office for a couple of hours. If you're
not near Seattle or Portland, then we'd set you up with LiveMeeting
or some other remote screencast software so I can watch you from here.

Obviously security concerns are an issue - I will not share any
proprietary information that I learn about while visiting you.

In exchange for your help, Microsoft will offer you your pick of free
software off its gratuity list (which has about 50 items, including
Visual Studio Professional, Word for Mac, XBOX 360 games) or any book
from MS Press.

We're doing this because expert functional programmers have not been
studied much. We plan to share our findings through academic
publications, to help tool developers create debugging tools that are
genuinely helpful in real-world settings.

I'm hoping to finish my observations by August 8th, so please contact
me immediately if you're interested!

Thank you,

Chris Bogart
425-538-3562
t-chribo@microsoft.com

Sunday, July 13, 2008

icfp contest update

Well, I got threads and tcp and everything all figured out, and my simple "spike" solution works the way I intended it: the rover makes a beeline for home base, ignoring craters, martians, and boulders, and usually dying or crashing.

However I can't get it to run in Mono on the LiveCD environment for the contest. I've been using Visual Studio on a virtual machine on my mac. Visual Studio runs a little slow, but the program runs fine. But when I try to run it in mono, I get a big wodge of error messages, none of them pertaining to my code. I used some new features of F#, so it may be that it exercises some corners of mono that haven't been tested yet.

I think at this point I'm going to give up on submitting a solution and just post interesting bits of my code here after the contest ends. I still want to think some about a quick and dirty way of avoiding craters, but I probably won't spend much more time on it: it's nice out today!

I feel like I've gotten what I wanted to out of this: building something significant in F#. I have 238 lines of code, and I used F#'s Erlang-style mailboxes, asynchronous workflow, discriminated unions, class definitions, and I overcame the headaches of separating things into multiple modules while making sure all references went backwards. I got threading and networking in a pretty clean way I think. The ugliest part of the code is actually probably the navigation code, that looks at where the rover is and how fast it's going, and decides how to head for home base.

Saturday, July 12, 2008

ICFP contest day 2

I spent a few hours programming last night, and I still don't have a running program yet. F# turns out to have some pretty interesting monad-like things for handling asynchronous code (they're called "workflows") and this appears to be the right way to handle sending and receiving stuff from a TCP/IP connection.

I think I have a pretty good idea how to make this work, but I'm banging my head against the details: for example I want to asynchronously read a line of text from a socket, passing it along to the rest of my program as soon as a carriage return is received. So, do I have to read one byte at a time in a tail-recursive function, adding to a mutable string? Or is there an object or something in the library that will do this for me? There's a tradeoff between searching and searching in the docs to find the most natural way of doing it in the language you're trying to learn, versus writing it from the ground up yourself, probably less efficiently, as a newbie.

My problem may be that I need to sit down and read a book on .NET instead of thinking I can adhoccumulate expertise efficiently.

By the way, I like Expert F# better than Foundations of F#. I wish I'd read the former instead of the latter as preparation.

Wish me luck!

Friday, July 11, 2008

ICFP contest! Rovers on Mars!

The 2008 icfp contest just started! Sadly I'm at work for another several hours, but I skimmed through the description, and hopefully the programmer-lobe of my brain is already hard at work on the problem while my researcher-lobe is busy dealing with participant recruitment for a study.

This one is not all parsey like the last two years: it's all real-time execution and floating point numbers in a navigation problem. It's not the kind of thing I've thought about much, so it should be an interesting challenge. Also, my laptop plug *just* stopped working, so I may have to complete the entire task in 2 hours and 27 minutes. Hopefully they have extras in Seattle somewhere.

My plan this year is to do it in F#, since it's cool and also I'm doing a study on it for my summer internship. But they made it a little harder by not including F# in the list of supported languages. But no worries -- they do have mono (the .NET clone, not the disease), so I'll just have to upload an executable.

Wednesday, October 10, 2007

5 Hints for Beginning Haskellers

Here are some things that have caused me headaches in learning Haskell.

  1. Function calls. Functions are called by giving the name and the arguments separated by spaces. If a function f has two parameters, a and b, you call it with f a b not f(a,b). The latter would be a one-argument function whose argument is a pair. You can do things that way if you like, but it'll make things a lot trickier later.
  2. Precedence. Those spaces in the function call syntax are about the tightest binding thing in the language. So if distance is an integer, and show is an (Int -> String), then show distance++" miles" is good syntax, because show distance is evaluated before the ++. On the other hand, if c is a character and cs is a string, then length c:cs is a type error. Haskell will try to evaluate length c first, then prefix that number to the front of the list cs. Instead, you want length (c:cs).
  3. Parens in patterns. This is really an example of the precedence issue above, but it trips me up all the time. You need more parens on the left hand side of function calls than you'd think. I don't know how many times I've written code like the sample below, leaving out the parens at first.
    • data Coord = Coord Int Int
    • manhattandist :: Coord -> Int
    • manhattandist Coord x1 y1 = x1 + y1 WRONG
    • manhattandist (Coord x1 y1) = x1 + y1 RIGHT
  4. Arrows in type declarations. The type of (+) is Int -> Int -> Int; and we're supposed to accept that the first two Ints are the arguments, and the last Int is the return value. But turns out there's a cool reason for this. An equivalent type declaration would be Int -> (Int -> Int) (because -> groups right). You can think about addition this way, and Haskell cooperates nicely: + is a function that takes one integer, and returns a function. So plus x y = x+y is equivalent to plus x = \y -> x + y (search for lambda in the Haskell docs if you don't know that backslash syntax). So if you need a one-argument function (that returns a function) for some reason, it's OK to go ahead and define it as a two-argument function returning a number; Haskell doesn't make a distinction, and it's more convenient sometimes to express it that way.
  5. Monads. These are famously hard to get. There are 10,000 tutorials out there, and most of them help a little. I'd recommend you start by learning to use the important standard ones, like Maybe, IO, and List, more or less by rote. Beyond that, if you're in a situation where you'd need to roll your own, I'd say just forget monads exist and write the code yourself. Once you get so you really understand the ugliness involved firsthand, monads will be an obvious benefit. Anyway, that's my plan right now. I think I get them well enough to explain them, but I make a lot of stupid mistakes when I try to use them, so I probably don't understand them as well as I think I do. (More on this later -- I'm taking two classes right now that rely on Haskell, so I'll comment on this more as I have little insights).

Friday, September 07, 2007

Types to distinguish parameters and dimensions

Suppose a language had a rule that said a function could only have one parameter of a given type, and each dimension of a multidimensional array had to be indexed by a different type.

This would have several benefits:

  1. You'd get extra fine-grained checking; you couldn't possibly get parameters mixed up
  2. When making array slices or currying, you wouldn't have to concern yourself with the ordering of the parameters.
  3. You wouldn't need to distinguish between optional named parameters and ordinal parameters. The name of a parameter would be (or would be derived from) it's type.
With functions like + that seem to require two items of the same type, you could interpret the two (or more) arguments as a collection. Lists certainly could contain homogeneously typed members.