Reflections on Haskell and ICFP Contest 2009

Hi All, As the ICFP 2009 contest (http://www.icfpcontest.org) approaches its end, I decided to write down some thoughts I had while trying. On Friday I downloaded the task (http://www.icfpcontest.org/task-1.9.pdf), read it for a while, and, since my goal is to finish by Xmas, went to the swimming pool. :-D While swimming, I started to think on the problem, and realized that the task is almost too easy for Haskell. Actually the task was so easy, that they added a final, non-scoring, task for those who have finished early. This year's task is to build a VM that runs a (simple) program that simulates the physics of a satellite. The VM code has no branches, acting like a huge pocket calculator. The mission is to create a simulator that interact with this VM and maneuver the sattelite(s) on predefined patterns. Here is how it went: 1) Reading the orbiter data file: The orbiter data file is a stream of 32-bit unsigned integers, which are commands, and 64-bit double precision IEEE-754 floats, which are data, forming a 96-bit frame. For this part I decided to use the Data.Binary module from hackage. The module is great, and it is very simple to use. But that took me 3 hours to learn how to use it (which, with my "honey-do" list ended up to be in Sunday morning) By Saturday night I was cursing "The Binary Strike Force" because a) get :: Word32 reads it in little-endian b) get :: Double reads the result of an decodeFloat, which has no resamblance at all with IEEE-754 standards c) I spent the entire Saturday (2 hours, honey-do excluded) thinking I was doing something wrong!! I was really pissed of, until I found "getWord32le" and "getWord64le", which solved 80% of the problem. The final blow was to decode the Word64 encoded IEEE-754 float into a Haskell float, which took me another honey-do-free hour. First step solved. (BTW: I am attaching the first version to this e-mail. I will upload to Hackage upon completion, when getIEEE754float64le and putIEEE754float64le functions are done!) 2) Running the VM: This is the step I am working on. A really good and obvious approach to run the VM is to use a RWS monad, since: a) I have a fixed environment (the program and the input ports) b) I have a state (the program counter, the status register and the data memory contents) c) I have a monoid output (the output ports) This is my recurrent complaint (a rant, maybe): this really important monad is completely undocumented, left for the developer to figure out how to use it. Even each of the singular monads (Reader, Writer and State) is poorly documented. I will do some toy programs to understand each one. Let's hope I can create a hands-on tutorial on the RWS monad. 3) Controlling the sattelites This is going to be a piece of cake (aheeem! Just kidding!!). After computing the VM iteration, another computation will take the output data time series and estimate the next move. It will be a piece of cake, considering I would have learned enough of Haskell state monads on step 2 to have just to worry about the physics of the problem!!! I'll keep you updated as my tests go, and hopefully I will have a working demo of the task written in Haskell by Xmas... 2010! ;-) Best regards, Rafael Gustavo da Cunha Pereira Pinto

Hi Rafael,
2009/6/29 Rafael Gustavo da Cunha Pereira Pinto
Hi All,
As the ICFP 2009 contest (http://www.icfpcontest.org) approaches its end, I decided to write down some thoughts I had while trying.
On Friday I downloaded the task (http://www.icfpcontest.org/task-1.9.pdf), read it for a while, and, since my goal is to finish by Xmas, went to the swimming pool. :-D While swimming, I started to think on the problem, and realized that the task is almost too easy for Haskell. Actually the task was so easy, that they added a final, non-scoring, task for those who have finished early.
This year's task is to build a VM that runs a (simple) program that simulates the physics of a satellite. The VM code has no branches, acting like a huge pocket calculator. The mission is to create a simulator that interact with this VM and maneuver the sattelite(s) on predefined patterns.
Here is how it went:
1) Reading the orbiter data file:
The orbiter data file is a stream of 32-bit unsigned integers, which are commands, and 64-bit double precision IEEE-754 floats, which are data, forming a 96-bit frame. For this part I decided to use the Data.Binary module from hackage. The module is great, and it is very simple to use. But that took me 3 hours to learn how to use it (which, with my "honey-do" list ended up to be in Sunday morning)
By Saturday night I was cursing "The Binary Strike Force" because
a) get :: Word32 reads it in little-endian b) get :: Double reads the result of an decodeFloat, which has no resamblance at all with IEEE-754 standards c) I spent the entire Saturday (2 hours, honey-do excluded) thinking I was doing something wrong!!
I was really pissed of, until I found "getWord32le" and "getWord64le", which solved 80% of the problem. The final blow was to decode the Word64 encoded IEEE-754 float into a Haskell float, which took me another honey-do-free hour.
First step solved. (BTW: I am attaching the first version to this e-mail. I will upload to Hackage upon completion, when getIEEE754float64le and putIEEE754float64le functions are done!)
Indeed, I found the binary format a difficulty for haskell. But in fact, hackage has a module that does the work: http://hackage.haskell.org/package/data-binary-ieee754
2) Running the VM:
This is the step I am working on. A really good and obvious approach to run the VM is to use a RWS monad, since:
a) I have a fixed environment (the program and the input ports) b) I have a state (the program counter, the status register and the data memory contents) c) I have a monoid output (the output ports)
This is my recurrent complaint (a rant, maybe): this really important monad is completely undocumented, left for the developer to figure out how to use it. Even each of the singular monads (Reader, Writer and State) is poorly documented.
I will do some toy programs to understand each one. Let's hope I can create a hands-on tutorial on the RWS monad.
Why a monad ? Why not just a function State -> State and the use a function like iterate to do the work ?
3) Controlling the sattelites
This is going to be a piece of cake (aheeem! Just kidding!!). After computing the VM iteration, another computation will take the output data time series and estimate the next move.
The next move is easy to estimate : you have the vm and simulating code at hand. Of course, making the best move is another problem.
It will be a piece of cake, considering I would have learned enough of Haskell state monads on step 2 to have just to worry about the physics of the problem!!!
I'll keep you updated as my tests go, and hopefully I will have a working demo of the task written in Haskell by Xmas... 2010! ;-)
Good luck ! Thu

