Part II: How not to Start Your Haskell Program >
Here’s a bit of sardonic code, that I’d like to propose to any Haskell advocate out there.
data Works = Works | Does_not
computerApp a :: Maybe a -> Works
| isJust a = Works
| otherwise = Does_not
I have been playing around with functional programming in Haskell. I have to say that it has more than certainly improved my ability to code in other languages, and probably has reduced the number of bugs I have to fix after the fact. On the other hand, it has driven me absolutely batty.
To be fair, I need to say that I am not a computer engineer. I have a BA in English. My Masters are in Public Administration and Information Management. I engaged in Haskell code simply as a curiosity and a challenge. I love math, and became curious about Monads and Lambda calculus. I am probably not smart enough to be a great Haskell programmer. However, I do understand two things. 1) Not-smart-enough people can and want to participate in application development 2) Coders, while making apps that do what they expect them to do, do not always understand (or care) about the sustainability and/or scalability of their code.
Web Development is an important test case. Just about anyone, with a reasonable amount of time and effort, can learn to develop a website in PHP, probably supported by some content management system as Drupal or ModX. Somewhere, their development goes overboard, the system does an upgrade to support some security risk or vulnerability, and ‘pop’ –> all that likely un-documented and messy code goes nowhere and wheels need to be reinvented.
That’s why learning Haskell is probably a good idea. Without getting into the code itself, it insists that a function always causes the same result to happen with any given input(s). Once developed, the documentation pretty much always exists in a minimal form (via Type declarations). So many bad habits would disappear if only people were forced into developing this way.
The problem, unfortunately, is that Haskell coding is confusing. There is no popular development framework to use it. Once you try to apply the examples provided in text books to real world development, things go wonky. I won’t go into the many reasons why, but I do have an observation based on what I’ve seen in responses from various gurus to newbies like me.
It’s this -> Users think computers do things. Computer engineers think computers solve problems. In Haskell terms, any interaction between users and engineers results in a type error. Somewhere along the line, an IO() monad needs to be created to turn what engineers like about Haskell into something that users will like about it.
I would like to propose a management framework, similar to extreme programming, to manage the development of functional code for regular people. While Programming it in Haskell is not a bad start, it uses a problem solving model, rather than a ‘how do you make the software do x’ model. It focuses on mathematical abstractions rather than simple actions. For instance, I would like to see a book that uses the development of a rogue-like rpg game in Haskell as an example. Instead of worrying about efficient computation, abstractions about ‘laziness’ and recursive factorial examples, the writer would have to focus on managing complex (a tuple of a lists of tuples) types, worrying about random numbers and IO issues that are inherent to Haskell. In approaching such a game, should I worry about creating newtypes first, or work from what I want main to do and fill in the gaps?
But while I make this suggestion, I really have no idea of what kind of advice I can offer your typical new-to-haskell coder. But I have some hypotheses:
- work from the main :: IO() first and build a framework of functions to develop your outputs.
- possibly create type variables for each of your functions, making it equal in Type to a typical output you would like to see. Then work backwards from there to create a lazy output, then involve possible recursion and so on.
- use generic types (eg. Int, String, Char etc.) with comments first, then develop types to make your code more clear.
- unit tests should include the System.IO.Unsafe module (cheating should be allowed when you are testing your code – let the learning happen when you are developing real code)
I’ll add what I can as I continue to learn more about coding in Haskell. The bottom line is that I think more people should be coding in a language like Haskell, but they are unlikely to work with it if they end up spending a bajillion hours just to get it to choose randomly from a list of monsters (for example). Especially when they can learn how to do the same in three minutes using an imperative language like Python.
For the greater good and more sustainable code overall, what high-level tips or approaches can you offer any newbie coders of Haskell, so they can develop without becoming absolutely bogged down in failure with their Haskell programs?
UPDATE: After writing this, I found a great powerpoint tutorial by Graham Hutton that uses Hangman as an example of interactive Haskell code development.