Running a startup on Haskell
bos.github.com
bos.github.com
Abstract: https://thestrangeloop.com/sessions/running-a-startup-on-has...
He also gave a workshop on Sunday (which I unfortunately was not able to attend): https://thestrangeloop.com/sessions/haskell-functional-progr...
Going to use the following in my "webmachine in Haskell" project.
- aeson: Fast json library [2]
- pronk: load test webservers [3]
[1]: https://github.com/mailrank/
[2]: https://github.com/mailrank/aeson
[3]: https://github.com/mailrank/pronkBryan quickly assured everyone that it had since been resolved. =)
I must hunt down and learn to use a QuickCheck-like library for my language.
If I can't find one, I should write one.
So what's the (best) equivalent of QuickCheck in Ruby? In other languages?Ruby, because of non static types, can't be as magical, but people have given their best: https://github.com/IKEGAMIDaisuke/rushcheck
Check out the citations on http://en.wikipedia.org/wiki/QuickCheck for QuickChecks in other languages.
* qc for python (http://dan.bravender.us/2009/6/21/Simple_Quickcheck_implemen...)
* QuickCheck Wikipedia page with links ot implementation for many languages (http://en.wikipedia.org/wiki/QuickCheck)
Personally I am looking forward to trying out qc for python. Has anyone here used it before?
[1] http://willowbend.cx/2009/12/05/qc-js-quickcheck-javascript/
It's not yet very advanced (sometimes the library is a bit messy), but it provides the basic QuickCheck functionality.
In any situation where you can state a powerful invariance your code must always be consistent with it's both fast and thorough. The common example is that (= str (reverse (reverse sequences))) for all sequences.
Note that this only tests invertibility. There are lots of ways reversal can be broken without violating this invariance. It's just really easy to write down this invariance and use it to rapidly check gross violations.
QC does not care, and since it's injecting fuzzed data at the unit leve (~function, generally) it makes it quite easy to see precisely where the failure happens.
Quick also not only gives you the failing cases, but tries to simplify and shrink them first.
What distingishes QuickCheck from regular unit testing is that you give it a function to test, some invariants that must hold and an input generator. Some of this is automated with compiler magic (where possible) to make simple tests really simple to write. QuickCheck will then grind through a bunch of random inputs and see if the invariants hold, finally showing you the failed cases.
That's actually not true. You can use QuickCheck with "normal" code that has side effects, too, and it's every bit as useful there.
The key to its effectiveness is that it doesn't suffer from limited human imagination. When I write test cases by hand, it's up to me to think of all the things that could go wrong and write test cases for them. But, being human, I have blind spots. Even when I try to be systematic about detecting edge cases and writing tests for them, I miss some. But when QuickCheck-like tools write the test cases for me, they can dream up corner cases like you wouldn't believe.
And, even better, when I use QuickCheck, my test code doesn't end up looking like an enumeration of corner cases. Instead, it becomes clear, concise, and formal documentation. (For a good example of QuickCheck properties as documentation, see [3].) I just specify the intended general properties of my code, and QuickCheck generates the messy test cases behind the scenes, where they don't become visible noise.
[1] http://blog.moertel.com/pages/seven-lessons-from-the-icfp-pr...
[2] http://search.cpan.org/dist/Test-LectroTest/lib/Test/LectroT...
[3] http://haskell.org/ghc/docs/latest/html/libraries/base/Text-...
Yesod reminds me of Rails, while Snap reminds me of Servlets + JSP.
Snap (I have only looked at it. Please correct me) seems like it only goes as far as the HTTP layer. It's designed so you can implement web services. Those services might return HTML, but they might return JSON or XML. It doesn't care or help you with your data representation. You have to do your own data persistence and display layers.
Taking a class just to learn a language is a bit dodgy, but Haskell is probably a forgivable exception.
Hopefully they cover the theory behind Haskell as much as the practical side of it.
Monads can be formulated in any language with first-class functions. Monadic I/O is more distinctively Haskellish, and of course Haskell has syntactic sugar to make using them easier, but as a tool and a concept they're far from unique to Haskell.
Yes, though they only really make sense if you also have static typing, and polymorphism by return type also helps.
I think the main advantage of a course at Stanford is access to the instructors. Sure, I could just read Real World Haskell and do all the exercises, but with the course I have a space where I can directly talk to Brian or David at least once a week if I have questions.
I only have a handful of experiences with GUI-intensive C# apps on Mac and Linux. They were all flat-out bad, though.
Which ones have you used?
Tomboy
F-Spot
Gnome-Do(?)
The brains are in the cloud though, apparently.
That being said Mono supports System.Windows.Forms (the poor predater to WPF) so there's always that. Or they can code against the (now dying?) Silverlight which actually works on Linux ala Moonlight.
But really, the best user experience is the one that feels the most native. So on Mac that would mean building a Cocoa client, on Windows WPF, on Linux Gtk/Qt (but then again who actually pays for Linux apps?)
Going with a one tech that supports it all just has a higher probability of having something that supports everything poorly, instead of something that supports one thing very well.
Despite this oft repeated statement, I have seen no evidence that Linux users don't pay for apps. The only thing saying it does is scare developers away from a perfectly good source of income.
If you're working in a datatype poor language, or simply one where the syntax makes defining complex datatypes painful then you're much more likely to pass around datatypes which are in implicitly defined. In this case you'll have to write a QuickCheck function to generate suitable instances in order to test your code. (This is also true for Haskell: there are often a few functions where you have to explain to QuickCheck how to generate appropriate test cases.)
Wonder if it has something to do with COM...
Usability could definitely be better, but I will admit to writing up similarly boring slides in the past.