Hi Tuh2009/6/29 minh thu
First step solved. (BTW: I am attaching the first version to this e-mail. I will upload to Hackage upon completion, when getIEEE754float64le and putIEEE754float64le functions are done!)
Indeed, I found the binary format a difficulty for haskell. But in fact, hackage has a module that does the work: http://hackage.haskell.org/package/data-binary-ieee754
Shame on me! :-( If only I have posted this rant earlier! :-D
2) Running the VM:
This is the step I am working on. A really good and obvious approach to
the VM is to use a RWS monad, since:
a) I have a fixed environment (the program and the input ports) b) I have a state (the program counter, the status register and
run the
data memory contents) c) I have a monoid output (the output ports)
Why a monad ? Why not just a function State -> State and the use a function like iterate to do the work ?
I am considering that using the monad all the state and environment threading will be simplified. The output part is optional. But you are absolutely right, I could use a state composed by (Inputs, program counter, status, data), which would do just as well, as it is just a matter of not touching the program and the input.
3) Controlling the sattelites
This is going to be a piece of cake (aheeem! Just kidding!!). After computing the VM iteration, another computation will take the output data time series and estimate the next move.
The next move is easy to estimate : you have the vm and simulating code at hand. Of course, making the best move is another problem.
I think the simulator itself is another State->State function, but this time the state is a [Output].
Good luck !
Thanks!
Rafael Gustavo da Cunha Pereira Pinto

When you get bored or stumped with the problem you might pass your time with Orbiter [http://orbit.medphys.ucl.ac.uk/]. Or you could just use all the orbital mechanics math from the documentation. :) Enjoy, -ljr Rafael Gustavo da Cunha Pereira Pinto wrote:
Hi All,
As the ICFP 2009 contest (http://www.icfpcontest.org) approaches its end, I decided to write down some thoughts I had while trying.
On Friday I downloaded the task (http://www.icfpcontest.org/task-1.9.pdf), read it for a while, and, since my goal is to finish by Xmas, went to the swimming pool. :-D While swimming, I started to think on the problem, and realized that the task is almost too easy for Haskell. Actually the task was so easy, that they added a final, non-scoring, task for those who have finished early.
This year's task is to build a VM that runs a (simple) program that simulates the physics of a satellite. The VM code has no branches, acting like a huge pocket calculator. The mission is to create a simulator that interact with this VM and maneuver the sattelite(s) on predefined patterns.
Here is how it went:
1) Reading the orbiter data file:
The orbiter data file is a stream of 32-bit unsigned integers, which are commands, and 64-bit double precision IEEE-754 floats, which are data, forming a 96-bit frame. For this part I decided to use the Data.Binary module from hackage. The module is great, and it is very simple to use. But that took me 3 hours to learn how to use it (which, with my "honey-do" list ended up to be in Sunday morning)
By Saturday night I was cursing "The Binary Strike Force" because
a) get :: Word32 reads it in little-endian b) get :: Double reads the result of an decodeFloat, which has no resamblance at all with IEEE-754 standards c) I spent the entire Saturday (2 hours, honey-do excluded) thinking I was doing something wrong!!
I was really pissed of, until I found "getWord32le" and "getWord64le", which solved 80% of the problem. The final blow was to decode the Word64 encoded IEEE-754 float into a Haskell float, which took me another honey-do-free hour.
First step solved. (BTW: I am attaching the first version to this e-mail. I will upload to Hackage upon completion, when getIEEE754float64le and putIEEE754float64le functions are done!)
2) Running the VM:
This is the step I am working on. A really good and obvious approach to run the VM is to use a RWS monad, since:
a) I have a fixed environment (the program and the input ports) b) I have a state (the program counter, the status register and the data memory contents) c) I have a monoid output (the output ports)
This is my recurrent complaint (a rant, maybe): this really important monad is completely undocumented, left for the developer to figure out how to use it. Even each of the singular monads (Reader, Writer and State) is poorly documented.
I will do some toy programs to understand each one. Let's hope I can create a hands-on tutorial on the RWS monad.
3) Controlling the sattelites
This is going to be a piece of cake (aheeem! Just kidding!!). After computing the VM iteration, another computation will take the output data time series and estimate the next move.
It will be a piece of cake, considering I would have learned enough of Haskell state monads on step 2 to have just to worry about the physics of the problem!!!
I'll keep you updated as my tests go, and hopefully I will have a working demo of the task written in Haskell by Xmas... 2010! ;-)
Best regards,
Rafael Gustavo da Cunha Pereira Pinto
------------------------------------------------------------------------
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

2009/6/29 Lanny Ripple
When you get bored or stumped with the problem you might pass your time with Orbiter [http://orbit.medphys.ucl.ac.uk/]. Or you could just use all the orbital mechanics math from the documentation. :)
Enjoy, -ljr
That's cool... I'll try it someday!
participants (3)
-
Lanny Ripple
-
minh thu
-
Rafael Gustavo da Cunha Pereira Pinto