It's my pleasure to announce another release of EclipseFP, the Eclipse plugins for Haskell development.
In this feature, I've added support for cabal-dev, as demonstrated in this video.
I also have added a "organize imports" function on an opened source file. This cleans the import lists by only importing what's really used and formatting it in a manner similar to what stylish-haskell does.
I have also tried to improve the performance of the editor, and fixed all bugs we were made aware of. Syntax highlighting can now highlight more tokens in different colors (non alphanumeric symbols, different types of comment).
Full release notes can be seen here.
As usual, to upgrade just point your Eclipse to http://eclipsefp.sf.net/updates. Report any issue to the SourceForge forum.
Happy Haskell Hacking!
In this blog I talk about some of the personal programming I do as a hobby. From Java to Rust via Haskell, I've played around with a lot of technologies and still try to have fun with new languages and APIs!
Tuesday, February 26, 2013
Sunday, February 24, 2013
Porting my typeclass game to reactive-banana-sdl
Some time ago I wrote a tiny game called TypeClass, just to experiment with the SDL bindings for Haskell. I was always curious to learn more about FRP, but never really knew where to start. So I just decided to change TypeClass to use reactive-banana, since it looked like a nice library with a dedicated author. And there are SDL bindings too!
It took a bit efforts since I didn't find any sample in reactive-banana-sdl, but I finally got it working. The game is exactly the same from the outside, so it still not that exciting. But I feel I've made progress in understanding events and behaviors and how it all fits together.
I've put the game on github, so anybody else interested in using reactive-banana with SDL can at least have a sample. It requires my own version of reactive-banana.
Happy Haskell Hacking!
It took a bit efforts since I didn't find any sample in reactive-banana-sdl, but I finally got it working. The game is exactly the same from the outside, so it still not that exciting. But I feel I've made progress in understanding events and behaviors and how it all fits together.
I've put the game on github, so anybody else interested in using reactive-banana with SDL can at least have a sample. It requires my own version of reactive-banana.
Happy Haskell Hacking!
Tuesday, February 19, 2013
EclipseFP + cabal-dev
Some of EclipseFP users had a dream: use cabal-dev sandboxing capabilities to manage their Haskell projects in EclipseFP. Well, we're getting there. I've uploaded a video of the current state of EclipseFP and cabal-dev integration. The workflow is as follows:
- Fill in the cabal-dev location in the preferences page. Once this is filled, all your Haskell packages will be sandboxed
- Create projects as you would normally
- In the Cabal editor, local projects will now be available as dependencies. When you select a project as a dependency, a project reference is created by Eclipse. The dependent project is then installed in the current project sandbox
- Building, autocomplete, GHCi sessions, etc. will use the project sandbox
Under the scenes, we're only using cabal-dev install --sandbox=.... Thanks Rogan for the help!
This will be part of EclipseFP 2.5.0. I urge adventurous hackers to get the current version from github and start testing!
- Fill in the cabal-dev location in the preferences page. Once this is filled, all your Haskell packages will be sandboxed
- Create projects as you would normally
- In the Cabal editor, local projects will now be available as dependencies. When you select a project as a dependency, a project reference is created by Eclipse. The dependent project is then installed in the current project sandbox
- Building, autocomplete, GHCi sessions, etc. will use the project sandbox
Under the scenes, we're only using cabal-dev install --sandbox=.... Thanks Rogan for the help!
This will be part of EclipseFP 2.5.0. I urge adventurous hackers to get the current version from github and start testing!
Friday, February 08, 2013
Discovering the value of QuickCheck
I like tests. I like the confidence that you get when you have an extensive test suite so you know you'll be notified when things break. But so far I've used mainly frameworks like HUnit to explicitly state my assertions. I know what the code should produce given the inputs, and I encode that information in tests. So I didn't really see what QuickCheck brought to that. I'm still not that comfortable with the random aspect of it, but I understand that it can find corner cases for you, whereas with assertions the corner cases you need to think of beforehand, or add them when your users encounter them (ouch). But I'm starting to see the value of QuickCheck.
I was working inside the HTF source code, and the goal was to produce a textual representation of a diff between strings similar to what the diff utility does on Unix. I just wanted to have a fallback for machines that don't have diff installed. And Stefan had written a QuickCheck property to verify that the outputs of the pure Haskell code and the utility matched. I used the property to fall back to my comfortable way of working: fire QuickCheck, let it find a failing case, add it to a HUnit TestCase, and try to understand and fix the issue without breaking the rest. So QuickCheck was just a test case generator.
But then Sterling, the maintainer of Diff, convinced me that 100% matches between the code and the utility was an utopian goal, since diff does some tradeoffs for speed and compactness, and rewriting diff with all its quirks wasn't really worthwhile. And that's when I started to like QuickCheck. I thought: we want exact matches most of the time, but it's fine to have differences as long as what we generate is not too big compared to what the diff utility outputs. This is what QuickCheck classify function can do: I first verify if the size of the output is ok (less than 10% bigger that the utility output), and then I classify the test case as an exact match if the two outputs match. And then I use the cover function (not, ahem, covered in the manual ) to ensure that I get at least 90% exact match:
cover (haskDiff == utilDiff) 90 "exact match" $
classify (haskDiff == utilDiff) "exact match"
(div ((length haskDiff)*100) (length utilDiff) < 110)
So the tests are random, yes, but I've pretty good confidence that the output function does what's it's supposed to do. 90% of the time :-).
I was working inside the HTF source code, and the goal was to produce a textual representation of a diff between strings similar to what the diff utility does on Unix. I just wanted to have a fallback for machines that don't have diff installed. And Stefan had written a QuickCheck property to verify that the outputs of the pure Haskell code and the utility matched. I used the property to fall back to my comfortable way of working: fire QuickCheck, let it find a failing case, add it to a HUnit TestCase, and try to understand and fix the issue without breaking the rest. So QuickCheck was just a test case generator.
But then Sterling, the maintainer of Diff, convinced me that 100% matches between the code and the utility was an utopian goal, since diff does some tradeoffs for speed and compactness, and rewriting diff with all its quirks wasn't really worthwhile. And that's when I started to like QuickCheck. I thought: we want exact matches most of the time, but it's fine to have differences as long as what we generate is not too big compared to what the diff utility outputs. This is what QuickCheck classify function can do: I first verify if the size of the output is ok (less than 10% bigger that the utility output), and then I classify the test case as an exact match if the two outputs match. And then I use the cover function (not, ahem, covered in the manual ) to ensure that I get at least 90% exact match:
cover (haskDiff == utilDiff) 90 "exact match" $
classify (haskDiff == utilDiff) "exact match"
(div ((length haskDiff)*100) (length utilDiff) < 110)
So the tests are random, yes, but I've pretty good confidence that the output function does what's it's supposed to do. 90% of the time :-).
Tuesday, February 05, 2013
EclipseFP and performance
OK, ok, performance in EclipseFP could be better. I'll try to present a bit the challenges and why things are the way they are.
You see, EclipseFP used scion for a while, and scion was a long running process, which ended up eating loads of memory, and had a few issues due to the GHC API maintaining state and not releasing memory (I've written about this elsewhere). So I rewrote the whole Haskell backend with BuildWrapper, and I took opposite approach: BuildWrapper is an short-lived executable. You start BuildWrapper with some parameters, it does its stuff and outputs some JSON answer. And that's fine for a lot of operations. But people have started to complain that when they edit a source file, the feedback loop is quite slow, and they keep seeing that the synchronization job keeps on running all the time. That's because every time Eclipse says that the editor has changed (not every keystroke, luckily), EclipseFP goes back to BuildWrapper to analyze the source. So it fires the BuildWrapper executable (and only this can be slow if you have an over zealous anti virus running), which in turn builds up a GHC session, analyses the AST, writes it to JSON, and tears everything down. For small projects and fast machines, this is acceptable. But I eat my own dogfood, of course, and when working on BuildWrapper itself, I noticed things could be too slow for comfort. Sometimes it would take 4 seconds to analyze completely a file.
So I went the middle route. I create another command in BuildWrapper that makes the executable stay around and listen for more commands. More specifically, there is now a long running build command, that can repeatedly analyze a file while staying in the GHC session. It won't have the same issues as the long running scion because it's tied to the file you're editing. When you close the file in Eclipse, the executable dies. When you change something in the Cabal file, the executable restarts to it can take into account new modules, flags or dependencies. The synchronization job now runs in something like a quarter of the time, and even faster.
I believe we have a happy medium: most operations are short-lived and we don't need to worry about memory usage or stray processes, but where performance matters (when you're in the flow and writing Haskell and don't want to wait for the editor to catch up) we have a long running process that's efficient, but not too persistent.
This will be part of the upcoming 2.5.0 release of EclipseFP. Of course people are welcome to get the source and test it for themselves before the official release!
You see, EclipseFP used scion for a while, and scion was a long running process, which ended up eating loads of memory, and had a few issues due to the GHC API maintaining state and not releasing memory (I've written about this elsewhere). So I rewrote the whole Haskell backend with BuildWrapper, and I took opposite approach: BuildWrapper is an short-lived executable. You start BuildWrapper with some parameters, it does its stuff and outputs some JSON answer. And that's fine for a lot of operations. But people have started to complain that when they edit a source file, the feedback loop is quite slow, and they keep seeing that the synchronization job keeps on running all the time. That's because every time Eclipse says that the editor has changed (not every keystroke, luckily), EclipseFP goes back to BuildWrapper to analyze the source. So it fires the BuildWrapper executable (and only this can be slow if you have an over zealous anti virus running), which in turn builds up a GHC session, analyses the AST, writes it to JSON, and tears everything down. For small projects and fast machines, this is acceptable. But I eat my own dogfood, of course, and when working on BuildWrapper itself, I noticed things could be too slow for comfort. Sometimes it would take 4 seconds to analyze completely a file.
So I went the middle route. I create another command in BuildWrapper that makes the executable stay around and listen for more commands. More specifically, there is now a long running build command, that can repeatedly analyze a file while staying in the GHC session. It won't have the same issues as the long running scion because it's tied to the file you're editing. When you close the file in Eclipse, the executable dies. When you change something in the Cabal file, the executable restarts to it can take into account new modules, flags or dependencies. The synchronization job now runs in something like a quarter of the time, and even faster.
I believe we have a happy medium: most operations are short-lived and we don't need to worry about memory usage or stray processes, but where performance matters (when you're in the flow and writing Haskell and don't want to wait for the editor to catch up) we have a long running process that's efficient, but not too persistent.
This will be part of the upcoming 2.5.0 release of EclipseFP. Of course people are welcome to get the source and test it for themselves before the official release!
Subscribe to:
Posts (Atom)