Hi folks, I ran across Haskell at the Great Win32 Computer Language Shootout. A friend approached me with a potential large application to develop. The idea of a language which can reduce time to design and make better code is very intriguing. I was looking at prototyping in Python using wxWindows as the GUI. I see Haskell has wxWindows libraries as well. So, here's some newbie questions I couldn't get from 2-3h on the various web sites: 1) Can I develop a Windows application to sell? Or is Haskell not really geared for that? 2) Say a team wants to develop a larger application, like a CRM system. In "thinking" in functional programming, can a team split up work and implementation and work together? In other words, how easily does Haskell adapt to a team approach? 3) Again, using a CRM tool as an example, what is the advantage to developing an application like this in Haskell vs. any other language? If I really invest the time, can I get this done quicker in Haskell? Sell me on this, please. 3) I'm a very top-down programmer. I like to start at the "big-picture" and work my way down in implementation. Does this adapt to Haskell, or am I missing the point? TIA! Mike
On 2005-10-04 at 00:01EDT Mike Crowe wrote:
Hi folks,
I ran across Haskell at the Great Win32 Computer Language Shootout. A friend approached me with a potential large application to develop. The idea of a language which can reduce time to design and make better code is very intriguing.
1) Can I develop a Windows application to sell? Or is Haskell not really geared for that?
I don't see any reason why not, though the GUI aspect of Haskell is as well developed as some other aspects of the language.
2) Say a team wants to develop a larger application, like a CRM system. In "thinking" in functional programming, can a team split up work and implementation and work together? In other words, how easily does Haskell adapt to a team approach?
At least as well as any other language.
3) Again, using a CRM tool as an example, what is the advantage to developing an application like this in Haskell vs. any other language? If I really invest the time, can I get this done quicker in Haskell? Sell me on this, please.
Whether you can get it done quicker depends on how long it takes you to "get" functional programming. It's very easy to understand Haskell just well enough to write C programmes in it. It takes a significantly greater effort -- and time -- to get into the appropriate state of mind to write real Haskell programmes.
3) I'm a very top-down programmer. I like to start at the "big-picture" and work my way down in implementation. Does this adapt to Haskell, or am I missing the point?
Haskell is very good for this. -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk
On Tue, 2005-10-04 at 11:31 +0100, Jon Fairbairn wrote:
On 2005-10-04 at 00:01EDT Mike Crowe wrote:
Hi folks,
I ran across Haskell at the Great Win32 Computer Language Shootout. A friend approached me with a potential large application to develop. The idea of a language which can reduce time to design and make better code is very intriguing.
1) Can I develop a Windows application to sell? Or is Haskell not really geared for that?
I don't see any reason why not, though the GUI aspect of Haskell is as well developed as some other aspects of the language.
Gtk2Hs and wxHaskell both support Windows and both are distributed under the LGPL (or a license very similar to the LGPL) so are suitable for developing proprietary applications. Both libraries are nearing maturity; both are approaching 1.0 releases. http://haskell.org/gtk2hs/ http://wxhaskell.sourceforge.net/ Duncan
I wouldn't really consider any of those a particularly quick question, but I'll give them a shot :) On 04/10/05, Mike Crowe <mike@mikeandkellycrowe.com> wrote:
Hi folks,
I ran across Haskell at the Great Win32 Computer Language Shootout. A friend approached me with a potential large application to develop. The idea of a language which can reduce time to design and make better code is very intriguing.
I was looking at prototyping in Python using wxWindows as the GUI. I see Haskell has wxWindows libraries as well.
So, here's some newbie questions I couldn't get from 2-3h on the various web sites:
1) Can I develop a Windows application to sell? Or is Haskell not really geared for that?
Well, of course -- the compilers are free, but there's no reason I can see that you couldn't sell an app that was written in Haskell. You'd need to be careful about the licenses of libraries that you use. I think that binaries produced with GHC are currently linked with libgmp which is under the LGPL, so you may have to be careful there as well. There are a variety of cross platform GUI libraries available.
2) Say a team wants to develop a larger application, like a CRM system. In "thinking" in functional programming, can a team split up work and implementation and work together? In other words, how easily does Haskell adapt to a team approach?
Haskell supports quite a few different abstractions which would let you code things separately. In fact, most Haskell code is referentially transparent, so you usually don't even need the rest of the app to run in order to properly test a particular function (just the dependencies of that function). The type system is very nice at eliminating potential for bugs and helping to document how things fit together. The largest application that I've written personally is a pipeline scheduler and register allocator as part of a compiler for a high level signal processing language. The algorithm was a search and backtracking algorithm, which carried on into the register allocation (if a schedule couldn't be register allocated, it would have to backtrack into the scheduler). A nice thing here is that I didn't have to think of it as such, as all the backtracking occurred automatically, as I used the list monad for nondeterminism. After design of the algorithm which would be used, it only took a couple weeks to implement and test and was around 1000 lines, which was about 1/2 documentation, and ~250 lines of which was a parser generator for an assembly/dependency language, which built a parser based on the opcodes available. I suspect that a similar project in C would be at least 10 times as much code, and would not have been manageable in the time I had. Many things are very elegantly expressed in Haskell. I recommend that you try writing some small applications in it to get a feel for what it's like.
3) Again, using a CRM tool as an example, what is the advantage to developing an application like this in Haskell vs. any other language? If I really invest the time, can I get this done quicker in Haskell? Sell me on this, please.
Haskell has quite a lot of nice features which help in various different ways. I won't even try to list them all for you, but point out a few I find nice. This really takes some exploring on your own in order to find out what is available, and how it might help. Also keep in mind that a lot has been written on the wiki (http://www.haskell.org/hawiki/) and in these mailing lists as to neat ways in which to use Haskell's features. Referential transparency I already mentioned, is incredibly nice to have. It basically consists of the guarantee that functions are completely determined by what values they return for given inputs - there is no hidden global state or side effects. This makes it much easier to prove that programs do what they are supposed to do, as well as to understand the code. The type system itself is marvellous in its ability to control how code is used and catch bugs at compile time, and prove various simple constraints hold on the code. To a very large extent, when programs compile, they also work as intended. Of course there are still bugs involved with using the wrong algorithm, but nothing can really prevent that. The type system catches a large portion of the errors which occur from attempting to fit existing pieces of code together in an unsuitable way. This is incredibly helpful when approaching a large library of existing code and wanting to write a new function based on it. The first thing to do is to look at the type of the function you want to write, and the types of the functions available. Your options in searching for useful code will often be quite restricted by the types which makes your job easier. When state and side effects are needed in Haskell, these things (though not only these things) are treated specially through the use of monads, which are a nice abstraction of both containers and models of computation. The monad being used occurs directly in the types of the functions and values involved, making it clear when it is in use, and preventing abuses. For example, if I have a function of type String -> String, then it cannot launch missiles (or do any IO whatsoever) while computing its result, simply because of its type. If it could possibly do some IO, it would have the type String -> IO String, which is somewhat rarer, and can not be used in the same places as a function of type String -> String. At first, this seems inconvenient, but in general, it helps to structure your program in such a way that makes it easier to reason about and work with.
4) I'm a very top-down programmer. I like to start at the "big-picture" and work my way down in implementation. Does this adapt to Haskell, or am I missing the point?
From my experience, Haskell is quite good at this. You might be interested in type classes, which are effectively a way to express a relation between types in a program, and specify functionality between those types wherever the relation holds. This is how "overloaded" functions work in Haskell. For example, in the standard Prelude which is generally used in every Haskell program, there is the class Eq:
class Eq a where (==), (/=) :: a -> a -> Bool -- Minimal complete definition: -- (==) or (/=) x /= y = not (x == y) x == y = not (x /= y) This single-parameter class basically defines the equality testing operations. If "Eq a" holds for some type "a", then it is possible to compare values of that type for equality. When you create types of your own, you get to specify an instance of Eq for your type to say how they should be compared, or write "deriving Eq" at the end of your data or newtype declaration, which will provide a sane default. Typeclasses in general let you specify functionality in an abstract way, and then specify a variety of implementations for that functionality and keep that entirely separate from the code which uses it. In this way, it is possible to provide simple instances when starting out, and provide more sophisticated implementations of the same behaviour later, without rewriting the code which uses it at all. (Just providing an input of a different type is enough.)
TIA! Mike
hope this is useful - Cale
Thanks, all, especially Cale for the detail. This may be unfair to ask, but is anybody willing to give an example? There are great examples for writing factorials. However, that's not really useful. I'm looking for a real-world example of using the language. Specifically, the first page of About Haskell states:
WOW! I basically wrote this without testing just thinking about my program in terms of transformations between types.
What I'm still missing is how to use this idea of functional programming to tie all this together. Let's say, for example, I want to write a data input system for a database. Consider these two examples: I think I understand how to take the following example (and others in that library) and expand to a complete UI for the data input: http://cvs.sourceforge.net/viewcvs.py/wxhaskell/wxhaskell/samples/wx/Grid.hs... <http://cvs.sourceforge.net/viewcvs.py/wxhaskell/wxhaskell/samples/wx/Grid.hs?rev=1.6&view=auto> I also looked over the examples in http://htoolkit.sourceforge.net/ for writing to a SQL database. So I can see how to save the data. The following example I get for inserting: insertRecords :: Connection -> IO () insertRecords c = do execute c "insert into Test(id,name) values (1,'Test1')" How, though, would I start? If I did this in an imperative language, I might do it like (in Python): def main: if gridCtrl.Show(): # returns True if user exits pressing Save data = gridCtrl.getData() dataBase.insertRecords(data) In Haskell, how would you start this at the top? How would you define a relationship between two modules? If this is more detailed than I should ask in this list, please LMK. Thanks! Mike Cale Gibbard wrote:
I wouldn't really consider any of those a particularly quick question, but I'll give them a shot :)
On 04/10/05, Mike Crowe <mike@mikeandkellycrowe.com> wrote:
Hi folks,
I ran across Haskell at the Great Win32 Computer Language Shootout. A friend approached me with a potential large application to develop. The idea of a language which can reduce time to design and make better code is very intriguing.
I was looking at prototyping in Python using wxWindows as the GUI. I see Haskell has wxWindows libraries as well.
So, here's some newbie questions I couldn't get from 2-3h on the various web sites:
1) Can I develop a Windows application to sell? Or is Haskell not really geared for that?
Well, of course -- the compilers are free, but there's no reason I can see that you couldn't sell an app that was written in Haskell. You'd need to be careful about the licenses of libraries that you use. I think that binaries produced with GHC are currently linked with libgmp which is under the LGPL, so you may have to be careful there as well. There are a variety of cross platform GUI libraries available.
2) Say a team wants to develop a larger application, like a CRM system. In "thinking" in functional programming, can a team split up work and implementation and work together? In other words, how easily does Haskell adapt to a team approach?
Haskell supports quite a few different abstractions which would let you code things separately. In fact, most Haskell code is referentially transparent, so you usually don't even need the rest of the app to run in order to properly test a particular function (just the dependencies of that function). The type system is very nice at eliminating potential for bugs and helping to document how things fit together.
The largest application that I've written personally is a pipeline scheduler and register allocator as part of a compiler for a high level signal processing language. The algorithm was a search and backtracking algorithm, which carried on into the register allocation (if a schedule couldn't be register allocated, it would have to backtrack into the scheduler). A nice thing here is that I didn't have to think of it as such, as all the backtracking occurred automatically, as I used the list monad for nondeterminism. After design of the algorithm which would be used, it only took a couple weeks to implement and test and was around 1000 lines, which was about 1/2 documentation, and ~250 lines of which was a parser generator for an assembly/dependency language, which built a parser based on the opcodes available. I suspect that a similar project in C would be at least 10 times as much code, and would not have been manageable in the time I had.
Many things are very elegantly expressed in Haskell. I recommend that you try writing some small applications in it to get a feel for what it's like.
3) Again, using a CRM tool as an example, what is the advantage to developing an application like this in Haskell vs. any other language? If I really invest the time, can I get this done quicker in Haskell? Sell me on this, please.
Haskell has quite a lot of nice features which help in various different ways. I won't even try to list them all for you, but point out a few I find nice. This really takes some exploring on your own in order to find out what is available, and how it might help. Also keep in mind that a lot has been written on the wiki (http://www.haskell.org/hawiki/) and in these mailing lists as to neat ways in which to use Haskell's features.
Referential transparency I already mentioned, is incredibly nice to have. It basically consists of the guarantee that functions are completely determined by what values they return for given inputs - there is no hidden global state or side effects. This makes it much easier to prove that programs do what they are supposed to do, as well as to understand the code.
The type system itself is marvellous in its ability to control how code is used and catch bugs at compile time, and prove various simple constraints hold on the code. To a very large extent, when programs compile, they also work as intended. Of course there are still bugs involved with using the wrong algorithm, but nothing can really prevent that. The type system catches a large portion of the errors which occur from attempting to fit existing pieces of code together in an unsuitable way.
This is incredibly helpful when approaching a large library of existing code and wanting to write a new function based on it. The first thing to do is to look at the type of the function you want to write, and the types of the functions available. Your options in searching for useful code will often be quite restricted by the types which makes your job easier.
When state and side effects are needed in Haskell, these things (though not only these things) are treated specially through the use of monads, which are a nice abstraction of both containers and models of computation. The monad being used occurs directly in the types of the functions and values involved, making it clear when it is in use, and preventing abuses.
For example, if I have a function of type String -> String, then it cannot launch missiles (or do any IO whatsoever) while computing its result, simply because of its type. If it could possibly do some IO, it would have the type String -> IO String, which is somewhat rarer, and can not be used in the same places as a function of type String -> String. At first, this seems inconvenient, but in general, it helps to structure your program in such a way that makes it easier to reason about and work with.
4) I'm a very top-down programmer. I like to start at the "big-picture" and work my way down in implementation. Does this adapt to Haskell, or am I missing the point?
From my experience, Haskell is quite good at this. You might be interested in type classes, which are effectively a way to express a relation between types in a program, and specify functionality between those types wherever the relation holds. This is how "overloaded" functions work in Haskell. For example, in the standard Prelude which is generally used in every Haskell program, there is the class Eq:
class Eq a where (==), (/=) :: a -> a -> Bool
-- Minimal complete definition: -- (==) or (/=) x /= y = not (x == y) x == y = not (x /= y)
This single-parameter class basically defines the equality testing operations. If "Eq a" holds for some type "a", then it is possible to compare values of that type for equality. When you create types of your own, you get to specify an instance of Eq for your type to say how they should be compared, or write "deriving Eq" at the end of your data or newtype declaration, which will provide a sane default.
Typeclasses in general let you specify functionality in an abstract way, and then specify a variety of implementations for that functionality and keep that entirely separate from the code which uses it. In this way, it is possible to provide simple instances when starting out, and provide more sophisticated implementations of the same behaviour later, without rewriting the code which uses it at all. (Just providing an input of a different type is enough.)
TIA! Mike
hope this is useful - Cale
On 10/4/05, Mike Crowe <mike@mikeandkellycrowe.com> wrote:
Thanks, all, especially Cale for the detail.
This may be unfair to ask, but is anybody willing to give an example? There are great examples for writing factorials. However, that's not really useful. I'm looking for a real-world example of using the language. Specifically, the first page of About Haskell states: WOW! I basically wrote this without testing just thinking about my program in terms of transformations between types. What I'm still missing is how to use this idea of functional programming to tie all this together. Let's say, for example, I want to write a data input system for a database. Consider these two examples:
I think I understand how to take the following example (and others in that library) and expand to a complete UI for the data input: http://cvs.sourceforge.net/viewcvs.py/wxhaskell/wxhaskell/samples/wx/Grid.hs...
I also looked over the examples in http://htoolkit.sourceforge.net/ for writing to a SQL database. So I can see how to save the data. The following example I get for inserting: insertRecords :: Connection -> IO () insertRecords c = do execute c "insert into Test(id,name) values (1,'Test1')"
How, though, would I start? If I did this in an imperative language, I might do it like (in Python):
def main: if gridCtrl.Show(): # returns True if user exits pressing Save data = gridCtrl.getData() dataBase.insertRecords(data)
In Haskell, how would you start this at the top? How would you define a relationship between two modules?
If this is more detailed than I should ask in this list, please LMK.
Thanks! Mike
In general you write a small "shell" of IO code as your base application. This IO code then calls the rest of the (non-IO-)functions and presents the result in some way. As you can see in the source code you linked you can attatch IO actions to events. E.g. set g [on gridEvent := onGrid] So to, for example, trigger a database update when the user presses a button, you would attatch the database-update action to the on click event for that button. You could also use partial application to pass along extra data that this function may need set but [on click := updateDB dbConnection] where dbConnection is some value representing a database connection and then in the function defintion: updateDB dbConn = do ... As you can see onGrid takes two parameters (everything it needs to do what you want it to do) but when you attatch it to the gridEvent you only pass it the first one (the event itself passes the second one). You would most likely want to pass other data to updateDB, such as the data that should be inserted into the table etc. You could e.g. pass the gridcontrol to updateDB and let the updateDB function extract the data from it and insert it into the database. So the main IO code is very imperative in look and feel, except that all data flow is explicit (and perhaps more importantly, that actions are first class citizens). So you could lay out your haskell IO code in much the same way as you would in an imperative language. As an aside. if you're going to use databases, consider using HaskellDB (an SQL "unwrapper"), which allows you type-safe database queries (pretty cool!). /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862
On 10/5/05, Sebastian Sylvan <sebastian.sylvan@gmail.com> wrote:
On 10/4/05, Mike Crowe <mike@mikeandkellycrowe.com> wrote:
Thanks, all, especially Cale for the detail.
This may be unfair to ask, but is anybody willing to give an example? There are great examples for writing factorials. However, that's not really useful. I'm looking for a real-world example of using the language. Specifically, the first page of About Haskell states: WOW! I basically wrote this without testing just thinking about my program in terms of transformations between types. What I'm still missing is how to use this idea of functional programming to tie all this together. Let's say, for example, I want to write a data input system for a database. Consider these two examples:
I think I understand how to take the following example (and others in that library) and expand to a complete UI for the data input: http://cvs.sourceforge.net/viewcvs.py/wxhaskell/wxhaskell/samples/wx/Grid.hs...
I also looked over the examples in http://htoolkit.sourceforge.net/ for writing to a SQL database. So I can see how to save the data. The following example I get for inserting: insertRecords :: Connection -> IO () insertRecords c = do execute c "insert into Test(id,name) values (1,'Test1')"
How, though, would I start? If I did this in an imperative language, I might do it like (in Python):
def main: if gridCtrl.Show(): # returns True if user exits pressing Save data = gridCtrl.getData() dataBase.insertRecords(data)
In Haskell, how would you start this at the top? How would you define a relationship between two modules?
If this is more detailed than I should ask in this list, please LMK.
Thanks! Mike
In general you write a small "shell" of IO code as your base application. This IO code then calls the rest of the (non-IO-)functions and presents the result in some way.
As you can see in the source code you linked you can attatch IO actions to events. E.g. set g [on gridEvent := onGrid]
So to, for example, trigger a database update when the user presses a button, you would attatch the database-update action to the on click event for that button.
You could also use partial application to pass along extra data that this function may need
set but [on click := updateDB dbConnection]
where dbConnection is some value representing a database connection
and then in the function defintion:
updateDB dbConn = do ...
As you can see onGrid takes two parameters (everything it needs to do what you want it to do) but when you attatch it to the gridEvent you only pass it the first one (the event itself passes the second one).
I meant updateDB and click-event and there respectively. Sorry. /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862
On 10/4/05, Mike Crowe <mike@mikeandkellycrowe.com> wrote:
This may be unfair to ask, but is anybody willing to give an example? There are great examples for writing factorials. However, that's not really useful. I'm looking for a real-world example of using the language.
You might be interested in Dazzle [1], which I recently read up on. It's a Bayesian network toolbox written in Haskell and using wxHaskell for the GUI side. The team behind it had a paper [2] accepted to the 2005 Haskell Workshop that details some of the tricks they used to do the GUI integration. Hope this helps. Collin Winter [1] http://www.cs.uu.nl/dazzle/ [2] http://www.cs.uu.nl/dazzle/f08-schrage.pdf
participants (6)
-
Cale Gibbard -
Collin Winter -
Duncan Coutts -
Jon Fairbairn -
Mike Crowe -
Sebastian Sylvan